Merge pull request #4873 from gisikw/repair_broken_test_suite

Repair Broken Test Suite - Full Passing Tests
This commit is contained in:
Alys
2015-03-26 14:49:28 +10:00
14 changed files with 147 additions and 79 deletions

2
.gitignore vendored
View File

@@ -23,3 +23,5 @@ test/*.map
website/public/docs website/public/docs
*.sublime-workspace *.sublime-workspace
coverage.html coverage.html
test/spec/translations.js

View File

@@ -154,8 +154,8 @@ module.exports = function(grunt) {
fileNameFormat: '${name}-${hash}.${ext}' fileNameFormat: '${name}-${hash}.${ext}'
}, },
src: [ src: [
'website/build/*.js', 'website/build/*.js',
'website/build/*.css', 'website/build/*.css',
'website/build/favicon.ico', 'website/build/favicon.ico',
'website/build/common/dist/sprites/*.png', 'website/build/common/dist/sprites/*.png',
'website/build/common/img/sprites/backer-only/*.gif', 'website/build/common/img/sprites/backer-only/*.gif',
@@ -166,7 +166,7 @@ module.exports = function(grunt) {
} }
}, },
nodemon: { nodemon: {
dev: { dev: {
script: '<%= pkg.main %>' script: '<%= pkg.main %>'
} }
@@ -202,7 +202,7 @@ module.exports = function(grunt) {
_.each(files[key].js, function(val){ _.each(files[key].js, function(val){
var path = "./"; var path = "./";
if( val.indexOf('common/') == -1) if( val.indexOf('common/') == -1)
path = './website/public/'; path = './website/public/';
js.push(path + val); js.push(path + val);
}); });
@@ -213,7 +213,7 @@ module.exports = function(grunt) {
var path = "./"; var path = "./";
if( val.indexOf('common/') == -1) { if( val.indexOf('common/') == -1) {
path = (val == 'app.css' || val == 'static.css') ? './website/build/' : './website/public/'; path = (val == 'app.css' || val == 'static.css') ? './website/build/' : './website/public/';
} }
css.push(path + val) css.push(path + val)
}); });
@@ -231,9 +231,19 @@ module.exports = function(grunt) {
grunt.registerTask('compile:sprites', ['clean:sprite', 'sprite', 'cssmin']); grunt.registerTask('compile:sprites', ['clean:sprite', 'sprite', 'cssmin']);
grunt.registerTask('build:prod', ['loadManifestFiles', 'clean:build', 'browserify', 'uglify', 'stylus', 'cssmin', 'copy:build', 'hashres']); grunt.registerTask('build:prod', ['loadManifestFiles', 'clean:build', 'browserify', 'uglify', 'stylus', 'cssmin', 'copy:build', 'hashres']);
grunt.registerTask('build:dev', ['browserify', 'stylus']); grunt.registerTask('build:dev', ['browserify', 'stylus']);
grunt.registerTask('build:test', ['test:prepare:translations', 'build:dev']);
grunt.registerTask('run:dev', [ 'build:dev', 'concurrent' ]); grunt.registerTask('run:dev', [ 'build:dev', 'concurrent' ]);
grunt.registerTask('test:prepare:translations', function() {
require('coffee-script');
var i18n = require('./website/src/i18n'),
fs = require('fs');
fs.writeFileSync('test/spec/translations.js',
"if(!window.env) window.env = {};\n" +
"window.env.translations = " + JSON.stringify(i18n.translations['en']) + ';');
});
if(process.env.NODE_ENV == 'production') if(process.env.NODE_ENV == 'production')
grunt.registerTask('default', ['build:prod']); grunt.registerTask('default', ['build:prod']);
else else

View File

@@ -4889,7 +4889,11 @@ module.exports = {
if ((locale == null) || (!module.exports.strings && !module.exports.translations[locale])) { if ((locale == null) || (!module.exports.strings && !module.exports.translations[locale])) {
locale = 'en'; locale = 'en';
} }
string = !module.exports.strings ? module.exports.translations[locale][stringName] : module.exports.strings[stringName]; if (module.exports.strings) {
string = module.exports.strings[stringName];
} else {
string = module.exports.translations[locale] && module.exports.translations[locale][stringName];
}
clonedVars = _.clone(vars) || {}; clonedVars = _.clone(vars) || {};
clonedVars.locale = locale; clonedVars.locale = locale;
if (string) { if (string) {
@@ -4900,7 +4904,11 @@ module.exports = {
return 'Error processing string. Please report to http://github.com/HabitRPG/habitrpg.'; return 'Error processing string. Please report to http://github.com/HabitRPG/habitrpg.';
} }
} else { } else {
stringNotFound = !module.exports.strings ? module.exports.translations[locale].stringNotFound : module.exports.strings.stringNotFound; if (module.exports.strings) {
stringNotFound = module.exports.strings.stringNotFound;
} else if (module.exports.translations[locale]) {
stringNotFound = module.exports.translations[locale] && module.exports.translations[locale].stringNotFound;
}
try { try {
return _.template(stringNotFound, { return _.template(stringNotFound, {
string: stringName string: stringName

View File

@@ -1,6 +1,6 @@
_ = require 'lodash' _ = require 'lodash'
module.exports = module.exports =
strings: null, # Strings for one single language strings: null, # Strings for one single language
translations: {} # Strings for multiple languages {en: strings, de: strings, ...} translations: {} # Strings for multiple languages {en: strings, de: strings, ...}
t: (stringName) -> # Other parameters allowed are vars (Object) and locale (String) t: (stringName) -> # Other parameters allowed are vars (Object) and locale (String)
@@ -14,10 +14,16 @@ module.exports =
locale = arguments[2] locale = arguments[2]
locale = 'en' if (!locale? or (!module.exports.strings and !module.exports.translations[locale])) locale = 'en' if (!locale? or (!module.exports.strings and !module.exports.translations[locale]))
string = if (!module.exports.strings) then module.exports.translations[locale][stringName] else module.exports.strings[stringName]
if module.exports.strings
clonedVars = _.clone(vars) or {}; string = module.exports.strings[stringName]
clonedVars.locale = locale; else
string =
module.exports.translations[locale] and
module.exports.translations[locale][stringName]
clonedVars = _.clone(vars) or {}
clonedVars.locale = locale
if string if string
try try
@@ -25,8 +31,14 @@ module.exports =
catch e catch e
'Error processing string. Please report to http://github.com/HabitRPG/habitrpg.' 'Error processing string. Please report to http://github.com/HabitRPG/habitrpg.'
else else
stringNotFound = if (!module.exports.strings) then module.exports.translations[locale].stringNotFound else module.exports.strings.stringNotFound if module.exports.strings
stringNotFound = module.exports.strings.stringNotFound
else if module.exports.translations[locale]
stringNotFound =
module.exports.translations[locale] and
module.exports.translations[locale].stringNotFound
try try
_.template(stringNotFound, {string: stringName}) _.template(stringNotFound, {string: stringName})
catch e catch e
'Error processing string. Please report to http://github.com/HabitRPG/habitrpg.' 'Error processing string. Please report to http://github.com/HabitRPG/habitrpg.'

View File

@@ -34,6 +34,8 @@ module.exports = function(config) {
'website/public/bower_components/js-emoji/emoji.js', 'website/public/bower_components/js-emoji/emoji.js',
'common/dist/scripts/habitrpg-shared.js', 'common/dist/scripts/habitrpg-shared.js',
"test/spec/translations.js",
"website/public/js/env.js", "website/public/js/env.js",
"website/public/js/app.js", "website/public/js/app.js",
@@ -96,6 +98,8 @@ module.exports = function(config) {
// - IE (only Windows) // - IE (only Windows)
browsers: ['PhantomJS'], browsers: ['PhantomJS'],
// Enable mocha-style reporting, for better test visibility
reporters: ['mocha'],
// Continuous Integration mode // Continuous Integration mode
// if true, it capture browsers, run tests and exit // if true, it capture browsers, run tests and exit

View File

@@ -92,6 +92,7 @@
"karma-html2js-preprocessor": "~0.1.0", "karma-html2js-preprocessor": "~0.1.0",
"karma-jasmine": "~0.1.3", "karma-jasmine": "~0.1.3",
"karma-mocha": "0.1.3", "karma-mocha": "0.1.3",
"karma-mocha-reporter": "^1.0.2",
"karma-ng-html2js-preprocessor": "~0.1.0", "karma-ng-html2js-preprocessor": "~0.1.0",
"karma-phantomjs-launcher": "~0.1.0", "karma-phantomjs-launcher": "~0.1.0",
"karma-requirejs": "~0.2.0", "karma-requirejs": "~0.2.0",

View File

@@ -19,6 +19,6 @@ exports.config = {
// Options to be passed to Jasmine-node. // Options to be passed to Jasmine-node.
jasmineNodeOpts: { jasmineNodeOpts: {
showColors: true, showColors: true,
defaultTimeoutInterval: 30000 defaultTimeoutInterval: 60000
} }
}; };

View File

@@ -37,7 +37,7 @@ describe('front page', function() {
var login = element(by.css("#login-tab input[value='Login']")); var login = element(by.css("#login-tab input[value='Login']"));
login.click(); login.click();
var alertDialog = browser.switchTo().alert(); var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toMatch(/Username 'username' not found/); expect(alertDialog.getText()).toMatch(/Username or password incorrect./);
alertDialog.accept(); alertDialog.accept();
}); });
@@ -58,4 +58,4 @@ describe('front page', function() {
expect(url).not.toMatch(/static\/front/); expect(url).not.toMatch(/static\/front/);
}); });
}); });
}); });

View File

@@ -5,39 +5,55 @@ TEST_DB_URI="mongodb://localhost/$TEST_DB"
TEST_SERVER_PORT=3001 TEST_SERVER_PORT=3001
# Build assets # Build assets
grunt build:dev grunt build:test
# Launch Node server and Selenium # Launch Node server and Selenium
echo "Recreating test database" echo "= Recreating test database"
mongo "$TEST_DB" --eval "db.dropDatabase()" mongo "$TEST_DB" --eval "db.dropDatabase()"
if [ -z "$TRAVIS" ]; then if [ -z "$TRAVIS" ]; then
./node_modules/protractor/bin/webdriver-manager update if [ -z "$1" ] || [ "$1" == "protractor" ]; then
./node_modules/protractor/bin/webdriver-manager start > /dev/null & ./node_modules/protractor/bin/webdriver-manager update
trap "curl http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer" EXIT ./node_modules/protractor/bin/webdriver-manager start > /dev/null &
trap "curl http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer" EXIT
# Wait for selenium # Wait for selenium
MAX_WAIT=30 MAX_WAIT=30
WAITED=0 WAITED=0
until nc -z localhost 4444; do until nc -z localhost 4444; do
if [ $WAITED -ge $MAX_WAIT ]; then if [ $WAITED -ge $MAX_WAIT ]; then
echo "Waited $MAX_WAIT seconds, but Selenium never responded" >&2 echo "Waited $MAX_WAIT seconds, but Selenium never responded" >&2
kill $NODE_PID kill $NODE_PID
exit 1 exit 1
fi fi
sleep 1 sleep 1
let 'WAITED+=1' let 'WAITED+=1'
done done
fi
fi fi
NODE_DB_URI="$TEST_DB_URI" PORT=$TEST_SERVER_PORT node ./website/src/server.js > /dev/null & NODE_DB_URI="$TEST_DB_URI" PORT=$TEST_SERVER_PORT node ./website/src/server.js > /dev/null &
NODE_PID=$! NODE_PID=$!
trap "kill $NODE_PID" EXIT trap "kill $NODE_PID" EXIT
NODE_ENV=testing mocha || exit $? if [ -z "$1" ] || [ "$1" == "mocha" ]; then
echo "= Running mocha specs"
if [ -z "$TRAVIS" ]; then NODE_ENV=testing mocha || exit $?
NODE_ENV=testing ./node_modules/protractor/bin/protractor protractor.conf.js || exit $?
fi fi
NODE_ENV=testing grunt karma:continuous # If we're only running protractor, we need to let the server spin up.
if [ "$1" == "protractor" ]; then
sleep 2
fi
if [ -z "$TRAVIS" ]; then
if [ -z "$1" ] || [ "$1" == "protractor" ]; then
echo "= Running protractor specs"
NODE_ENV=testing ./node_modules/protractor/bin/protractor protractor.conf.js || exit $?
fi
fi
if [ -z "$1" ] || [ "$1" == "karma" ]; then
echo "= Running karma specs"
NODE_ENV=testing grunt karma:continuous || exit $?
fi

View File

@@ -1,8 +1,6 @@
'use strict'; 'use strict';
// @TODO translations aren't loading describe('Auth Controller', function() {
xdescribe('Auth Controller', function() {
describe('AuthCtrl', function(){ describe('AuthCtrl', function(){
var scope, ctrl, user, $httpBackend, $window; var scope, ctrl, user, $httpBackend, $window;

View File

@@ -3,7 +3,6 @@
describe('Filters Controller', function() { describe('Filters Controller', function() {
var scope, user; var scope, user;
beforeEach(module('habitrpg'));
beforeEach(inject(function($rootScope, $controller, Shared) { beforeEach(inject(function($rootScope, $controller, Shared) {
user = specHelper.newUser(); user = specHelper.newUser();
Shared.wrap(user); Shared.wrap(user);

View File

@@ -1,15 +1,18 @@
'use strict'; 'use strict';
// @TODO the requests via $resource seem to be describe('groupServices', function() {
// doing a full page reload which breaks the specs var $httpBackend, $http, groups;
xdescribe('groupServices', function() { beforeEach(function() {
var $httpBackend, groups; module(function($provide) {
$provide.value('User', {});
});
beforeEach(inject(function(_$httpBackend_, Groups) { inject(function(_$httpBackend_, Groups, User) {
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
groups = Groups; groups = Groups;
})); });
});
it('calls party endpoint', function() { it('calls party endpoint', function() {
$httpBackend.expectGET('/api/v2/groups/party').respond({}); $httpBackend.expectGET('/api/v2/groups/party').respond({});

View File

@@ -1,23 +1,31 @@
'use strict'; 'use strict';
// @TODO Address why translations aren't loading
// Possibly related to https://github.com/HabitRPG/habitrpg/commit/5aa401524934e6d9071f13cb2ccca0dba13cdcff
describe('Inventory Controller', function() { describe('Inventory Controller', function() {
var scope, ctrl, user, $rootScope; var scope, ctrl, user, $rootScope;
beforeEach(inject(function($rootScope, $controller, Shared){ beforeEach(function() {
user = specHelper.newUser(); module(function($provide) {
user.balance = 4, $provide.value('User', {});
user.items = {eggs: {Cactus: 1}, hatchingPotions: {Base: 1}, food: {Meat: 1}, pets: {}}; });
Shared.wrap(user);
var mockWindow = { inject(function($rootScope, $controller, Shared){
confirm: function(msg){ user = specHelper.newUser();
return true; user.balance = 4,
} user.items = {eggs: {Cactus: 1}, hatchingPotions: {Base: 1}, food: {Meat: 1}, pets: {}, mounts: {}};
}; Shared.wrap(user);
scope = $rootScope.$new(); var mockWindow = {
ctrl = $controller('InventoryCtrl', {$scope: scope, User: {user: user}, $window: mockWindow}); confirm: function(msg){
})); return true;
}
};
scope = $rootScope.$new();
// Load RootCtrl to ensure shared behaviors are loaded
$controller('RootCtrl', {$scope: scope, User: {user: user}, $window: mockWindow});
ctrl = $controller('InventoryCtrl', {$scope: scope, User: {user: user}, $window: mockWindow});
});
});
it('starts without any item selected', function(){ it('starts without any item selected', function(){
expect(scope.selectedEgg).to.eql(null); expect(scope.selectedEgg).to.eql(null);
@@ -35,7 +43,7 @@ describe('Inventory Controller', function() {
expect(scope.selectedPotion.key).to.eql('Base'); expect(scope.selectedPotion.key).to.eql('Base');
}); });
xit('hatches a pet', function(){ it('hatches a pet', function(){
scope.chooseEgg('Cactus'); scope.chooseEgg('Cactus');
scope.choosePotion('Base'); scope.choosePotion('Base');
expect(user.items.eggs).to.eql({Cactus: 0}); expect(user.items.eggs).to.eql({Cactus: 0});
@@ -66,13 +74,13 @@ describe('Inventory Controller', function() {
expect(user.stats.gp).to.eql(1); expect(user.stats.gp).to.eql(1);
}); });
xit('chooses a pet', function(){ it('chooses a pet', function(){
user.items.pets['Cactus-Base'] = 5; user.items.pets['Cactus-Base'] = 5;
scope.choosePet('Cactus', 'Base'); scope.choosePet('Cactus', 'Base');
expect(user.items.currentPet).to.eql('Cactus-Base'); expect(user.items.currentPet).to.eql('Cactus-Base');
}); });
xit('purchases an egg', inject(function(Content){ it('purchases an egg', inject(function(Content){
scope.purchase('eggs', Content.eggs['Wolf']); scope.purchase('eggs', Content.eggs['Wolf']);
expect(user.balance).to.eql(3.25); expect(user.balance).to.eql(3.25);
expect(user.items.eggs).to.eql({Cactus: 1, Wolf: 1}) expect(user.items.eggs).to.eql({Cactus: 1, Wolf: 1})

View File

@@ -1,18 +1,24 @@
'use strict'; 'use strict';
xdescribe('Root Controller', function() { // @TODO: Something here is calling a full page reload
describe('Root Controller', function() {
var scope, user, ctrl; var scope, user, ctrl;
beforeEach(inject(function($rootScope, $controller) { beforeEach(function () {
scope = $rootScope.$new(); module(function($provide) {
scope.loginUsername = 'user' $provide.value('User', {});
scope.loginPassword = 'pass' });
user = specHelper.newUser();
inject(function($rootScope, $controller) {
scope = $rootScope.$new();
scope.loginUsername = 'user'
scope.loginPassword = 'pass'
user = specHelper.newUser();
ctrl = $controller('RootCtrl', {$scope: scope, User: {user: user}});
});
});
ctrl = $controller('RootCtrl', {$scope: scope, User: {user: user}});
}));
// @TODO: Fix translations not loading here
it('shows contributor level text', function(){ it('shows contributor level text', function(){
expect(scope.contribText()).to.eql(undefined); expect(scope.contribText()).to.eql(undefined);
expect(scope.contribText(null, {npc: 'NPC'})).to.eql('NPC'); expect(scope.contribText(null, {npc: 'NPC'})).to.eql('NPC');
@@ -24,8 +30,9 @@ xdescribe('Root Controller', function() {
expect(scope.contribText({level: 5, text: 'Blacksmith'})).to.eql('Champion Blacksmith'); expect(scope.contribText({level: 5, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
expect(scope.contribText({level: 6, text: 'Blacksmith'})).to.eql('Champion Blacksmith'); expect(scope.contribText({level: 6, text: 'Blacksmith'})).to.eql('Champion Blacksmith');
expect(scope.contribText({level: 7, text: 'Blacksmith'})).to.eql('Legendary Blacksmith'); expect(scope.contribText({level: 7, text: 'Blacksmith'})).to.eql('Legendary Blacksmith');
expect(scope.contribText({level: 8, text: 'Blacksmith'})).to.eql('Heroic Blacksmith'); expect(scope.contribText({level: 8, text: 'Blacksmith'})).to.eql('Guardian Blacksmith');
expect(scope.contribText({level: 8, text: 'Blacksmith'}, {npc: 'NPC'})).to.eql('NPC'); expect(scope.contribText({level: 9, text: 'Blacksmith'})).to.eql('Heroic Blacksmith');
expect(scope.contribText({level: 9, text: 'Blacksmith'}, {npc: 'NPC'})).to.eql('NPC');
}); });
}); });