Index: misc/drupal.js =================================================================== RCS file: /cvs/drupal/drupal/misc/drupal.js,v retrieving revision 1.48 diff -u -p -r1.48 drupal.js --- misc/drupal.js 1 Nov 2008 21:38:56 -0000 1.48 +++ misc/drupal.js 24 Dec 2008 01:04:35 -0000 @@ -1,6 +1,6 @@ // $Id: drupal.js,v 1.48 2008/11/01 21:38:56 dries Exp $ -var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} }; +var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {}, 'tests': {} }; /** * Set the variable that indicates if JavaScript behaviors should be applied. Index: misc/test.js =================================================================== RCS file: misc/test.js diff -N misc/test.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ misc/test.js 24 Dec 2008 01:04:35 -0000 @@ -0,0 +1,173 @@ +// $Id$ + +/** + * Run any number of tests + * + * @param name + * Optional. Either an array of test names (prefix them with test, as in testSomething), + * a string which is a function name in the Drupal.tests namespace (it's a test if it's + * prefixed with test, as in testSomething), or if left out, it will be come all tests. + * @return + * The result of the tests. + */ +Drupal.test = function(name) { + Drupal.tests.compileTests(); + if (!name) { + var name = Drupal.tests._tests; + } + + if (name instanceof Array) { + var results = {}; + $.each(name, function() { + results[this] = Drupal.test.executeTest(this); + }); + return results; + } + else { + return Drupal.test.executeTest(name); + } +}; + +Drupal.test.executeTest = function(name) { + Drupal.tests[name](); + var results = Drupal.tests._results; + Drupal.tests._results = []; + return results; +} + +/** + * An array of results for the currently running test. + */ +Drupal.tests._results = []; + +/** + * Get all tests that have been defined. + * + * @return + * An array of all defined tests. + */ +Drupal.tests.compileTests = function() { + var tests = []; + for (i in Drupal.tests) { + if (i.substr(0, 4) == 'test') { + tests.push(i); + } + } + Drupal.tests._tests = tests; +} + +/** + * Logs an assertion to Drupal.tests._results. + * + * @param status + * Whether the assertion passed or failed. + * @param message + * The message to be displayed. + */ +Drupal.tests.assert = function(status, message) { + Drupal.tests._results.push({ + status: status, + message: message, + }); +}; + +/** + * Comes up with random text + * + * @param number + * The number of characters to generate. Default is 4. + * @param prefix + * The prefix to prepend to the string. Default is 'drupal'. + */ +Drupal.tests.randomName = function(number, prefix) { + if (!prefix) { + var prefix = 'drupal'; + } + if (!number) { + var number = 4; + } + var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'; + for (i = 0; i < number; i++) { + prefix += chars[Math.random(0, chars.length - 1)]; + if (i == 0) { + chars += '0123456789'; + } + } + return prefix; +}; + +/** + * Asserts whether a value is true + * + * @param value + * A boolean value + * @param message + * A message to be displayed to the user + */ +Drupal.tests.assertTrue = function(value, message) { + Drupal.tests.assert(value == true, message); +}; + +/** + * Asserts whether a value is false + * + * @param value + * A boolean value + * @param message + * A message to be displayed to the user + */ +Drupal.tests.assertFalse = function(value, message) { + Drupal.tests.assert(value == false, message); +}; + +/** + * Asserts whether two values are equal + * + * @param value1 + * A mixed value to be compared with value2 + * @param value2 + * A mixed value to be compared with value1 + * @param message + * A message to be displayed to the user + */ +Drupal.tests.assertEqual = function(value1, value2, message) { + Drupal.tests.assert(value1 == value2, message); +}; + +/** + * Asserts whether two values are not equal + * + * @param value1 + * A mixed value to be compared with value2 + * @param value2 + * A mixed value to be compared with value1 + * @param message + * A message to be displayed to the user + */ +Drupal.tests.assertNotEqual = function(value1, value2, message) { + Drupal.tests.assert(value != value2, message); +}; + +/** + * Asserts whether an element exists + * + * @param selector + * A valid jQuery selector + * @param message + * A message to be displayed to the user + */ +Drupal.tests.assertElement = function(selector, message) { + Drupal.tests.assert($(selector).size(), message); +}; + +/** + * Asserts whether an element doesn't exist + * + * @param selector + * A valid jQuery selector + * @param message + * A message to be displayed to the user + */ +Drupal.tests.assertNoElement = function(selector, message) { + Drupal.tests.assert($(selector).size() == 0, message); +}; Index: misc/tests.drupal.js =================================================================== RCS file: misc/tests.drupal.js diff -N misc/tests.drupal.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ misc/tests.drupal.js 24 Dec 2008 01:04:35 -0000 @@ -0,0 +1,163 @@ +// $Id$ + +/** + * @file Tests for drupal.js + */ + +/** + * Test the attachBehaviors function + */ +Drupal.tests.testAttachBehaviors = function() { + var oldBehaviors = Drupal.behaviors, text = Drupal.tests.randomName(10); + Drupal.behaviors = {}; + Drupal.behaviors.testBehavior = { + attach: function(context) { + Drupal.tests.assertTrue(true, 'Behavior fired'); + Drupal.tests.assertEqual(context, text, 'Correct context passed in'); + } + }; + + Drupal.attachBehaviors(text); + Drupal.behaviors = oldBehaviors; +} + +/** + * Test the checkPlain function + */ +Drupal.tests.testCheckPlain = function() { + Drupal.tests.assertEqual(Drupal.checkPlain('test'), 'test', "Nothing gets replaced that doesn't need to be replaced with their escaped equivalent"); + Drupal.tests.assertEqual(Drupal.checkPlain('"test'), '"test', 'Quotes are replaced with their escaped equivalent'); + Drupal.tests.assertEqual(Drupal.checkPlain('Test&1'), 'Test&1', 'Ampersands are replaced with their escaped equivalent'); + Drupal.tests.assertEqual(Drupal.checkPlain('Test>test'), 'Test>test', 'Greater-than signs are replaced with their escaped equivalent'); + Drupal.tests.assertEqual(Drupal.checkPlain('TestStuff'), '<tagname property="value">Stuff</tagname>', ''); + Drupal.tests.assertEqual(Drupal.checkPlain('Test"&".'), 'Test "&"', ''); +}; + +/** + * Test the t function + */ +Drupal.tests.testT = function() { + // Empty the localized strings, but store them + if (Drupal.locale.strings) { + var oldStrings = Drupal.locale.strings; + delete Drupal.locale.strings; + } + + // Test t() without string replacement + var text = Drupal.tests.randomName(8); + Drupal.tests.assertEqual(Drupal.t(text), text, "Text that doesn't have arguments isn't changed"); + var key = Drupal.tests.randomName(5), value = Drupal.tests.randomName(3) + '<', replacement = {}; + replacement['!'+ key] = value; + replacement['@'+ key] = value; + replacement['%'+ key] = value; + Drupal.tests.assertEqual(Drupal.t(text +' !'+ key +' '+ text, replacement), text +' '+ value +' '+ text, "Argument replacement with ! doesn't change text but replaces properly"); + Drupal.tests.assertEqual(Drupal.t(text +' @'+ key +' '+ text, replacement), text +' '+ Drupal.checkPlain(value) +' '+ text, "Argument replacement with @ replaces properly and runs through checkPlain"); + Drupal.tests.assertEqual(Drupal.t(text +' %'+ key +' '+ text, replacement), text +' '+ Drupal.theme('placeholder', value) +' '+ text, "Argument replacement with % replaces properly, runs through checkPlain, and runs through theme('placeholder')"); + + // Test multiple arguments + var key2 = Drupal.tests.randomName(4), value2 = '"'+ Drupal.tests.randomName(6) +'&'; + replacement['!'+ key2] = value2; + replacement['@'+ key2] = value2; + replacement['%'+ key2] = value2; + Drupal.tests.assertEqual(Drupal.t(text +' !'+ key +' '+ text +' !'+ key2, replacement), text +' '+ value +' '+ text + value2, "Two-argument replacement with ! doesn't change text but replaces properly"); + Drupal.tests.assertEqual(Drupal.t(text +' !'+ key +' '+ text +' @'+ key2, replacement), text +' '+ value +' '+ text + Drupal.checkPlain(value2), "Two-argument replacement with ! and @ replaces properly"); + Drupal.tests.assertEqual(Drupal.t(text +' @'+ key +' '+ text +' @'+ key2, replacement), text +' '+ Drupal.checkPlain(value) +' '+ text + Drupal.checkPlain(value2), "Two-argument replacement with @ replaces properly"); + Drupal.tests.assertEqual(Drupal.t(text +' %'+ key +' '+ text + ' %'+ key2, replacement), text +' '+ Drupal.theme('placeholder', value) +' '+ text + Drupal.theme('placeholder', value2), "Two-argument replacement with % replaces properly, runs through checkPlain, and runs through theme('placeholder')"); + + // Actual localization/translation tests + Drupal.locale.strings = {}; + Drupal.locale.strings[key] = value; + Drupal.locale.strings[key2] = value2; + Drupal.locale.strings['This is a test %replacement'] = 'is-thay is-ay a-ay est-tay %replacement'; + Drupal.tests.assertEqual(Drupal.t(key), value, 'Text is translated'); + Drupal.tests.assertEqual(Drupal.t(key2), value2, 'More text is translated'); + Drupal.tests.assertEqual(Drupal.t('This is a test %replacement', { '%replacement': 'Replacement' }), 'is-thay is-ay a-ay est-tay '+ Drupal.theme('placeholder', 'Replacement'), 'Text is translated with placeholders'); + + // Done testing, revert to original strings + if (oldStrings) { + Drupal.locale.strings = oldStrings; + } + else { + delete Drupal.locale.strings; + } +}; + +/** + * Test the formatPlural function + */ +Drupal.tests.testFormatPlural = function() { + // Do set up + if (Drupal.locale.pluralFormula) { + var oldFormula = Drupal.locale.pluralFormula; + } + if (Drupal.locale.strings) { + var oldStrings = Drupal.locale.strings; + delete Drupal.locale.strings; + } + // Check default plural format + Drupal.tests.assertEqual(Drupal.formatPlural(1, 'Say hello world 1 time', 'Say hello world @count times'), 'Say hello world 1 time', 'Singular was returned when count was 1'); + Drupal.tests.assertEqual(Drupal.formatPlural(5, 'Say hello world 1 time', 'Say hello world @count times'), 'Say hello world 5 times', 'Plural was returned when count was 5'); + // Check with argument replacement + Drupal.tests.assertEqual(Drupal.formatPlural(1, 'Say hello world 1 time', 'Say hello world @count. This is @arg1', {'@arg1': 'my first argument'}), 'Say hello world 1 time', 'Singular was returned when count was 1, and no replacements occured'); + Drupal.tests.assertEqual(Drupal.formatPlural(5, 'Say hello world 1 time', 'Say hello world @count. This is @arg1', {'@arg1': 'my first argument'}), 'Say hello world 5 times', 'Plural was returned when count was 5, and the replacement happened'); + + if (oldFormula) { + Drupal.locale.pluralFormula = oldFormula; + } + if (oldStrings) { + Drupal.locale.strings = oldStrings; + } +} + +/** + * Test the theme function + */ +Drupal.tests.testTheme = function() { + var text = Drupal.tests.randomName(8); + Drupal.theme.prototype.testThemeFunction = function(argument) { + Drupal.tests.assertTrue(true, 'Theme function in prototype was called'); + Drupal.tests.assertEqual(text, argument, 'Argument passed in was correct'); + return { 'key': 'value', 'arg': argument }; + } + value = Drupal.theme('testThemeFunction', text); + Drupal.tests.assertEqual(value.key, 'value', 'Value was returned correctly from theme function in prototype'); + delete Drupal.theme.prototype.testThemeFunction; + + var text = Drupal.tests.randomName(8); + Drupal.theme.testThemeFunction = function(argument) { + Drupal.tests.assertTrue(true, 'Theme function not in prototype was called'); + Drupal.tests.assertEqual(text, argument, 'Argument passed in was correct'); + return { 'key': 'value', 'arg': argument }; + } + value = Drupal.theme('testThemeFunction', text); + Drupal.tests.assertEqual(value.key, 'value', 'Value was returned correctly from theme function not in prototype'); + delete Drupal.theme.testThemeFunction; +} + +/** + * Test the parseJson function + */ +Drupal.tests.testParseJson = function() { + Drupal.tests.assertEqual(Drupal.parseJson('{key: "value"}'), {key: "value"}, 'Drupal.parseJson parsed an object'); + Drupal.tests.assertEqual(Drupal.parseJson('[1, 2]'), [1, 2], 'Drupal.parseJson parsed an array'); + Drupal.tests.assertEqual(Drupal.parseJson('1'), {status: 0, data: 1 }, 'Drupal.parseJson threw a proper error'); +} + +/** + * Test the freezeHeight and unfreezeHeight functions + */ +Drupal.tests.testFreezeHeight = function() { + Drupal.freezeHeight(); + Drupal.tests.assertElement('#freeze-height', 'The freeze-height element exists'); + var element = $('#freeze-height'); + Drupal.tests.assertEqual(element.css('height'), $('body').css('height'), 'The height is correct'); + Drupal.unfreezeHeight(); + Drupal.tests.assertNoElement('#freeze-height', "The freeze-height element has been removed and doesn't exist"); +}