Skip to content

Commit 530d5b5

Browse files
authored
Merge pull request #16 from umbrellio/fix-class-components
Fix observer and multiple observer for class components
2 parents bc1835b + 3d04c7f commit 530d5b5

5 files changed

+110
-11
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@umbrellio/observable",
3-
"version": "1.4.2",
3+
"version": "1.4.3",
44
"description": "Observable library",
55
"repository": "git@github.com:umbrellio/observable.git",
66
"author": "Aleksei Bespalov <nulldefiner@gmail.com>",

src/multipleObserver.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const multipleObserver = stores => WrappedComponent => {
3333
}
3434
}, {})
3535

36-
return WrappedComponent({ ...this.props, ...state })
36+
return <WrappedComponent {...this.props} {...state} />
3737
}
3838
}
3939
}

src/observer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const observer = (store, { key, map }) => WrappedComponent => {
2323

2424
render () {
2525
const state = { [key]: map ? map(this.state) : this.state }
26-
return WrappedComponent({ ...this.props, ...state })
26+
return <WrappedComponent {...this.props} {...state} />
2727
}
2828
}
2929
}

tests/multipleObserver.test.js

+62-4
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,61 @@ const TestComponent = props => {
88
return <pre dangerouslySetInnerHTML={{ __html: JSON.stringify(props) }} />
99
}
1010

11-
const shallowComponent = observer => {
12-
const ObservedComponent = observer(TestComponent)
11+
class ClassTestComponent extends React.Component {
12+
constructor (props) {
13+
super(props)
14+
this.state = {
15+
count: 0,
16+
}
17+
}
18+
19+
handleClick = () => {
20+
this.setState(prev => {
21+
const next = prev === this.props.maxCount ? prev : prev + 1
22+
return { count: next }
23+
})
24+
}
25+
26+
render () {
27+
return (
28+
<div>
29+
<button onClick={this.handleClick}>+</button>
30+
<span>{`Count: ${this.state.count}`}</span>
31+
<span>{`Max: ${this.props.count.max}`}</span>
32+
<span>{`Value: ${this.props.info.key}`}</span>
33+
</div>
34+
)
35+
}
36+
}
37+
38+
const shallowComponent = (observer, component) => {
39+
const ObservedComponent = observer(component)
1340
return Enzyme.shallow(<ObservedComponent />)
1441
}
1542

1643
let store = null
1744
let anotherStore = null
45+
let countStore = null
1846

1947
beforeAll(() => {
2048
Enzyme.configure({ adapter: new Adapter() })
2149
store = observable({ key: "initial value" })
2250
anotherStore = observable({ anotherKey: "another initial value" })
51+
countStore = observable({ max: 10 })
2352
})
2453

2554
beforeEach(() => {
2655
store.reset()
2756
anotherStore.reset()
57+
countStore.reset()
2858
})
2959

3060
it("wraps a component with the multiple observable", () => {
3161
const observer = multipleObserver([
3262
{ store, key: "value" },
3363
{ store: anotherStore, key: "anotherValue" },
3464
])
35-
const component = shallowComponent(observer)
65+
const component = shallowComponent(observer, TestComponent)
3666
expect(component.html()).toEqual(
3767
"<pre>" +
3868
"{\"value\":{\"key\":\"initial value\"}," +
@@ -56,7 +86,7 @@ it("wraps a component with the multiple observable (mapped)", () => {
5686
{ store, key: "value", map: state => state.key },
5787
{ store: anotherStore, key: "anotherValue", map: state => state.anotherKey },
5888
])
59-
const component = shallowComponent(observer)
89+
const component = shallowComponent(observer, TestComponent)
6090
expect(component.html()).toEqual(
6191
"<pre>" +
6292
"{\"value\":\"initial value\"," +
@@ -74,3 +104,31 @@ it("wraps a component with the multiple observable (mapped)", () => {
74104
)
75105
component.unmount()
76106
})
107+
108+
it("wraps a class component with the multiple observable", () => {
109+
const observer = multipleObserver([
110+
{ store, key: "info" },
111+
{ store: countStore, key: "count" },
112+
])
113+
const component = shallowComponent(observer, ClassTestComponent)
114+
expect(component.html()).toEqual(
115+
"<div>" +
116+
"<button>+</button>" +
117+
"<span>Count: 0</span>" +
118+
"<span>Max: 10</span>" +
119+
"<span>Value: initial value</span>" +
120+
"</div>",
121+
)
122+
123+
store.set({ key: "new value" })
124+
countStore.set({ max: 20 })
125+
expect(component.html()).toEqual(
126+
"<div>" +
127+
"<button>+</button>" +
128+
"<span>Count: 0</span>" +
129+
"<span>Max: 20</span>" +
130+
"<span>Value: new value</span>" +
131+
"</div>",
132+
)
133+
component.unmount()
134+
})

tests/observer.test.js

+45-4
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,57 @@ const TestComponent = props => {
88
return <pre dangerouslySetInnerHTML={{ __html: JSON.stringify(props) }} />
99
}
1010

11-
const shallowComponent = observer => {
12-
const ObservedComponent = observer(TestComponent)
11+
class ClassTestComponent extends React.Component {
12+
constructor (props) {
13+
super(props)
14+
this.state = {
15+
count: 0,
16+
}
17+
}
18+
19+
handleClick = () => {
20+
this.setState(prev => {
21+
const next = prev === this.props.maxCount ? prev : prev + 1
22+
return { count: next }
23+
})
24+
}
25+
26+
render () {
27+
return (
28+
<div>
29+
<button onClick={this.handleClick}>+</button>
30+
<span>{`Count: ${this.state.count}`}</span>
31+
<span>{`Max: ${this.props.count.max}`}</span>
32+
</div>
33+
)
34+
}
35+
}
36+
37+
const shallowComponent = (observer, component) => {
38+
const ObservedComponent = observer(component)
1339
return Enzyme.shallow(<ObservedComponent />)
1440
}
1541

1642
let store = null
1743
let anotherStore = null
44+
let countStore = null
1845

1946
beforeAll(() => {
2047
Enzyme.configure({ adapter: new Adapter() })
2148
store = observable({ key: "initial value" })
2249
anotherStore = observable({ anotherKey: "another initial value" })
50+
countStore = observable({ max: 10 })
2351
})
2452

2553
beforeEach(() => {
2654
store.reset()
2755
anotherStore.reset()
56+
countStore.reset()
2857
})
2958

3059
it("wraps a component with the observable", () => {
3160
const observer = store.observer({ key: "value" })
32-
const component = shallowComponent(observer)
61+
const component = shallowComponent(observer, TestComponent)
3362
expect(component.html()).toEqual("<pre>{\"value\":{\"key\":\"initial value\"}}</pre>")
3463

3564
store.set({ key: "new value" })
@@ -39,10 +68,22 @@ it("wraps a component with the observable", () => {
3968

4069
it("wraps a component with the observable (mapped)", () => {
4170
const observer = store.observer({ key: "value", map: state => state.key })
42-
const component = shallowComponent(observer)
71+
const component = shallowComponent(observer, TestComponent)
4372
expect(component.html()).toEqual("<pre>{\"value\":\"initial value\"}</pre>")
4473

4574
store.set({ key: "new value" })
4675
expect(component.html()).toEqual("<pre>{\"value\":\"new value\"}</pre>")
4776
component.unmount()
4877
})
78+
79+
it("wraps a class component with the observable", () => {
80+
const observer = countStore.observer({ key: "count" })
81+
const component = shallowComponent(observer, ClassTestComponent)
82+
expect(component.html())
83+
.toEqual("<div><button>+</button><span>Count: 0</span><span>Max: 10</span></div>")
84+
85+
countStore.set({ max: 20 })
86+
expect(component.html())
87+
.toEqual("<div><button>+</button><span>Count: 0</span><span>Max: 20</span></div>")
88+
component.unmount()
89+
})

0 commit comments

Comments
 (0)