2017-11-02 14:28:37 +03:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2017-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* @flow */
|
|
|
|
|
|
|
|
let fs = require("fs");
|
|
|
|
let path = require("path");
|
|
|
|
let { prepackSources } = require("../lib/prepack-node.js");
|
|
|
|
let babel = require("babel-core");
|
|
|
|
let React = require("react");
|
2018-02-16 18:58:44 +03:00
|
|
|
let PropTypes = require("prop-types");
|
2018-02-09 15:42:10 +03:00
|
|
|
let ReactRelay = require("react-relay");
|
2017-11-02 14:28:37 +03:00
|
|
|
let ReactTestRenderer = require("react-test-renderer");
|
|
|
|
let { mergeAdacentJSONTextNodes } = require("../lib/utils/json.js");
|
|
|
|
/* eslint-disable no-undef */
|
|
|
|
let { expect, describe, it } = global;
|
|
|
|
|
2018-02-06 01:08:06 +03:00
|
|
|
function cxShim(...args) {
|
|
|
|
let classNames = [];
|
|
|
|
for (let arg of args) {
|
|
|
|
if (typeof arg === "string") {
|
|
|
|
classNames.push(arg);
|
|
|
|
} else if (typeof arg === "object" && arg !== null) {
|
|
|
|
let keys = Object.keys(arg);
|
|
|
|
for (let key of keys) {
|
|
|
|
if (arg[key]) {
|
|
|
|
classNames.push(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return classNames.join(" ");
|
|
|
|
}
|
|
|
|
|
|
|
|
// assign for tests that use the cx() global
|
|
|
|
global.cx = cxShim;
|
|
|
|
|
2018-02-16 18:58:44 +03:00
|
|
|
function getDataFile(directory, name) {
|
|
|
|
let reactTestRoot = path.join(__dirname, "../test/react/");
|
|
|
|
let data = fs.readFileSync(path.join(reactTestRoot, directory, name)).toString();
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2018-02-22 03:09:52 +03:00
|
|
|
function runTestSuite(outputJsx, shouldTranspileSource) {
|
2017-12-16 19:04:37 +03:00
|
|
|
let reactTestRoot = path.join(__dirname, "../test/react/");
|
|
|
|
let prepackOptions = {
|
2018-01-24 22:23:51 +03:00
|
|
|
compatibility: "fb-www",
|
2017-12-16 19:04:37 +03:00
|
|
|
internalDebug: true,
|
|
|
|
serialize: true,
|
|
|
|
uniqueSuffix: "",
|
|
|
|
maxStackDepth: 100,
|
|
|
|
reactEnabled: true,
|
|
|
|
reactOutput: outputJsx ? "jsx" : "create-element",
|
|
|
|
inlineExpressions: true,
|
|
|
|
omitInvariants: true,
|
2018-01-17 10:14:14 +03:00
|
|
|
abstractEffectsInAdditionalFunctions: true,
|
2018-02-13 19:34:42 +03:00
|
|
|
stripFlow: true,
|
2017-11-02 14:28:37 +03:00
|
|
|
};
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
function compileSourceWithPrepack(source) {
|
|
|
|
let code = `(function(){${source}})()`;
|
|
|
|
let serialized = prepackSources([{ filePath: "", fileContents: code, sourceMapContents: "" }], prepackOptions);
|
|
|
|
if (serialized == null || serialized.reactStatistics == null) {
|
|
|
|
throw new Error("React test runner failed during serialization");
|
2017-11-02 14:28:37 +03:00
|
|
|
}
|
2017-12-16 19:04:37 +03:00
|
|
|
return {
|
|
|
|
compiledSource: serialized.code,
|
|
|
|
statistics: serialized.reactStatistics,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2018-02-22 03:09:52 +03:00
|
|
|
function transpileSource(source) {
|
|
|
|
return babel.transform(source, {
|
2017-12-16 19:04:37 +03:00
|
|
|
presets: ["babel-preset-react"],
|
|
|
|
plugins: ["transform-object-rest-spread"],
|
|
|
|
}).code;
|
2018-02-22 03:09:52 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function runSource(source) {
|
|
|
|
let transformedSource = transpileSource(source);
|
2017-12-16 19:04:37 +03:00
|
|
|
/* eslint-disable no-new-func */
|
|
|
|
let fn = new Function("require", "module", transformedSource);
|
|
|
|
let moduleShim = { exports: null };
|
|
|
|
let requireShim = name => {
|
|
|
|
switch (name) {
|
2018-01-24 22:23:51 +03:00
|
|
|
case "React":
|
2017-12-16 19:04:37 +03:00
|
|
|
case "react":
|
|
|
|
return React;
|
2018-02-16 18:58:44 +03:00
|
|
|
case "PropTypes":
|
|
|
|
case "prop-types":
|
|
|
|
return PropTypes;
|
2018-01-24 22:23:51 +03:00
|
|
|
case "RelayModern":
|
2018-02-09 15:42:10 +03:00
|
|
|
return ReactRelay;
|
2018-02-06 01:08:06 +03:00
|
|
|
case "cx":
|
|
|
|
return cxShim;
|
2018-01-24 22:23:51 +03:00
|
|
|
case "FBEnvironment":
|
|
|
|
return {};
|
2017-12-16 19:04:37 +03:00
|
|
|
default:
|
|
|
|
throw new Error(`Unrecognized import: "${name}".`);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
// $FlowFixMe flow doesn't new Function
|
|
|
|
fn(requireShim, moduleShim);
|
|
|
|
} catch (e) {
|
|
|
|
console.error(transformedSource);
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
return moduleShim.exports;
|
2017-11-02 14:28:37 +03:00
|
|
|
}
|
|
|
|
|
2018-02-16 18:58:44 +03:00
|
|
|
async function runTest(directory, name, data) {
|
2017-12-16 19:04:37 +03:00
|
|
|
let source = fs.readFileSync(path.join(reactTestRoot, directory, name)).toString();
|
2018-02-22 03:09:52 +03:00
|
|
|
if (shouldTranspileSource) {
|
|
|
|
source = transpileSource(source);
|
|
|
|
}
|
2018-02-08 22:22:17 +03:00
|
|
|
let { compiledSource, statistics } = compileSourceWithPrepack(source);
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2018-02-08 22:22:17 +03:00
|
|
|
expect(statistics).toMatchSnapshot();
|
2017-12-16 19:04:37 +03:00
|
|
|
let A = runSource(source);
|
|
|
|
let B = runSource(compiledSource);
|
2018-02-06 01:08:06 +03:00
|
|
|
|
2018-01-31 18:53:30 +03:00
|
|
|
expect(typeof A).toBe(typeof B);
|
|
|
|
if (typeof A !== "function") {
|
|
|
|
// Test without exports just verifies that the file compiles.
|
|
|
|
return;
|
|
|
|
}
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
let rendererA = ReactTestRenderer.create(null);
|
|
|
|
let rendererB = ReactTestRenderer.create(null);
|
|
|
|
if (A == null || B == null) {
|
|
|
|
throw new Error("React test runner issue");
|
|
|
|
}
|
2018-01-31 18:53:30 +03:00
|
|
|
// Use the original version of the test in case transforming messes it up.
|
2017-12-16 19:04:37 +03:00
|
|
|
let { getTrials } = A;
|
2018-01-31 18:53:30 +03:00
|
|
|
// Run tests that assert the rendered output matches.
|
2018-02-16 18:58:44 +03:00
|
|
|
let resultA = getTrials(rendererA, A, data);
|
|
|
|
let resultB = getTrials(rendererB, B, data);
|
2017-12-16 19:04:37 +03:00
|
|
|
|
2018-01-31 18:53:30 +03:00
|
|
|
// The test has returned many values for us to check
|
2017-12-16 19:04:37 +03:00
|
|
|
for (let i = 0; i < resultA.length; i++) {
|
|
|
|
let [nameA, valueA] = resultA[i];
|
|
|
|
let [nameB, valueB] = resultB[i];
|
|
|
|
expect(mergeAdacentJSONTextNodes(valueB)).toEqual(mergeAdacentJSONTextNodes(valueA));
|
|
|
|
expect(nameB).toEqual(nameA);
|
|
|
|
}
|
2017-11-02 14:28:37 +03:00
|
|
|
}
|
|
|
|
|
2018-02-09 15:42:10 +03:00
|
|
|
async function stubReactRelay(f) {
|
|
|
|
let oldReactRelay = ReactRelay;
|
|
|
|
ReactRelay = {
|
|
|
|
QueryRenderer(props) {
|
|
|
|
return props.render({ props: {}, error: null });
|
|
|
|
},
|
|
|
|
createFragmentContainer() {
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
graphql() {
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
try {
|
|
|
|
await f();
|
|
|
|
} finally {
|
|
|
|
ReactRelay = oldReactRelay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
// Jest tests
|
|
|
|
let originalConsoleError = console.error;
|
|
|
|
|
2018-02-22 03:09:52 +03:00
|
|
|
describe(`Test React with ${shouldTranspileSource ? "create-element input" : "JSX input"}, ${outputJsx
|
|
|
|
? "JSX output"
|
|
|
|
: "create-element output"}`, () => {
|
2017-12-16 19:04:37 +03:00
|
|
|
describe("Functional component folding", () => {
|
|
|
|
let directory = "functional-components";
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Simple", async () => {
|
|
|
|
await runTest(directory, "simple.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2018-01-17 10:14:14 +03:00
|
|
|
it("Simple 2", async () => {
|
|
|
|
await runTest(directory, "simple-2.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple 3", async () => {
|
|
|
|
await runTest(directory, "simple-3.js");
|
|
|
|
});
|
|
|
|
|
2018-01-26 14:04:15 +03:00
|
|
|
it("Simple 4", async () => {
|
|
|
|
await runTest(directory, "simple-4.js");
|
|
|
|
});
|
|
|
|
|
2018-01-26 22:47:51 +03:00
|
|
|
it("Simple 5", async () => {
|
|
|
|
await runTest(directory, "simple-5.js");
|
|
|
|
});
|
|
|
|
|
2018-01-31 00:59:52 +03:00
|
|
|
it("Simple 6", async () => {
|
|
|
|
await runTest(directory, "simple-6.js");
|
|
|
|
});
|
|
|
|
|
2018-02-16 16:14:45 +03:00
|
|
|
it("Simple 7", async () => {
|
|
|
|
await runTest(directory, "simple-7.js");
|
|
|
|
});
|
|
|
|
|
2018-02-09 01:58:22 +03:00
|
|
|
it("Simple fragments", async () => {
|
|
|
|
await runTest(directory, "simple-fragments.js");
|
|
|
|
});
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Simple children", async () => {
|
|
|
|
await runTest(directory, "simple-children.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Simple refs", async () => {
|
|
|
|
await runTest(directory, "simple-refs.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2018-02-22 03:09:52 +03:00
|
|
|
it("Simple with abstract props", async () => {
|
|
|
|
await runTest(directory, "simple-with-abstract-props.js");
|
|
|
|
});
|
|
|
|
|
2018-02-24 03:36:15 +03:00
|
|
|
it("Simple with unary expressions", async () => {
|
|
|
|
await runTest(directory, "simple-with-unary.js");
|
|
|
|
});
|
|
|
|
|
2018-02-22 03:09:52 +03:00
|
|
|
it("Simple with multiple JSX spreads", async () => {
|
|
|
|
await runTest(directory, "simple-with-jsx-spread.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with multiple JSX spreads #2", async () => {
|
|
|
|
await runTest(directory, "simple-with-jsx-spread2.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with multiple JSX spreads #3", async () => {
|
|
|
|
await runTest(directory, "simple-with-jsx-spread3.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with multiple JSX spreads #4", async () => {
|
|
|
|
await runTest(directory, "simple-with-jsx-spread4.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with multiple JSX spreads #5", async () => {
|
|
|
|
await runTest(directory, "simple-with-jsx-spread5.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with multiple JSX spreads #6", async () => {
|
|
|
|
await runTest(directory, "simple-with-jsx-spread6.js");
|
|
|
|
});
|
|
|
|
|
2018-02-17 01:09:03 +03:00
|
|
|
it("Simple with Object.assign", async () => {
|
|
|
|
await runTest(directory, "simple-assign.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with Object.assign #2", async () => {
|
|
|
|
await runTest(directory, "simple-assign2.js");
|
|
|
|
});
|
|
|
|
|
Make Object.assign() safe to use with simple partial sources
Summary:
Fixes https://github.com/facebook/prepack/issues/1462.
Supersedes my attempts in https://github.com/facebook/prepack/pull/1459, https://github.com/facebook/prepack/pull/1460, and https://github.com/facebook/prepack/pull/1468.
The git history reflects a lot of back-and-forth so it might make more sense to look at the final code.
There are two separate fixes here:
* If we have a partial simple source and then a normal source, we shouldn't attempt to `Set` any further keys after the first partial. Instead we should emit residual `Object.assign` calls. If we set the keys, we end up with a wrong key order (a key gets set earlier than it should have). Key order (AFAIK) isn't mandated by the spec but tends to be relied on in product code because all engines preserve it in the order of assignments.
* It is not safe to mutate either a partial source or the target (when some sources are partial) in Prepack land after the `Object.assign` call. This is because Prepack will serialize all those mutations (as the object final state) right into the residual `Object.assign` call. But this is wrong because they haven't happened yet.
The second issue is thorny. In many cases sources (and the target) don't get mutated later. So we'd like to keep supporting `Object.assign` with partials when we don't touch them later.
To solve it, I introduced new `obj.makeFinal()` and `obj.isFinalObject()` methods. If an object is marked as "final", we cannot make changes to it that would change its emitted form. This is a way for us to say "let's try to continue as far as we can, but if anything tries to touch it, fatal".
It doesn't mean the object is "frozen" (technically we didn't freeze it), but it means Prepack can't deal with further mutations to it because Prepack has already "used" its current snapshot and it would be unsafe to change it.
I'm not sure I'm checking `isFinalObject()` in all places where it's necessary. If there is a way to do this with stronger guarantees please let me know. I want to still highlight that this fixes multiple existing issues on master so it's a step in a safer duration, even though I'm wary that if the concept is not fully baked, it might give a false sense of security.
Here's how we're using this new infra. When we emit a residual `Object.assign()` call because some sources are partial (and simple), I mark all sources and the target as "final". So if they don't get mutated, everything is fine. If they get mutated later, we get a fatal when they do. In the future Prepack might support this better, but the fatal makes it clear which cases it currently doesn't handle (and would produce wrong output for).
There might also be other cases where making an object as "final" lets us continue further, although I don't know Prepack codebase well enough to tell for sure. So I'm hoping it is useful as a generic concept outside of the `Object.assign()` use case.
The pure mode is treated a bit differently. In the pure mode we can get away with "leaking" final values whenever we need to write to them. Then they're treated like any other "leaked" object.
I added regression tests for all existing cases I could find, both in pure and impure mode.
Closes https://github.com/facebook/prepack/pull/1469
Reviewed By: trueadm
Differential Revision: D7046641
Pulled By: gaearon
fbshipit-source-id: 472188eeabe28dcce36ab026ecbcbc4c8e83176b
2018-02-22 00:17:15 +03:00
|
|
|
it("Simple with Object.assign #3", async () => {
|
|
|
|
await runTest(directory, "simple-assign3.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with Object.assign #4", async () => {
|
|
|
|
await runTest(directory, "simple-assign4.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple with Object.assign #5", async () => {
|
|
|
|
await runTest(directory, "simple-assign5.js");
|
|
|
|
});
|
|
|
|
|
2018-01-26 22:53:17 +03:00
|
|
|
it("Circular reference", async () => {
|
|
|
|
await runTest(directory, "circular-reference.js");
|
|
|
|
});
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Conditional", async () => {
|
|
|
|
await runTest(directory, "conditional.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Key nesting", async () => {
|
|
|
|
await runTest(directory, "key-nesting.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Key nesting 2", async () => {
|
|
|
|
await runTest(directory, "key-nesting-2.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Key nesting 3", async () => {
|
|
|
|
await runTest(directory, "key-nesting-3.js");
|
|
|
|
});
|
2017-11-14 18:33:32 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Key change", async () => {
|
|
|
|
await runTest(directory, "key-change.js");
|
|
|
|
});
|
2017-11-14 18:33:32 +03:00
|
|
|
|
2018-02-27 04:21:01 +03:00
|
|
|
it("Delete element prop key", async () => {
|
|
|
|
await runTest(directory, "delete-element-prop-key.js");
|
|
|
|
});
|
|
|
|
|
2018-02-09 01:58:22 +03:00
|
|
|
it("Key change with fragments", async () => {
|
|
|
|
await runTest(directory, "key-change-fragments.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Key not changing with fragments", async () => {
|
|
|
|
await runTest(directory, "key-not-change-fragments.js");
|
|
|
|
});
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Component type change", async () => {
|
|
|
|
await runTest(directory, "type-change.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Component type same", async () => {
|
|
|
|
await runTest(directory, "type-same.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Dynamic props", async () => {
|
|
|
|
await runTest(directory, "dynamic-props.js");
|
|
|
|
});
|
2017-11-06 15:54:12 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Dynamic context", async () => {
|
|
|
|
await runTest(directory, "dynamic-context.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("React.cloneElement", async () => {
|
|
|
|
await runTest(directory, "clone-element.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Return text", async () => {
|
|
|
|
await runTest(directory, "return-text.js");
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2018-02-20 17:29:48 +03:00
|
|
|
it("Render array twice", async () => {
|
|
|
|
await runTest(directory, "array-twice.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Render nested array children", async () => {
|
|
|
|
await runTest(directory, "nested-array-children.js");
|
|
|
|
});
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Return undefined", async () => {
|
|
|
|
// this test will cause a React console.error to show
|
|
|
|
// we monkey patch it to stop it polluting the test output
|
|
|
|
// with a false-negative error
|
|
|
|
global.console.error = () => {};
|
|
|
|
try {
|
|
|
|
await runTest(directory, "return-undefined.js");
|
|
|
|
} finally {
|
|
|
|
global.console.error = originalConsoleError;
|
|
|
|
}
|
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
|
2018-02-23 01:05:50 +03:00
|
|
|
it("Event handlers", async () => {
|
|
|
|
await runTest(directory, "event-handlers.js");
|
|
|
|
});
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Class component as root", async () => {
|
|
|
|
await runTest(directory, "class-root.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Class component as root with multiple render methods", async () => {
|
|
|
|
await runTest(directory, "class-root-with-render-methods.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Class component as root with props", async () => {
|
|
|
|
await runTest(directory, "class-root-with-props.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Class component as root with state", async () => {
|
|
|
|
await runTest(directory, "class-root-with-state.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Class component as root with refs", async () => {
|
|
|
|
await runTest(directory, "class-root-with-refs.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Class component as root with instance variables", async () => {
|
|
|
|
await runTest(directory, "class-root-with-instance-vars.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
it("Class component as root with instance variables #2", async () => {
|
|
|
|
await runTest(directory, "class-root-with-instance-vars-2.js");
|
|
|
|
});
|
2018-01-31 01:18:34 +03:00
|
|
|
|
|
|
|
it("Additional functions closure scope capturing", async () => {
|
|
|
|
await runTest(directory, "additional-function-regression.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
});
|
|
|
|
|
2017-12-16 19:04:37 +03:00
|
|
|
describe("Class component folding", () => {
|
|
|
|
let directory = "class-components";
|
|
|
|
|
|
|
|
it("Simple classes", async () => {
|
|
|
|
await runTest(directory, "simple-classes.js");
|
|
|
|
});
|
2018-01-17 05:46:19 +03:00
|
|
|
|
|
|
|
it("Simple classes #2", async () => {
|
|
|
|
await runTest(directory, "simple-classes-2.js");
|
|
|
|
});
|
|
|
|
|
2018-01-31 01:52:01 +03:00
|
|
|
it("Simple classes #3", async () => {
|
|
|
|
await runTest(directory, "simple-classes-3.js");
|
|
|
|
});
|
|
|
|
|
2018-02-07 22:24:56 +03:00
|
|
|
it("Inheritance chaining", async () => {
|
|
|
|
await runTest(directory, "inheritance-chain.js");
|
|
|
|
});
|
|
|
|
|
2018-01-17 05:46:19 +03:00
|
|
|
it("Classes with state", async () => {
|
|
|
|
await runTest(directory, "classes-with-state.js");
|
|
|
|
});
|
2017-11-16 16:12:31 +03:00
|
|
|
});
|
2018-01-24 22:23:51 +03:00
|
|
|
|
2018-02-03 04:39:53 +03:00
|
|
|
describe("Factory class component folding", () => {
|
|
|
|
let directory = "factory-components";
|
|
|
|
|
|
|
|
it("Simple factory classes", async () => {
|
|
|
|
await runTest(directory, "simple.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Simple factory classes 2", async () => {
|
|
|
|
await runTest(directory, "simple2.js");
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-03-01 09:05:02 +03:00
|
|
|
describe("Render props", () => {
|
|
|
|
let directory = "render-props";
|
|
|
|
|
|
|
|
it("Relay QueryRenderer", async () => {
|
|
|
|
await runTest(directory, "relay-query-renderer.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Relay QueryRenderer 2", async () => {
|
|
|
|
await runTest(directory, "relay-query-renderer2.js");
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-01-24 22:23:51 +03:00
|
|
|
describe("fb-www mocks", () => {
|
|
|
|
let directory = "mocks";
|
|
|
|
|
|
|
|
it("fb-www", async () => {
|
2018-02-09 15:42:10 +03:00
|
|
|
await stubReactRelay(async () => {
|
|
|
|
await runTest(directory, "fb1.js");
|
|
|
|
});
|
2018-01-24 22:23:51 +03:00
|
|
|
});
|
2018-01-26 18:45:32 +03:00
|
|
|
|
|
|
|
it("fb-www 2", async () => {
|
|
|
|
await runTest(directory, "fb2.js");
|
|
|
|
});
|
2018-01-31 18:53:30 +03:00
|
|
|
|
|
|
|
it("fb-www 3", async () => {
|
2018-02-09 15:42:10 +03:00
|
|
|
await stubReactRelay(async () => {
|
|
|
|
await runTest(directory, "fb3.js");
|
|
|
|
});
|
2018-01-31 18:53:30 +03:00
|
|
|
});
|
2018-01-31 22:48:33 +03:00
|
|
|
|
|
|
|
it("fb-www 4", async () => {
|
2018-02-09 15:42:10 +03:00
|
|
|
await stubReactRelay(async () => {
|
|
|
|
await runTest(directory, "fb4.js");
|
|
|
|
});
|
2018-01-31 22:48:33 +03:00
|
|
|
});
|
2018-02-02 15:41:47 +03:00
|
|
|
|
|
|
|
it("fb-www 5", async () => {
|
|
|
|
await runTest(directory, "fb5.js");
|
|
|
|
});
|
2018-02-06 01:08:06 +03:00
|
|
|
|
|
|
|
it("fb-www 6", async () => {
|
|
|
|
await runTest(directory, "fb6.js");
|
|
|
|
});
|
2018-02-09 15:42:10 +03:00
|
|
|
|
|
|
|
it("fb-www 7", async () => {
|
|
|
|
await runTest(directory, "fb7.js");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("fb-www 8", async () => {
|
|
|
|
await runTest(directory, "fb8.js");
|
|
|
|
});
|
2018-02-13 19:34:42 +03:00
|
|
|
|
2018-02-22 03:09:52 +03:00
|
|
|
it("fb-www 9", async () => {
|
|
|
|
await runTest(directory, "fb9.js");
|
|
|
|
});
|
|
|
|
|
2018-02-13 19:34:42 +03:00
|
|
|
it("repl example", async () => {
|
|
|
|
await runTest(directory, "repl-example.js");
|
|
|
|
});
|
2018-02-16 18:58:44 +03:00
|
|
|
|
|
|
|
it("Hacker News app", async () => {
|
|
|
|
let data = JSON.parse(getDataFile(directory, "hacker-news.json"));
|
|
|
|
await runTest(directory, "hacker-news.js", data);
|
|
|
|
});
|
2018-01-24 22:23:51 +03:00
|
|
|
});
|
2017-11-02 14:28:37 +03:00
|
|
|
});
|
2017-12-16 19:04:37 +03:00
|
|
|
}
|
2017-12-05 19:10:54 +03:00
|
|
|
|
2018-02-22 03:09:52 +03:00
|
|
|
// pre non-transpiled
|
|
|
|
runTestSuite(true, false);
|
|
|
|
runTestSuite(false, false);
|
|
|
|
// pre transpiled
|
|
|
|
runTestSuite(true, true);
|
|
|
|
runTestSuite(false, true);
|