Files
meteor/tools/tests/batch-plugins.js
David Glasser 774b9754ec Test less caching, and improve client refresh
Specifically, ensure that we don't even include client-specific files in
the server WatchSet by making sure we pass a precise set of extensions
to initFromAppDir.  We still also rule out wrong-arch files at a later
stage too (because sourceExtensions only affects initFromAppDir).

Without the change to compiler.js, the final test (adding
yet-another-root.main.less) restarts the server rather than printing
"Client modified -- refreshing".
2015-06-08 22:41:55 -07:00

123 lines
5.0 KiB
JavaScript

var _ = require('underscore');
var selftest = require('../selftest.js');
var files = require('../files.js');
var Sandbox = selftest.Sandbox;
var MONGO_LISTENING =
{ stdout: " [initandlisten] waiting for connections on port" };
// Tests the actual cache logic used by coffeescript and less.
selftest.define("compiler plugin caching", function () {
var s = new Sandbox({ fakeMongo: true });
// Create an app that uses coffeescript and less.
s.createApp("myapp", "coffee-and-less");
s.cd("myapp");
// Ask them to print out when they build a file (instead of using it from the
// cache).
s.set("METEOR_TEST_PRINT_ON_CACHE_MISS", "t");
var run = s.run();
run.match("myapp");
run.match("proxy");
run.tellMongo(MONGO_LISTENING);
run.match("MongoDB");
// First program built (server or web.browser) compiles everything.
run.match('Ran coffee.compile (#1) on: ' + JSON.stringify(
['/f1.coffee', '/f2.coffee', '/f3.coffee', '/packages/local-pack/p.coffee']
));
run.match('Ran less.render (#1) on: ' + JSON.stringify(
["/subdir/nested-root.main.less", "/top.main.less"]));
// Second program doesn't need to compile anything because compilation works
// the same on both programs. (Note that there is no less.render execution in
// the second program, because it has archMatching: 'web'. We'll see this
// more clearly when the next call later is "#2" --- we didn't miss a call!)
run.match("Ran coffee.compile (#2) on: []");
// App prints this:
run.match("Coffeescript X is 2 Y is 1 FromPackage is 4");
// Check that the CSS is what we expect.
var checkCSS = selftest.markStack(function (borderStyleMap) {
var builtBrowserProgramDir = files.pathJoin(
s.cwd, '.meteor', 'local', 'build', 'programs', 'web.browser');
var cssFile = _.find(
files.readdir(
files.pathJoin(s.cwd, '.meteor/local/build/programs/web.browser')),
function (path) {
return path.match(/\.css$/);
}
);
selftest.expectTrue(cssFile);
var actual = s.read(
files.pathJoin('.meteor/local/build/programs/web.browser', cssFile));
actual = actual.replace(/\s+/g, ' '); // simplify whitespace
var expected = _.map(borderStyleMap, function (style, className) {
return '.' + className + " { border-style: " + style + "; }";
}).join(' ');
selftest.expectEqual(actual, expected);
});
var expectedBorderStyles = {
el0: "dashed", el1: "dotted", el2: "solid", el3: "groove", el4: "ridge"};
checkCSS(expectedBorderStyles);
s.write("f2.coffee", "share.Y = 'Y is 3'\n");
// Only recompiles f2.
run.match('Ran coffee.compile (#3) on: ["/f2.coffee"]');
run.match('Ran less.render (#2) on: []');
// And other program doesn't even need to do f2.
run.match("Ran coffee.compile (#4) on: []");
// Program prints this:
run.match("Coffeescript X is 2 Y is 3 FromPackage is 4");
// Force a rebuild of the local package without actually changing the
// coffeescript file in it. This should not require us to coffee.compile
// anything (for either program).
s.append("packages/local-pack/package.js", "\n// foo\n");
run.match("Ran coffee.compile (#5) on: []");
run.match('Ran less.render (#3) on: []');
run.match("Ran coffee.compile (#6) on: []");
run.match("Coffeescript X is 2 Y is 3 FromPackage is 4");
// But writing to the actual source file in the local package should
// recompile.
s.write("packages/local-pack/p.coffee", "FromPackage = 'FromPackage is 5'");
run.match('Ran coffee.compile (#7) on: ["/packages/local-pack/p.coffee"]');
run.match('Ran less.render (#4) on: []');
run.match('Ran coffee.compile (#8) on: []');
run.match("Coffeescript X is 2 Y is 3 FromPackage is 5");
// Writing to a single less file only re-renders the root that depends on it.
s.write('packages/local-pack/p.less', '@el4-style: inset;\n');
expectedBorderStyles.el4 = 'inset';
run.match('Ran coffee.compile (#9) on: []');
run.match('Ran less.render (#5) on: ["/top.main.less"]');
// Note that since this was a client-only change, we're smart enough to not
// rebuild the server at all. So the next coffee.compile will be #10.
run.match("Client modified -- refreshing");
checkCSS(expectedBorderStyles);
// This works for changing a root too.
s.write('subdir/nested-root.main.less', '.el0 { border-style: double; }\n');
expectedBorderStyles.el0 = 'double';
// Only #10, not #11, because client-only changes don't rebuild the server!
run.match('Ran coffee.compile (#10) on: []');
run.match('Ran less.render (#6) on: ["/subdir/nested-root.main.less"]');
run.match("Client modified -- refreshing");
checkCSS(expectedBorderStyles);
// Adding a new root works too.
s.write('yet-another-root.main.less', '.el6 { border-style: solid; }\n');
expectedBorderStyles.el6 = 'solid';
run.match('Ran coffee.compile (#11) on: []');
run.match('Ran less.render (#7) on: ["/yet-another-root.main.less"]');
run.match("Client modified -- refreshing");
checkCSS(expectedBorderStyles);
run.stop();
});
// XXX BBP test that modifying a local plugin works