Skip to content

Instantly share code, notes, and snippets.

@bradly
Created August 26, 2011 17:31
Show Gist options
  • Select an option

  • Save bradly/1173917 to your computer and use it in GitHub Desktop.

Select an option

Save bradly/1173917 to your computer and use it in GitHub Desktop.
Simple JavaScript Unit Testing
// i18n.js
// Copyright 2011 Bradly Feeley
// Language attribute should be added to the html nodes.
// <html lang="en">
//
// Alternatively, you can set the language by passing an argument to the I18n.set_locale function.
//
// Early in the layout view before all other js:
// <script src="/javascripts/i18n.js" type="text/javascript" charset="utf-8"></script>
//
// Example:
// I18n.locales.en = { 'personal_greeting' : 'Hello, {{name}}!'};
// I18n.locales.es = { 'personal_greeting' : 'Hola, {{name}}!'};
// I18n.set_locale('en');
// I18n.t('personal_greeting', {'name' : 'Bradly'});
// #=> Hello, Bradly!
// I18n.set_locale('es');
// I18n.t('personal_greeting', {'name' : 'Bradly'});
// #=> Hola, Bradly!
var I18n = {
'locales' : { 'en' : {} },
'default_locale' : 'en',
'locale' : 'en',
't' : function (key, args) {
var arg;
var translation;
var arg_regex;
if (this.locales[this.locale] === undefined) {
this.locales[this.locale] = {};
}
translation = this.locales[this.locale][key];
if (args !== undefined) {
for (arg in args) {
arg_regex = new RegExp('{{' + arg + '}}', 'g');
translation = translation.replace(arg_regex, args[arg]);
}
}
return translation || 'missing_translation: ' + key;
},
'set_locale' : function (new_locale) {
if (new_locale === undefined) {
var html_node = document.getElementsByTagName('html')[0];
this.locale = html_node.lang || this.default_locale;
} else {
this.locale = new_locale;
}
}
};
// Run with TestRuner.run_tests(I18n);
I18n.test_suite = {
'before_all' : function() { },
'before_each' : function() { I18n.set_locale('en'); },
'after_all' : function() { },
'after_each' : function() { },
'should set default locale' : [function () {
return I18n.locale;
}, I18n.default_locale],
'should set locale when passed in' : [function () {
I18n.set_locale('it');
return I18n.locale;
}, 'it'],
'should return missing translation when locale does not exist' : [function () {
I18n.set_locale('it');
return I18n.t('some_missing_translation');
}, 'missing_translation: some_missing_translation'],
'should return translation when found' : [function () {
I18n.locales.en.test_tranlation = 'Translation in English!';
return I18n.t('test_tranlation');
}, 'Translation in English!'],
'should return missing translation when a translation is not found' : [function () {
return I18n.t('some_missing_translation');
}, 'missing_translation: some_missing_translation'],
'should allow variables to be passed in' : [function () {
I18n.locales.en.hello_name = 'Hello, {{name}}!';
return I18n.t('hello_name', {'name' : 'Bradly'});
}, 'Hello, Bradly!'],
'should allow variables to be used more than once' : [function () {
I18n.locales.en.hello_name = 'Hello, {{name}}! Your name is {{name}}.';
return I18n.t('hello_name', {'name' : 'Bradly'});
}, 'Hello, Bradly! Your name is Bradly.'],
'should allow multiple variables to be used' : [function () {
I18n.locales.en.greeting = '{{greeting}}, {{name}}!';
return I18n.t('greeting', {'greeting' : 'Hi', 'name' : 'Bradly'});
}, 'Hi, Bradly!']
};
// Copyright 2011 Bradly Feeley
var TestRuner = {
'number_of_tests' : 0,
'number_of_tests_passed' : 0,
'number_of_tests_failed' : 0,
'start_time' : null,
'end_time' : null,
'run_time' : null,
'targets' : null,
'ensure_test_target_has_tests' : function (test_target) {
if (!test_target.hasOwnProperty('test_suite')) {
throw('TestSuiteNotFoundException');
}
},
'logger' : function (message) {
// document.write(message + '<br />');
// print(message);
// $stdin(message);
console.log(message);
},
'run_test' : function (test_name, test_case) {
var error = null;
var result = null;
var expected = test_case[1];
try {
result = test_case[0]();
} catch (exception) {
error = exception;
}
if (result === expected) {
this.test_passed();
this.number_of_tests_passed += 1;
} else {
this.number_of_tests_failed += 1;
this.test_failed(test_name, expected, (error || result));
}
},
'run_tests' : function (test_target) {
this.ensure_test_target_has_tests(test_target);
this.number_of_tests_failed = 0;
this.start_time = (new Date()).getTime();
this.number_of_tests = Object.keys(test_target.test_suite).length;
var test_suite = test_target.test_suite;
var test_case = null;
if (test_suite['before_all'] !== undefined) {
test_suite['before_all']();
} else {
this.logger('error...');
}
for (test_name in test_suite) {
if (test_suite.hasOwnProperty(test_name) && test_name.match(/^should/)) {
if (test_suite['before_each'] !== undefined) {
test_suite['before_each']();
}
this.run_test( test_name, test_target.test_suite[test_name] );
if (test_suite['after_each'] !== undefined) {
test_suite['after_each']();
}
}
}
if (test_suite['after_all'] !== undefined) {
test_suite['after_all']();
}
this.end_time = (new Date()).getTime();
this.run_time = (this.end_time - this.start_time) / 1000.0;
this.number_of_tests = this.number_of_tests_passed + this.number_of_tests_failed;
if ( this.number_of_failed == 0 ) {
this.all_passed();
} else if ( this.number_of_tests_passed == 0 ) {
this.all_failed();
}
this.complete();
},
'start' : function () {
this.logger('Running ' + this.number_of_tests + ' tests...');
},
'test_passed' : function (test_name) {
this.logger('.');
},
'all_passed' : function () {
this.logger('Good to go!');
},
'all_failed' : function () {
// this.logger('Oh noes!');
},
'test_failed' : function (test_name, expected, result) {
this.logger('`' + test_name + '` failed: expected `' + expected + '`, but got `' + result + '`');
},
'complete' : function () {
this.logger(this.number_of_tests + ' tests run in ' + this.run_time + ' seconds.');
this.logger(this.number_of_tests_passed + ' passed, ' + this.number_of_tests_failed + ' failed.');
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment