@samitouri / QOS-React-2 / commits / 204796868d
Fork 0

The library for web and native user interfaces.

Enable module.exports mocking in react-test.js.

We don't currently attempt to mock modules automatically, but we do respect require("mock-modules").mock, .dontMock, and .dumpCache. I'm going to keep investigating auto-mocking, since that would move us much closer to the behavior used within Facebook. Closes #154. Closes #155.

Ben Newman committed Jul 3, 2013 at 12:22 UTC 204796868d377acbcbbb1e2de4698b8827dc6b83
1 file changed +82 -9
src/test/mock-modules.js
+82 -9
@@ -16,22 +16,95 @@
16 * @providesModule mock-modules
17 */
18
19 +var mocks = require("mocks");
20 +var exportsRegistry = {};
21 +var hasOwn = exportsRegistry.hasOwnProperty;
22 +var explicitMockMap = {};
23 +
24 +function getMock(exports) {
25 + try {
26 + return mocks.generateFromMetadata(mocks.getMetadata(exports));
27 + } catch (err) {
28 + console.warn(err);
29 + return exports;
30 + }
31 +}
32 +
33 +// This function should be called at the bottom of any module that might
34 +// need to be mocked, after the final value of module.exports is known.
35 exports.register = function(id, module) {
20 - // TODO
36 + exportsRegistry[id] = {
37 + module: module,
38 + actual: module.exports,
39 + mocked: null // Filled in lazily later.
40 + };
41 +
42 + // If doMock or doNotMock was called earlier, before the module was
43 + // registered, then the choice should have been recorded in
44 + // explicitMockMap. Now that the module is registered, we can finally
45 + // fulfill the request.
46 + if (hasOwn.call(explicitMockMap, id)) {
47 + if (explicitMockMap[id]) {
48 + doMock(id);
49 + } else {
50 + doNotMock(id);
51 + }
52 + }
53 +
54 + return exports;
55 };
56
57 +function resetEntry(id) {
58 + if (hasOwn.call(exportsRegistry, id)) {
59 + delete exportsRegistry[id].module.exports;
60 + delete exportsRegistry[id];
61 + }
62 +}
63 +
64 exports.dumpCache = function() {
24 - require("mocks").clear();
25 - return exports;
26 -};
65 + require("mocks").clear();
66
28 -exports.dontMock = function() {
29 - return exports;
30 -};
67 + // Deleting module.exports will cause the module to be lazily
68 + // reevaluated the next time it is required.
69 + for (var id in exportsRegistry) {
70 + resetEntry(id);
71 + }
72
32 -exports.mock = function() {
33 - return exports;
73 + return exports;
74 };
75
76 +// Call this function to ensure that require(id) returns the actual
77 +// exports object created by the module.
78 +function doNotMock(id) {
79 + explicitMockMap[id] = false;
80 +
81 + var entry = exportsRegistry[id];
82 + if (entry && entry.module && entry.actual) {
83 + entry.module.exports = entry.actual;
84 + }
85 +
86 + return exports;
87 +}
88 +
89 +// Call this function to ensure that require(id) returns a mock exports
90 +// object based on the actual exports object created by the module.
91 +function doMock(id) {
92 + explicitMockMap[id] = true;
93 +
94 + var entry = exportsRegistry[id];
95 + if (entry && entry.module && entry.actual) {
96 + // Because mocking can be expensive, create the mock exports object on
97 + // demand, the first time doMock is called.
98 + entry.mocked || (entry.mocked = getMock(entry.actual));
99 + entry.module.exports = entry.mocked;
100 + }
101 +
102 + return exports;
103 +}
104 +
105 var global = Function("return this")();
106 require('test/mock-timers').installMockTimers(global);
107 +
108 +// Exported names are different for backwards compatibility.
109 +exports.dontMock = doNotMock;
110 +exports.mock = doMock;