@samitouri / QOS-React / commits / e8500fb1c2

Add failing tests for coroutines

There are a few different issues: * Updates result in unnecessary duplicate placements because it can't find the current fiber for continuations. * When run together, coroutine update and unmounting tests appear to lock down in an infinite loop. They don't freeze in isolation. I don't have a solution for this but just leaving it for future fixes.

Sebastian Markbage committed Jan 20, 2017 at 23:57 UTC e8500fb1c2df2b215c3a20aa596446eaea0390ad
2 files changed +72 -1
scripts/fiber/tests-passing.txt
+1
@@ -1143,6 +1143,7 @@ src/renderers/shared/__tests__/ReactPerf-test.js
1143
1144 src/renderers/shared/fiber/__tests__/ReactCoroutine-test.js
1145 * should render a coroutine
1146 +* should update a coroutine
1147 * should unmount a composite in a coroutine
1148
1149 src/renderers/shared/fiber/__tests__/ReactIncremental-test.js
src/renderers/shared/fiber/__tests__/ReactCoroutine-test.js
+71 -1
@@ -26,12 +26,21 @@ describe('ReactCoroutine', () => {
26 ReactFeatureFlags.disableNewFiberFeatures = false;
27 });
28
29 + function div(...children) {
30 + children = children.map(c => typeof c === 'string' ? { text: c } : c);
31 + return { type: 'div', children, prop: undefined };
32 + }
33 +
34 + function span(prop) {
35 + return { type: 'span', children: [], prop };
36 + }
37 +
38 it('should render a coroutine', () => {
39 var ops = [];
40
41 function Continuation({ isSame }) {
42 ops.push(['Continuation', isSame]);
34 - return <span>{isSame ? 'foo==bar' : 'foo!=bar'}</span>;
43 + return <span prop={isSame ? 'foo==bar' : 'foo!=bar'} />;
44 }
45
46 // An alternative API could mark Continuation as something that needs
@@ -88,6 +97,67 @@ describe('ReactCoroutine', () => {
97 ['Continuation', true],
98 ['Continuation', false],
99 ]);
100 + expect(ReactNoop.getChildren()).toEqual([
101 + div(
102 + span('foo==bar'),
103 + span('foo!=bar'),
104 + ),
105 + ]);
106 + });
107 +
108 + it('should update a coroutine', () => {
109 + function Continuation({ isSame }) {
110 + return <span prop={isSame ? 'foo==bar' : 'foo!=bar'} />;
111 + }
112 +
113 + function Child({ bar }) {
114 + return ReactCoroutine.createYield({
115 + props: {
116 + bar: bar,
117 + },
118 + continuation: Continuation,
119 + });
120 + }
121 +
122 + function Indirection() {
123 + return [<Child bar={true} />, <Child bar={false} />];
124 + }
125 +
126 + function HandleYields(props, yields) {
127 + return yields.map(y =>
128 + <y.continuation isSame={props.foo === y.props.bar} />
129 + );
130 + }
131 +
132 + function Parent(props) {
133 + return ReactCoroutine.createCoroutine(
134 + props.children,
135 + HandleYields,
136 + props
137 + );
138 + }
139 +
140 + function App(props) {
141 + return <div><Parent foo={props.foo}><Indirection /></Parent></div>;
142 + }
143 +
144 + ReactNoop.render(<App foo={true} />);
145 + ReactNoop.flush();
146 + expect(ReactNoop.getChildren()).toEqual([
147 + div(
148 + span('foo==bar'),
149 + span('foo!=bar'),
150 + ),
151 + ]);
152 +
153 + ReactNoop.render(<App foo={false} />);
154 + ReactNoop.flush();
155 + expect(ReactNoop.getChildren()).toEqual([
156 + div(
157 + span('foo!=bar'),
158 + span('foo==bar'),
159 + ),
160 + ]);
161 });
162
163 it('should unmount a composite in a coroutine', () => {