Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion bin/jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,23 @@ require("commoner").resolve(function(id) {

// Constant propagation means removing any obviously dead code after
// replacing constant expressions with literal (boolean) values.
return propagate(constants, source);
source = propagate(constants, source);

// Make sure there is exactly one newline at the end of the module.
source = source.replace(/\s+$/m, "\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad @benjamn. No modifying files unnecessarily.


if (constants.__MOCK__) {
return context.getProvidedP().then(function(idToPath) {
if (id !== "mock-modules" &&
id !== "mocks" &&
idToPath.hasOwnProperty("mock-modules")) {
return source + '\nrequire("mock-modules").register(' +
JSON.stringify(id) + ', module);\n';
}

return source;
});
}

return source;
});
57 changes: 56 additions & 1 deletion grunt/config/browserify.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,60 @@ function simpleBannerify(src) {
'\n' + src;
}

var TEST_PRELUDE = [
"(function(modules, cache, entry) {",
" var hasOwn = cache.hasOwnProperty;",
" function require(name) {",
" if (!hasOwn.call(cache, name)) {",
" var m = cache[name] = { exports: {} };",
" modules[name][0].call(m.exports, function(relID) {",
" var id = modules[name][1][relID];",
" return require(id ? id : relID);",
" }, m, m.exports);",
" }",
" return cache[name].exports;",
" }",
"",
" require.dumpCache = function() { cache = {} };",
"",
" for(var i = 0, len = entry.length; i < len; ++i)",
" require(entry[i]);",
"",
" return require;",
"})"
].join("\n");

function monkeyPatchDumpCache(src) {
var ch, start = 0, depth = 0;

// Parsing the entire source with Esprima would be cleaner but also
// prohibitively expensive (multiple seconds), and regular expressions
// don't balance parentheses well. So we take a hybrid parenthesis
// counting approach that fails noisily if things go awry.
for (var i = 0, len = src.length; i < len; ++i) {
ch = src.charAt(i);
if (ch === "(") {
if (depth++ === 0) {
var expected = "(function";
if (src.slice(i, i + expected.length) !== expected) {
throw new Error(
"Refusing to replace react-test.js prelude because first " +
"opening parenthesis did not begin a function expression: " +
src.slice(i, 100) + "..."
);
}
start = i;
}
} else if (ch === ")") {
if (--depth === 0) {
return src.slice(0, start) + TEST_PRELUDE + src.slice(i + 1);
}
}
}

throw new Error("Unable to replace react-test.js prelude.");
}

// Our basic config which we'll add to to make our other builds
var basic = {
entries: [
Expand Down Expand Up @@ -96,7 +150,8 @@ var test = {
],
outfile: './build/react-test.js',
debug: false,
standalone: false
standalone: false,
after: [monkeyPatchDumpCache]
};

module.exports = {
Expand Down
1 change: 1 addition & 0 deletions grunt/config/jsx/debug.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"debug": true,
"constants": {
"__MOCK__": true,
"__DEV__": true
}
}
80 changes: 74 additions & 6 deletions src/test/mock-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,86 @@
* @providesModule mock-modules
*/

var global = Function("return this")();
require('test/mock-timers').installMockTimers(global);
var mocks = require("mocks");
var exportsRegistry = {};

function getMock(exports) {
try {
return mocks.generateFromMetadata(
mocks.getMetadata(exports));
} catch (err) {
console.warn(err);
return exports;
}
}

// This function should be called at the bottom of any module that might
// need to be mocked, after the final value of module.exports is known.
exports.register = function(id, module) {
var directive = exportsRegistry[id];

exportsRegistry[id] = {
module: module,
actual: module.exports,
mocked: null // Filled in lazily later.
};

// If doMock or doNotMock was called earlier, before the module was
// registered, then we ought to have recorded the choice as a string
// literal. Now that the module is registered, we can finally fulfill
// the request.
if (directive === "doNotMock") {
doNotMock(id);
} else if (directive === "doMock") {
doMock(id);
}

return exports;
};

exports.dumpCache = function() {
// This .clear() call intelligently resets all mocked properties that
// have been modified, so we don't have to recreate every mock exports
// object or invalidate the exportsRegistry.
require("mocks").clear();
global.require.dumpCache();
return exports;
};

exports.dontMock = function() {
// Call this function to ensure that require(id) returns the actual
// exports object created by the module.
function doNotMock(id) {
var entry = exportsRegistry[id];
if (entry && entry.module && entry.actual) {
entry.module.exports = entry.actual;
} else {
// When this module is first registered, make sure NOT to mock it.
exportsRegistry[id] = "doNotMock";
}

return exports;
};
}

// Call this function to ensure that require(id) returns a mock exports
// object based on the actual exports object created by the module.
function doMock(id) {
var entry = exportsRegistry[id];
if (entry && entry.module && entry.actual) {
entry.module.exports = entry.mocked || (
// Because mocking can be expensive, create the mock exports
// object on demand, the first time doMock is called.
entry.mocked = getMock(entry.actual));
} else {
// When this module is first registered, make sure TO mock it.
exportsRegistry[id] = "doMock";
}

exports.mock = function() {
return exports;
};
}

var global = Function("return this")();
require('test/mock-timers').installMockTimers(global);

// Exported names are different for backwards compatibility.
exports.dontMock = doNotMock;
exports.mock = doMock;
7 changes: 4 additions & 3 deletions src/test/mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,16 +305,17 @@ function removeUnusedRefs(metadata) {
});
}

var dirtyMocks = [];
var global = Function("return this")();
global.dirtyMocks = global.dirtyMocks || [];

module.exports = {
/**
* Invokes the .mockClear method of all function mocks that have been
* called since the last time clear was called.
*/
clear: function() {
var old = dirtyMocks;
dirtyMocks = [];
var old = global.dirtyMocks;
global.dirtyMocks = [];
old.forEach(function(mock) {
mock.mockClear();
});
Expand Down