From 3fea961f0614050676c295dff2d9d8ea2240ca91 Mon Sep 17 00:00:00 2001 From: Michael Jackson Date: Thu, 6 Dec 2012 10:13:23 -0800 Subject: [PATCH] Use mocha for testing --- CHANGES | 4 + package.json | 4 +- test/context-test.js | 51 +++++++++++ test/context_test.js | 47 ----------- test/helper.js | 2 + test/{parse_test.js => parse-test.js} | 26 +++--- test/render-test.js | 68 +++++++++++++++ test/render_test.js | 66 --------------- test/scanner-test.js | 78 +++++++++++++++++ test/scanner_test.js | 117 -------------------------- test/writer-test.js | 43 ++++++++++ test/writer_test.js | 44 ---------- 12 files changed, 259 insertions(+), 291 deletions(-) create mode 100644 test/context-test.js delete mode 100644 test/context_test.js create mode 100644 test/helper.js rename test/{parse_test.js => parse-test.js} (91%) create mode 100644 test/render-test.js delete mode 100644 test/render_test.js create mode 100644 test/scanner-test.js delete mode 100644 test/scanner_test.js create mode 100644 test/writer-test.js delete mode 100644 test/writer_test.js diff --git a/CHANGES b/CHANGES index 15d7e7c74..32cced730 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ += HEAD + + * Converted tests to use mocha instead of vows. + = 0.7.1 / 6 Dec 2012 * Handle empty templates gracefully. Fixes #265, #267, and #270. diff --git a/package.json b/package.json index e9c709f5c..3549fedfd 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "keywords": ["mustache", "template", "templates", "ejs"], "main": "./mustache.js", "devDependencies": { - "vows": "0.6.x" + "mocha": "1.5.0" }, "volo": { "url": "https://raw.github.com/janl/mustache.js/0.7.1/mustache.js" }, "scripts": { - "test": "vows --spec" + "test": "mocha test" } } diff --git a/test/context-test.js b/test/context-test.js new file mode 100644 index 000000000..752f74bc7 --- /dev/null +++ b/test/context-test.js @@ -0,0 +1,51 @@ +require('./helper'); +var Context = Mustache.Context; + +describe('A new Mustache.Context', function () { + var context; + beforeEach(function () { + context = new Context({ name: 'parent', message: 'hi', a: { b: 'b' } }); + }); + + it('is able to lookup properties of its own view', function () { + assert.equal(context.lookup('name'), 'parent'); + }); + + it('is able to lookup nested properties of its own view', function () { + assert.equal(context.lookup('a.b'), 'b'); + }); + + describe('when pushed', function () { + beforeEach(function () { + context = context.push({ name: 'child', c: { d: 'd' } }); + }); + + it('returns the child context', function () { + assert.equal(context.view.name, 'child'); + assert.equal(context.parent.view.name, 'parent'); + }); + + it('is able to lookup properties of its own view', function () { + assert.equal(context.lookup('name'), 'child'); + }); + + it("is able to lookup properties of the parent context's view", function () { + assert.equal(context.lookup('message'), 'hi'); + }); + + it('is able to lookup nested properties of its own view', function () { + assert.equal(context.lookup('c.d'), 'd'); + }); + + it('is able to lookup nested properties of its parent view', function () { + assert.equal(context.lookup('a.b'), 'b'); + }); + }); +}); + +describe('Mustache.Context.make', function () { + it('returns the same object when given a Context', function () { + var context = new Context; + assert.strictEqual(Context.make(context), context); + }); +}); diff --git a/test/context_test.js b/test/context_test.js deleted file mode 100644 index eab672947..000000000 --- a/test/context_test.js +++ /dev/null @@ -1,47 +0,0 @@ -var assert = require("assert"); -var vows = require("vows"); -var Context = require("./../mustache").Context; - -vows.describe("Mustache.Context").addBatch({ - "A Context": { - topic: function () { - var view = { name: 'parent', message: 'hi', a: { b: 'b' } }; - var context = new Context(view); - return context; - }, - "is able to lookup properties of its own view": function (context) { - assert.equal(context.lookup("name"), "parent"); - }, - "is able to lookup nested properties of its own view": function (context) { - assert.equal(context.lookup("a.b"), "b"); - }, - "when pushed": { - topic: function (context) { - var view = { name: 'child', c: { d: 'd' } }; - return context.push(view); - }, - "returns the child context": function (context) { - assert.equal(context.view.name, "child"); - assert.equal(context.parent.view.name, "parent"); - }, - "is able to lookup properties of its own view": function (context) { - assert.equal(context.lookup("name"), "child"); - }, - "is able to lookup properties of the parent context's view": function (context) { - assert.equal(context.lookup("message"), "hi"); - }, - "is able to lookup nested properties of its own view": function (context) { - assert.equal(context.lookup("c.d"), "d"); - }, - "is able to lookup nested properties of its parent view": function (context) { - assert.equal(context.lookup("a.b"), "b"); - } - } // when pushed - }, // A Context - "make": { - "returns the same object when given a Context": function () { - var context = new Context; - assert.strictEqual(Context.make(context), context); - } - } -}).export(module); diff --git a/test/helper.js b/test/helper.js new file mode 100644 index 000000000..a91fe499f --- /dev/null +++ b/test/helper.js @@ -0,0 +1,2 @@ +assert = require('assert'); +Mustache = require('../mustache'); diff --git a/test/parse_test.js b/test/parse-test.js similarity index 91% rename from test/parse_test.js rename to test/parse-test.js index b75f87ca7..e706f0004 100644 --- a/test/parse_test.js +++ b/test/parse-test.js @@ -1,9 +1,7 @@ -var assert = require('assert'); -var vows = require('vows'); -var Mustache = require('./../mustache'); +require('./helper'); // A map of templates to their expected token output. Tokens are in the format: -// [type, value, startIndex, endIndex]. +// [type, value, startIndex, endIndex, subTokens]. var expectations = { '' : [], '{{hi}}' : [ [ 'name', 'hi', 0, 6 ] ], @@ -55,16 +53,14 @@ var expectations = { : [ [ '#', 'foo', 0, 8, [ [ '#', 'a', 11, 17, [ [ 'text', ' ', 18, 22 ], [ 'name', 'b', 22, 27 ], [ 'text', '\n', 27, 28 ] ] ] ] ] ] }; -var spec = {}; +describe('Mustache.parse', function () { -for (var template in expectations) { - (function (template, tokens) { - spec['knows how to parse ' + JSON.stringify(template)] = function () { - assert.deepEqual(Mustache.parse(template), tokens); - }; - })(template, expectations[template]); -} + for (var template in expectations) { + (function (template, tokens) { + it('knows how to parse ' + JSON.stringify(template), function () { + assert.deepEqual(Mustache.parse(template), tokens); + }); + })(template, expectations[template]); + } -vows.describe('Mustache.parse').addBatch({ - 'parse': spec -}).export(module); +}); diff --git a/test/render-test.js b/test/render-test.js new file mode 100644 index 000000000..acec47ffd --- /dev/null +++ b/test/render-test.js @@ -0,0 +1,68 @@ +require('./helper'); + +var fs = require('fs'); +var path = require('path'); +var _files = path.join(__dirname, '_files'); + +function getContents(testName, ext) { + return fs.readFileSync(path.join(_files, testName + '.' + ext), 'utf8'); +} + +function getView(testName) { + var view = getContents(testName, 'js'); + if (!view) throw new Error('Cannot find view for test "' + testName + '"'); + return eval(view); +} + +function getPartial(testName) { + try { + return getContents(testName, 'partial'); + } catch (e) { + // No big deal. Not all tests need to test partial support. + } +} + +function getTest(testName) { + var test = {}; + test.view = getView(testName); + test.template = getContents(testName, 'mustache'); + test.partial = getPartial(testName); + test.expect = getContents(testName, 'txt'); + return test; +} + +// You can put the name of a specific test to run in the TEST environment +// variable (e.g. TEST=backslashes vows test/render-test.js) +var testToRun = process.env.TEST; + +var testNames; +if (testToRun) { + testNames = [testToRun]; +} else { + testNames = fs.readdirSync(_files).filter(function (file) { + return (/\.js$/).test(file); + }).map(function (file) { + return path.basename(file).replace(/\.js$/, ''); + }); +} + +describe('Mustache.render', function () { + beforeEach(function () { + Mustache.clearCache(); + }); + + testNames.forEach(function (testName) { + var test = getTest(testName); + + it('knows how to render ' + testName, function () { + var output; + if (test.partial) { + output = Mustache.render(test.template, test.view, { partial: test.partial }); + } else { + output = Mustache.render(test.template, test.view); + } + + assert.equal(output, test.expect); + }); + }); +}); diff --git a/test/render_test.js b/test/render_test.js deleted file mode 100644 index 57f41a111..000000000 --- a/test/render_test.js +++ /dev/null @@ -1,66 +0,0 @@ -var fs = require("fs"); -var path = require("path"); -var assert = require("assert"); -var vows = require("vows"); -var Mustache = require("./../mustache"); - -var _files = path.join(__dirname, "_files"); - -function getContents(testName, ext) { - return fs.readFileSync(path.join(_files, testName + "." + ext), "utf8"); -} - -// You can put the name of a specific test to run in the TEST environment -// variable (e.g. TEST=backslashes vows test/render_test.js) -var testToRun = process.env["TEST"]; - -var testNames; -if (testToRun) { - testNames = [testToRun]; -} else { - testNames = fs.readdirSync(_files).filter(function (file) { - return (/\.js$/).test(file); - }).map(function (file) { - return path.basename(file).replace(/\.js$/, ""); - }); -} - -var spec = {}; - -testNames.forEach(function (testName) { - var view = getContents(testName, "js"); - - if (view) { - view = eval(view); - } else { - console.log("Cannot find view for test: " + testName); - process.exit(); - } - - var template = getContents(testName, "mustache"); - var expect = getContents(testName, "txt"); - - var partial; - try { - partial = getContents(testName, "partial"); - } catch (e) { - // No big deal. - } - - spec["knows how to render " + testName] = function () { - Mustache.clearCache(); - - var output; - if (partial) { - output = Mustache.render(template, view, {partial: partial}); - } else { - output = Mustache.render(template, view); - } - - assert.equal(output, expect); - }; -}); - -vows.describe("Mustache.render").addBatch({ - "render": spec -}).export(module); diff --git a/test/scanner-test.js b/test/scanner-test.js new file mode 100644 index 000000000..9c9766420 --- /dev/null +++ b/test/scanner-test.js @@ -0,0 +1,78 @@ +require('./helper'); +var Scanner = Mustache.Scanner; + +describe('A new Mustache.Scanner', function () { + describe('for an empty string', function () { + it('is at the end', function () { + var scanner = new Scanner(''); + assert(scanner.eos()); + }); + }); + + describe('for a non-empty string', function () { + var scanner; + beforeEach(function () { + scanner = new Scanner('a b c'); + }); + + describe('scan', function () { + describe('when the RegExp matches the entire string', function () { + it('returns the entire string', function () { + var match = scanner.scan(/a b c/); + assert.equal(match, scanner.string); + assert(scanner.eos()); + }); + }); + + describe('when the RegExp matches at index 0', function () { + it('returns the portion of the string that matched', function () { + var match = scanner.scan(/a/); + assert.equal(match, 'a'); + assert.equal(scanner.pos, 1); + }); + }); + + describe('when the RegExp matches at some index other than 0', function () { + it('returns the empty string', function () { + var match = scanner.scan(/b/); + assert.equal(match, ''); + assert.equal(scanner.pos, 0); + }); + }); + + describe('when the RegExp does not match', function () { + it('returns the empty string', function () { + var match = scanner.scan(/z/); + assert.equal(match, ''); + assert.equal(scanner.pos, 0); + }); + }); + }); // scan + + describe('scanUntil', function () { + describe('when the RegExp matches at index 0', function () { + it('returns the empty string', function () { + var match = scanner.scanUntil(/a/); + assert.equal(match, ''); + assert.equal(scanner.pos, 0); + }); + }); + + describe('when the RegExp matches at some index other than 0', function () { + it('returns the string up to that index', function () { + var match = scanner.scanUntil(/b/); + assert.equal(match, 'a '); + assert.equal(scanner.pos, 2); + }); + }); + + describe('when the RegExp does not match', function () { + it('returns the entire string', function () { + var match = scanner.scanUntil(/z/); + assert.equal(match, scanner.string); + assert(scanner.eos()); + }); + }); + }); // scanUntil + }); // for a non-empty string +}); diff --git a/test/scanner_test.js b/test/scanner_test.js deleted file mode 100644 index 5850fe29f..000000000 --- a/test/scanner_test.js +++ /dev/null @@ -1,117 +0,0 @@ -var assert = require("assert"); -var vows = require("vows"); -var Scanner = require("./../mustache").Scanner; - -vows.describe("Mustache.Scanner").addBatch({ - "A Scanner": { - "for an empty string": { - topic: new Scanner(""), - "is at the end of the string": function () { - var scanner = new Scanner(""); - assert(scanner.eos()); - } - }, - "for a non-empty string": { - topic: "a b c", - "when calling scan": { - "when the regexp matches the entire string": { - topic: function (string) { - var scanner = new Scanner(string); - var match = scanner.scan(/a b c/); - this.callback(scanner, match); - }, - "returns the entire string": function (scanner, match) { - assert.equal(match, scanner.string); - }, - "is at the end of the string": function (scanner, match) { - assert(scanner.eos()); - } - }, // when the regexp matches the entire string - "when the regexp matches": { - "at the 0th index": { - topic: function (string) { - var scanner = new Scanner(string); - var match = scanner.scan(/a/); - this.callback(scanner, match); - }, - "returns the portion of the string that was matched": function (scanner, match) { - assert.equal(match, "a"); - }, - "advances the internal pointer the length of the match": function (scanner, match) { - assert.equal(scanner.pos, 1); - } - }, // at the 0th index - "at some index other than 0": { - topic: function (string) { - var scanner = new Scanner(string); - var match = scanner.scan(/b/); - this.callback(scanner, match); - }, - "returns the empty string": function (scanner, match) { - assert.equal(match, ""); - }, - "does not advance the internal pointer": function (scanner, match) { - assert.equal(scanner.pos, 0); - } - } // at some index other than 0 - }, // when the regexp matches - "when the regexp doesn't match": { - topic: function (string) { - var scanner = new Scanner(string); - var match = scanner.scan(/z/); - this.callback(scanner, match); - }, - "returns the empty string": function (scanner, match) { - assert.equal(match, ""); - }, - "does not advance the internal pointer": function (scanner, match) { - assert.equal(scanner.pos, 0); - } - } - }, // when calling scan - "when calling scanUntil": { - "when the regexp matches": { - "at the 0th index": { - topic: function (string) { - var scanner = new Scanner(string); - var match = scanner.scanUntil(/a/); - this.callback(scanner, match); - }, - "returns the empty string": function (scanner, match) { - assert.equal(match, "") - }, - "does not advance the internal pointer": function (scanner, match) { - assert.equal(scanner.pos, 0); - } - }, - "at index 2": { - topic: function (string) { - var scanner = new Scanner(string); - var match = scanner.scanUntil(/b/); - this.callback(scanner, match); - }, - "returns the portion of the string it scanned": function (scanner, match) { - assert.equal(match, "a "); - }, - "advances the internal pointer the length of the match": function (scanner, match) { - assert.equal(scanner.pos, 2); - } - } - }, // when the regexp matches - "when the regexp doesn't match": { - topic: function (string) { - var scanner = new Scanner(string); - var match = scanner.scanUntil(/z/); - this.callback(scanner, match); - }, - "returns the entire string": function (scanner, match) { - assert.equal(match, scanner.string); - }, - "is at the end of the string": function (scanner, match) { - assert(scanner.eos()); - } - } // when the regexp doesn't match - } // when calling scanUntil - } // for a non-empty string - } -}).export(module); diff --git a/test/writer-test.js b/test/writer-test.js new file mode 100644 index 000000000..db2813a5f --- /dev/null +++ b/test/writer-test.js @@ -0,0 +1,43 @@ +require('./helper'); +var Writer = Mustache.Writer; + +describe('A new Mustache.Writer', function () { + var writer; + beforeEach(function () { + writer = new Writer; + }); + + it('loads partials correctly', function () { + var partial = 'The content of the partial.'; + var result = writer.render('{{>partial}}', {}, function (name) { + assert.equal(name, 'partial'); + return partial; + }); + + assert.equal(result, partial); + }); + + it('caches partials by content, not name', function () { + var result = writer.render('{{>partial}}', {}, { + partial: 'partial one' + }); + + assert.equal(result, 'partial one'); + + result = writer.render('{{>partial}}', {}, { + partial: 'partial two' + }); + + assert.equal(result, 'partial two'); + }); + + it('can compile an array of tokens', function () { + var template = 'Hello {{name}}!'; + var tokens = Mustache.parse(template); + var render = writer.compileTokens(tokens, template); + + var result = render({ name: 'Michael' }); + + assert.equal(result, 'Hello Michael!'); + }); +}); diff --git a/test/writer_test.js b/test/writer_test.js deleted file mode 100644 index 10a45872f..000000000 --- a/test/writer_test.js +++ /dev/null @@ -1,44 +0,0 @@ -var assert = require("assert"); -var vows = require("vows"); -var Mustache = require("./../mustache"); -var Writer = Mustache.Writer; - -vows.describe("Mustache.Writer").addBatch({ - "A Writer": { - topic: function () { - var writer = new Writer(); - return writer; - }, - "loads partials correctly": function (writer) { - var partial = "The content of the partial."; - var result = writer.render("{{>partial}}", {}, function (name) { - assert.equal(name, "partial"); - return partial; - }); - - assert.equal(result, partial); - }, - "caches partials by content, not by name": function (writer) { - var result = writer.render("{{>partial}}", {}, { - partial: "partial one" - }); - - assert.equal(result, "partial one"); - - result = writer.render("{{>partial}}", {}, { - partial: "partial two" - }); - - assert.equal(result, "partial two"); - }, - "can compile an array of tokens": function (writer) { - var template = "Hello {{name}}!"; - var tokens = Mustache.parse(template); - var render = writer.compileTokens(tokens, template); - - var result = render({ name: 'Michael' }); - - assert.equal(result, 'Hello Michael!'); - } - } -}).export(module);