(function() { var _ = typeof require == 'function' ? require('..') : window._; var templateSettings; QUnit.module('Utility', { beforeEach: function() { templateSettings = _.clone(_.templateSettings); }, afterEach: function() { _.templateSettings = templateSettings; } }); if (typeof this == 'object') { QUnit.test('noConflict', function(assert) { var underscore = _.noConflict(); assert.strictEqual(underscore.identity(1), 1); if (typeof require != 'function') { assert.strictEqual(this._, void 0, 'global underscore is removed'); this._ = underscore; } else if (typeof global !== 'undefined') { delete global._; } }); } if (typeof require == 'function') { QUnit.test('noConflict (node vm)', function(assert) { assert.expect(2); var done = assert.async(); var fs = require('fs'); var vm = require('vm'); var filename = __dirname + '/../underscore.js'; fs.readFile(filename, function(err, content){ var sandbox = vm.createScript( content + 'this.underscore = this._.noConflict();', filename ); var context = {_: 'oldvalue'}; sandbox.runInNewContext(context); assert.strictEqual(context._, 'oldvalue'); assert.strictEqual(context.underscore.VERSION, _.VERSION); done(); }); }); } QUnit.test('#750 - Return _ instance.', function(assert) { assert.expect(2); var instance = _([]); assert.strictEqual(_(instance), instance); assert.strictEqual(new _(instance), instance); }); QUnit.test('identity', function(assert) { var stooge = {name: 'moe'}; assert.strictEqual(_.identity(stooge), stooge, 'stooge is the same as his identity'); }); QUnit.test('constant', function(assert) { var stooge = {name: 'moe'}; assert.strictEqual(_.constant(stooge)(), stooge, 'should create a function that returns stooge'); }); QUnit.test('noop', function(assert) { assert.strictEqual(_.noop('curly', 'larry', 'moe'), void 0, 'should always return undefined'); }); QUnit.test('random', function(assert) { var array = _.range(1000); var min = Math.pow(2, 31); var max = Math.pow(2, 62); assert.ok(_.every(array, function() { return _.random(min, max) >= min; }), 'should produce a random number greater than or equal to the minimum number'); assert.ok(_.some(array, function() { return _.random(Number.MAX_VALUE) > 0; }), 'should produce a random number when passed `Number.MAX_VALUE`'); }); QUnit.test('now', function(assert) { var diff = _.now() - new Date().getTime(); assert.ok(diff <= 0 && diff > -5, 'Produces the correct time in milliseconds');//within 5ms }); QUnit.test('uniqueId', function(assert) { var ids = [], i = 0; while (i++ < 100) ids.push(_.uniqueId()); assert.strictEqual(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids'); }); QUnit.test('times', function(assert) { var vals = []; _.times(3, function(i) { vals.push(i); }); assert.deepEqual(vals, [0, 1, 2], 'is 0 indexed'); // vals = []; _(3).times(function(i) { vals.push(i); }); assert.deepEqual(vals, [0, 1, 2], 'works as a wrapper'); // collects return values assert.deepEqual([0, 1, 2], _.times(3, function(i) { return i; }), 'collects return values'); assert.deepEqual(_.times(0, _.identity), []); assert.deepEqual(_.times(-1, _.identity), []); assert.deepEqual(_.times(parseFloat('-Infinity'), _.identity), []); }); QUnit.test('mixin', function(assert) { var ret = _.mixin({ myReverse: function(string) { return string.split('').reverse().join(''); } }); assert.strictEqual(ret, _, 'returns the _ object to facilitate chaining'); assert.strictEqual(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _'); assert.strictEqual(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper'); }); QUnit.test('_.escape', function(assert) { assert.strictEqual(_.escape(null), ''); }); QUnit.test('_.unescape', function(assert) { var string = 'Curly & Moe'; assert.strictEqual(_.unescape(null), ''); assert.strictEqual(_.unescape(_.escape(string)), string); assert.strictEqual(_.unescape(string), string, 'don\'t unescape unnecessarily'); }); // Don't care what they escape them to just that they're escaped and can be unescaped QUnit.test('_.escape & unescape', function(assert) { // test & (&) separately obviously var escapeCharacters = ['<', '>', '"', '\'', '`']; _.each(escapeCharacters, function(escapeChar) { var s = 'a ' + escapeChar + ' string escaped'; var e = _.escape(s); assert.notEqual(s, e, escapeChar + ' is escaped'); assert.strictEqual(s, _.unescape(e), escapeChar + ' can be unescaped'); s = 'a ' + escapeChar + escapeChar + escapeChar + 'some more string' + escapeChar; e = _.escape(s); assert.strictEqual(e.indexOf(escapeChar), -1, 'can escape multiple occurrences of ' + escapeChar); assert.strictEqual(_.unescape(e), s, 'multiple occurrences of ' + escapeChar + ' can be unescaped'); }); // handles multiple escape characters at once var joiner = ' other stuff '; var allEscaped = escapeCharacters.join(joiner); allEscaped += allEscaped; assert.ok(_.every(escapeCharacters, function(escapeChar) { return allEscaped.indexOf(escapeChar) !== -1; }), 'handles multiple characters'); assert.ok(allEscaped.indexOf(joiner) >= 0, 'can escape multiple escape characters at the same time'); // test & -> & var str = 'some string & another string & yet another'; var escaped = _.escape(str); assert.notStrictEqual(escaped.indexOf('&'), -1, 'handles & aka &'); assert.strictEqual(_.unescape(str), str, 'can unescape &'); }); QUnit.test('template', function(assert) { var basicTemplate = _.template("<%= thing %> is gettin' on my noives!"); var result = basicTemplate({thing: 'This'}); assert.strictEqual(result, "This is gettin' on my noives!", 'can do basic attribute interpolation'); var sansSemicolonTemplate = _.template('A <% this %> B'); assert.strictEqual(sansSemicolonTemplate(), 'A B'); var backslashTemplate = _.template('<%= thing %> is \\ridanculous'); assert.strictEqual(backslashTemplate({thing: 'This'}), 'This is \\ridanculous'); var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>'); assert.strictEqual(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.'); var fancyTemplate = _.template(''); result = fancyTemplate({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}}); assert.strictEqual(result, '', 'can run arbitrary javascript in templates'); var escapedCharsInJavaScriptTemplate = _.template(''); result = escapedCharsInJavaScriptTemplate({numbers: 'one\ntwo\nthree\nfour'}); assert.strictEqual(result, '', 'Can use escaped characters (e.g. \\n) in JavaScript'); var namespaceCollisionTemplate = _.template('<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %>
<% }); %>'); result = namespaceCollisionTemplate({ pageCount: 3, thumbnails: { 1: 'p1-thumbnail.gif', 2: 'p2-thumbnail.gif', 3: 'p3-thumbnail.gif' } }); assert.strictEqual(result, '3 p3-thumbnail.gif
'); var noInterpolateTemplate = _.template('

Just some text. Hey, I know this is silly but it aids consistency.

'); result = noInterpolateTemplate(); assert.strictEqual(result, '

Just some text. Hey, I know this is silly but it aids consistency.

'); var quoteTemplate = _.template("It's its, not it's"); assert.strictEqual(quoteTemplate({}), "It's its, not it's"); var quoteInStatementAndBody = _.template('<% ' + " if(foo == 'bar'){ " + "%>Statement quotes and 'quotes'.<% } %>"); assert.strictEqual(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'."); var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.'); assert.strictEqual(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.'); var template = _.template('<%- value %>'); result = template({value: '