From 4720c8953ff57ceda2e5e1b80bb0fd43dc6c1a90 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 20:59:24 +0100 Subject: [PATCH 01/76] Amended readme to clarify deloyment options, closes #116 --- readme.md | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 7367a7cb..e33dc92e 100644 --- a/readme.md +++ b/readme.md @@ -8,11 +8,30 @@ FLL Scoring To have a look at what we are at, see [Testing](https://github.com/FirstLegoLeague/fllscoring/wiki/Testing). No guarantees. -Development prerequisites +Using --------------- +Currently the scoring application can only be reliably used as a hosted service. To use: + +- set up a server running nodejs [nodejs.org](http://nodejs.org) +- [download the source](https://github.com/FirstLegoLeague/fllscoring/archive/master.zip) or clone the repository using git. +- `npm install` +- `node localserver.js` then open [localhost:1390](http://localhost:1390) + - to specify another port, use `node localserver.js -p 8000` + - to add basic authentication, use `node localserver.js -u username:password` + +In the near future, we plan to have "ready to go" software available as: + +- executable, for Windows, Mac OS and Linux +- app, for iOS, Android and windows +- a hosted service, as described above + +Development +--------------- + +Prerequisites + - nodejs [nodejs.org](http://nodejs.org). Make sure you have a recent version (>.10) -- bower (`npm install -g bower`) - grunt (`npm install -g grunt-cli`) Steps @@ -80,12 +99,12 @@ License This projected is licensed under the terms of the [GNU GPL v2.0 licenses](https://raw.githubusercontent.com/FirstLegoLeague/fllscoring/master/LICENSE.txt) Basically, it allows users to legally copy, distribute and modify software. This means you can: -* Copy it onto your own servers, your client’s servers, your own computer, pretty much anywhere you want. There’s no limit to the number of copies you can make. +* Copy it onto your own servers, your client’s servers, your own computer, pretty much anywhere you want. There’s no limit to the number of copies you can make. * Provide a download link on your website. Put the software on a bunch of thumb drives and give them away. Print out the source code and throw it from the rooftops (please don’t, though, because that would waste a lot of paper and make a mess). Charge a fee to distribute the software. * If you want to charge someone to provide the software, set it up on their website or do anything else related to it, you can do so. But, you must give them a copy of the GNU GPL, which basically tells them that they could probably get the software elsewhere for free. Best to be up front about that, and about why you’re charging them. -* If you want to add or remove functionality, go ahead. If you want to use a portion of the code in another project, you can. The only catch is that the other project must also be released under the GPL. Ideally we would want you to share your improvements back with us on this GitHub. -* We welcome your feedback but please remember that this software comes with no guarantees. We are dedicated volunteer and experiences software developpers and will do our best make sure we make a valuable and reliable contribution to the community. However the use of this software is at your own risk. +* If you want to add or remove functionality, go ahead. If you want to use a portion of the code in another project, you can. The only catch is that the other project must also be released under the GPL. Ideally we would want you to share your improvements back with us on this GitHub. +* We welcome your feedback but please remember that this software comes with no guarantees. We are dedicated volunteer and experiences software developpers and will do our best make sure we make a valuable and reliable contribution to the community. However the use of this software is at your own risk. Authors -------- From e91f9f888fe1c13355b116d58187c6097f4b6ca5 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 21:21:00 +0100 Subject: [PATCH 02/76] lint --- src/js/views/scoresheet.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/js/views/scoresheet.js b/src/js/views/scoresheet.js index f88b3769..b668ee03 100644 --- a/src/js/views/scoresheet.js +++ b/src/js/views/scoresheet.js @@ -135,7 +135,7 @@ define('views/scoresheet',[ $scope.missions.every(function(mission) { return mission.objectives.every(function(objective) { return objective.value !== undefined && objective.value !== null; - }) && mission.errors.length == 0; + }) && mission.errors.length === 0; }); // console.log("saveable " + val); @@ -181,10 +181,10 @@ define('views/scoresheet',[ return $fs.write("scoresheets/" + fn,data).then(function() { log('result saved'); $scope.discard(); - alert('Thanks for submitting a score of ' - + data.score - + ' points for team ( ' + data.team.number + ' ) ' + data.team.name - + ' in ' + data.stage.name + ' ' + data.round + '.' + alert('Thanks for submitting a score of ' + + data.score + + ' points for team ( ' + data.team.number + ' ) ' + data.team.name + + ' in ' + data.stage.name + ' ' + data.round + '.' ); },function() { alert('unable to write result'); From 88369df6d1a8f9cb267c86af7edf029b2f9319c4 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 21:21:37 +0100 Subject: [PATCH 03/76] Added hideTotal setting to hide total score if wanted. Closes #123 --- src/views/scoresheet.html | 4 ++-- src/views/settings.html | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/views/scoresheet.html b/src/views/scoresheet.html index d15c19e4..e0f10873 100644 --- a/src/views/scoresheet.html +++ b/src/views/scoresheet.html @@ -30,7 +30,7 @@

Team & round

-
+
Total score: {{score()}}
@@ -98,7 +98,7 @@

Team & round

-
+
Total score: {{score()}}
diff --git a/src/views/settings.html b/src/views/settings.html index 718eebd7..7a352466 100644 --- a/src/views/settings.html +++ b/src/views/settings.html @@ -12,6 +12,10 @@

+

+ + +

From b132a8572e7f721cd8964bb46db672413c4b2ef7 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 21:27:02 +0100 Subject: [PATCH 04/76] lint --- spec/views/rankingSpec.js | 2 +- src/js/views/ranking.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/views/rankingSpec.js b/spec/views/rankingSpec.js index 4a0c9dc1..08a98d21 100644 --- a/spec/views/rankingSpec.js +++ b/spec/views/rankingSpec.js @@ -51,7 +51,7 @@ describe('ranking', function() { $scope.doSort(stage, 'foo',true); expect(stage.sort).toEqual('foo'); expect(stage.rev).toEqual(true); - }) + }); }); describe('export',function() { diff --git a/src/js/views/ranking.js b/src/js/views/ranking.js index 41aec42f..fb0069ca 100644 --- a/src/js/views/ranking.js +++ b/src/js/views/ranking.js @@ -33,8 +33,8 @@ define('views/ranking',[ } else { icon = 'icon-sort-up'; } - } else if (stage.sort == null && col == $scope.sort) { - if (stage.rev == null && $scope.rev) { + } else if (stage.sort === null && col == $scope.sort) { + if (stage.rev === null && $scope.rev) { icon = 'icon-sort-down'; } else { icon = 'icon-sort-up'; @@ -105,7 +105,7 @@ define('views/ranking',[ $scope.csvname[stageId] = encodeURIComponent("ranking_" + stageId + ".csv"); $scope.csvdata[stageId] = "data:text/csv;charset=utf-8," + encodeURIComponent(toCSV(rows)); }); - } + }; // Rebuild CSV data and filenames when scoreboard is updated $scope.$watch("scoreboard", function() { From e0962aab00b76ae70e3f5a5a0764925ff0caa3c8 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 22:07:43 +0100 Subject: [PATCH 05/76] refactor stagesMock to a factory, added more tests for ranking --- spec/mocks/stagesMock.js | 24 +++++----- spec/views/rankingSpec.js | 95 +++++++++++++++++++++++++++++++++++++-- spec/views/scoresSpec.js | 3 +- src/js/views/ranking.js | 8 ++-- 4 files changed, 110 insertions(+), 20 deletions(-) diff --git a/spec/mocks/stagesMock.js b/spec/mocks/stagesMock.js index 55b2ca3b..e46b7c3b 100644 --- a/spec/mocks/stagesMock.js +++ b/spec/mocks/stagesMock.js @@ -1,19 +1,21 @@ -var stagesMock = { - stages: [ +function createStagesMock() { + var stages = [ { id: "practice", name: "Oefenrondes", rounds: 2, $rounds: [1, 2] }, { id: "qualifying", name: "Voorrondes", rounds: 3, $rounds: [1, 2, 3] }, { id: "quarter", name: "Kwart finales", rounds: 0, $rounds: [] }, { id: "semi", name: "Halve finales", rounds: 0, $rounds: [] }, { id: "final", name: "Finale", rounds: 1, $rounds: [1] }, - ], - get: function(id) { - var stages = stagesMock.stages; - var i; - for (i = 0; i < stages.length; i++) { - if (stages[i].id === id) { - return stages[i]; + ]; + return { + stages: stages, + get: function(id) { + var i; + for (i = 0; i < stages.length; i++) { + if (stages[i].id === id) { + return stages[i]; + } } + throw new Error("unknown stage"); } - throw new Error("unknown stage"); - } + }; } diff --git a/spec/views/rankingSpec.js b/spec/views/rankingSpec.js index 08a98d21..41f84a3b 100644 --- a/spec/views/rankingSpec.js +++ b/spec/views/rankingSpec.js @@ -9,15 +9,17 @@ describe('ranking', function() { number: '123', name: 'foo' }; - var fsMock; + var fsMock, stagesMock, scoresMock; beforeEach(function() { angular.mock.module(module.name); angular.mock.inject(function($controller, $rootScope) { $scope = $rootScope.$new(); + scoresMock = createScoresMock(); + stagesMock = createStagesMock(); controller = $controller('rankingCtrl', { '$scope': $scope, - '$scores': createScoresMock(), + '$scores': scoresMock, '$stages': stagesMock, }); }); @@ -27,10 +29,12 @@ describe('ranking', function() { it('should initialize', function() { expect($scope.sort).toEqual('rank'); expect($scope.rev).toEqual(false); + expect($scope.csvdata).toEqual({}); + expect($scope.csvname).toEqual({}); }); }); - describe('sorting',function() { + describe('doSort',function() { it('should sort on the given direction when the column is not sorted',function() { var stage = {}; $scope.doSort(stage, 'foo',false); @@ -54,7 +58,68 @@ describe('ranking', function() { }); }); - describe('export',function() { + describe('sortIcon',function() { + it('should give the up icon when col is sorted',function() { + var stage = { + sort: 'foo' + }; + expect($scope.sortIcon(stage)).toEqual(''); + expect($scope.sortIcon(stage,'foo')).toEqual('icon-sort-up'); + }); + it('should give the up icon when col is sorted in reverse',function() { + var stage = { + sort: 'foo', + rev: true + }; + expect($scope.sortIcon(stage)).toEqual(''); + expect($scope.sortIcon(stage,'foo')).toEqual('icon-sort-down'); + }); + + //default sort order stuff, needs a bit of refactoring + it('should report a default sorting for any stage',function() { + var stage = {}; + expect($scope.sortIcon(stage,'rank')).toEqual('icon-sort-up'); + $scope.rev = true; + expect($scope.sortIcon(stage,'rank')).toEqual('icon-sort-down'); + }); + }); + + describe('toggle',function() { + it('should toggle the collapsed state of a stage',function() { + var stage = {}; + $scope.toggle(stage); + expect(stage.$collapsed).toBe(true); + $scope.toggle(stage); + expect(stage.$collapsed).toBe(false); + }); + }); + + describe('maxRounds',function() { + it('should return the maximum rounds of all stages',function() { + /* from stagesMock: + var stages = [ + { id: "practice", name: "Oefenrondes", rounds: 2, $rounds: [1, 2] }, + { id: "qualifying", name: "Voorrondes", rounds: 3, $rounds: [1, 2, 3] }, + { id: "quarter", name: "Kwart finales", rounds: 0, $rounds: [] }, + { id: "semi", name: "Halve finales", rounds: 0, $rounds: [] }, + { id: "final", name: "Finale", rounds: 1, $rounds: [1] }, + ]; + */ + expect($scope.maxRounds()).toBe(3); + }); + }); + + describe('emptyCols',function() { + it('should return an array with the number of empty columns for a stage',function() { + expect($scope.emptyCols(stagesMock.stages[0])).toEqual(Array(1)); + expect($scope.emptyCols(stagesMock.stages[1])).toEqual(Array()); + expect($scope.emptyCols(stagesMock.stages[2])).toEqual(Array(3)); + expect($scope.emptyCols(stagesMock.stages[3])).toEqual(Array(3)); + expect($scope.emptyCols(stagesMock.stages[4])).toEqual(Array(2)); + }); + }); + + describe('rebuildCSV',function() { it('should generate CSV data and filenames',function() { expect($scope.csvname).toEqual({}); expect($scope.csvdata).toEqual({}); @@ -71,5 +136,27 @@ describe('ranking', function() { '"1","456","""bar""","10","10","0","5"', ].join("\r\n"))); }); + it('should not skip empty values, but include as empty string',function() { + $scope.rebuildCSV({ + 'qualifying': [ + { team: { name: "foo", number: 123 }, highest: 10, scores: [0, 10, 5] }, + { team: { name: "\"bar\"", number: 456 }, highest: 10, scores: [10, 0, 5] } + ] + }); + expect($scope.csvdata["qualifying"]).toEqual("data:text/csv;charset=utf-8," + encodeURIComponent([ + '"Rank","Team Number","Team Name","Highest","Round 1","Round 2","Round 3"', + '"","123","foo","10","0","10","5"', + '"","456","""bar""","10","10","0","5"', + ].join("\r\n"))); + }); + }); + + describe('scoreboard watcher',function() { + it('should rebuild the csv when the scoreboard changes',function() { + $scope.rebuildCSV = jasmine.createSpy('rebuildCSV'); + $scope.scoreboard = 'foo'; + $scope.$digest(); + expect($scope.rebuildCSV).toHaveBeenCalledWith(scoresMock.scoreboard); + }); }); }); diff --git a/spec/views/scoresSpec.js b/spec/views/scoresSpec.js index 9367b12d..4eaaf2eb 100644 --- a/spec/views/scoresSpec.js +++ b/spec/views/scoresSpec.js @@ -4,11 +4,12 @@ describe('scores', function() { 'services/log': logMock }); - var $scope, controller, scoresMock, teamsMock; + var $scope, controller, scoresMock, teamsMock, stagesMock; beforeEach(function() { scoresMock = createScoresMock(); teamsMock = createTeamsMock(); + stagesMock = createStagesMock(); angular.mock.module(module.name); angular.mock.inject(function($controller, $rootScope) { $scope = $rootScope.$new(); diff --git a/src/js/views/ranking.js b/src/js/views/ranking.js index fb0069ca..4548265a 100644 --- a/src/js/views/ranking.js +++ b/src/js/views/ranking.js @@ -33,8 +33,8 @@ define('views/ranking',[ } else { icon = 'icon-sort-up'; } - } else if (stage.sort === null && col == $scope.sort) { - if (stage.rev === null && $scope.rev) { + } else if (stage.sort === undefined && col == $scope.sort) { + if (stage.rev === undefined && $scope.rev) { icon = 'icon-sort-down'; } else { icon = 'icon-sort-up'; @@ -51,12 +51,12 @@ define('views/ranking',[ $scope.maxRounds = function() { return $stages.stages.reduce(function(max,stage) { - //log(stage.name + ": " + stage.$rounds.length); - //log("maxRounds: " + max); return Math.max(max, stage.$rounds.length); },0); }; + //return an array with the number of empty columns to render for a stage + //max rounds minus stage rounds $scope.emptyCols = function(stage) { return new Array($scope.maxRounds() - stage.$rounds.length); }; From 67613518c8354f542f2da3b152449b9edc23d711 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 22:15:13 +0100 Subject: [PATCH 06/76] performance tweaks --- src/views/ranking.html | 2 +- src/views/scores.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/ranking.html b/src/views/ranking.html index 688f70ab..e98818c2 100644 --- a/src/views/ranking.html +++ b/src/views/ranking.html @@ -48,7 +48,7 @@

- + {{item.rank}} {{item.team.number}} {{item.team.name}} diff --git a/src/views/scores.html b/src/views/scores.html index 7a46a5ae..f5c912ed 100644 --- a/src/views/scores.html +++ b/src/views/scores.html @@ -15,7 +15,7 @@ Action - + {{score.index + 1}} From 4d0e350bf12c1e275bd267fd3b0134f7176a5bce Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 22:16:51 +0100 Subject: [PATCH 07/76] Updated cache manifest to reflect changes --- src/fllscoring.appcache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fllscoring.appcache b/src/fllscoring.appcache index 4bef9ceb..89395159 100644 --- a/src/fllscoring.appcache +++ b/src/fllscoring.appcache @@ -1,5 +1,5 @@ CACHE MANIFEST -#2014-12-12 2000 +#2014-12-20 2200 CACHE: index.html From 2d9f7c95efe6fbe5caea8cf1661f58d0a47b3dc5 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 22:27:04 +0100 Subject: [PATCH 08/76] Added number of entries in tables for #128 --- src/views/ranking.html | 125 +++++++++++++++++++++-------------------- src/views/scores.html | 2 + src/views/teams.html | 92 +++++++++++++++--------------- 3 files changed, 114 insertions(+), 105 deletions(-) diff --git a/src/views/ranking.html b/src/views/ranking.html index e98818c2..b877e6ca 100644 --- a/src/views/ranking.html +++ b/src/views/ranking.html @@ -1,64 +1,67 @@
- Export -

- - {{stage.name}} - - ({{scoreboard[stage.id].length}}) - -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- Rank - - - Team - - - Name - - - Highest - - - Score - - - Round {{round}} - -
{{item.rank}}{{item.team.number}}{{item.team.name}}{{item.highest}}{{score}}
+
+ Export +

+ + {{stage.name}} + + ({{scoreboard[stage.id].length}}) + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Rank + + + Team + + + Name + + + Highest + + + Score + + + Round {{round}} + +
{{item.rank}}{{item.team.number}}{{item.team.name}}{{item.highest}}{{score}}
+

Showing {{scoreboard[stage.id].length}} entries.

+
diff --git a/src/views/scores.html b/src/views/scores.html index f5c912ed..cbc368f3 100644 --- a/src/views/scores.html +++ b/src/views/scores.html @@ -3,6 +3,7 @@

+

Showing {{scores.length}} scores.

@@ -86,4 +87,5 @@
+

Showing {{scores.length}} scores.

diff --git a/src/views/teams.html b/src/views/teams.html index e61a9ad5..167d7e01 100644 --- a/src/views/teams.html +++ b/src/views/teams.html @@ -68,51 +68,54 @@
 
{{status}}

- - - - - - - - - - - - - +

Showing {{teams.length}} teams.

+
+
#NameCity (State)CountryAffiliationCoach 1Coach 2Judging GroupPit LocationTranslation
+ + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - -
#NameCity (State)CountryAffiliationCoach 1Coach 2Judging GroupPit LocationTranslation
{{team.number}}{{team.name}}{{team.cityState}}{{team.country}}{{team.affiliation}}{{team.coach1}}{{team.coach2}}{{team.judgingGroup}}{{team.pitLocation}}
{{team.number}}{{team.name}}{{team.cityState}}{{team.country}}{{team.affiliation}}{{team.coach1}}{{team.coach2}}{{team.judgingGroup}}{{team.pitLocation}}
- - - - -
+ + + + + + + + + + + + + + + + + + +
({{team.number}}) {{team.name}}, {{team.cityState}} @@ -159,4 +162,5 @@
 
+

Showing {{teams.length}} teams.

From abbd00578d6e400438b3573b689fef162640566f Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sat, 20 Dec 2014 23:00:07 +0100 Subject: [PATCH 09/76] Added tests for scores --- spec/mocks/scoresMock.js | 12 +++-- spec/views/rankingSpec.js | 4 +- spec/views/scoresSpec.js | 94 ++++++++++++++++++++++++++++++++++----- src/js/views/scores.js | 10 ++--- 4 files changed, 99 insertions(+), 21 deletions(-) diff --git a/spec/mocks/scoresMock.js b/spec/mocks/scoresMock.js index 4c471a38..60b3808d 100644 --- a/spec/mocks/scoresMock.js +++ b/spec/mocks/scoresMock.js @@ -1,12 +1,18 @@ -function createScoresMock() { +function createScoresMock($q) { return { scores: [{ - score: 1 + score: 1, + index: 0 },{ - score: 2 + score: 2, + index: 1 }], scoreboard: {}, remove: jasmine.createSpy('scoreRemoveSpy'), + load: jasmine.createSpy('scoreLoadSpy'), + pollSheets: jasmine.createSpy('scorePollSheetsSpy').andReturn($q.when()), + update: jasmine.createSpy('scoreUpdateSpy'), + _update: jasmine.createSpy('score_UpdateSpy'), save: jasmine.createSpy('scoreSaveSpy') }; } diff --git a/spec/views/rankingSpec.js b/spec/views/rankingSpec.js index 41f84a3b..4b9009e8 100644 --- a/spec/views/rankingSpec.js +++ b/spec/views/rankingSpec.js @@ -13,9 +13,9 @@ describe('ranking', function() { beforeEach(function() { angular.mock.module(module.name); - angular.mock.inject(function($controller, $rootScope) { + angular.mock.inject(function($controller, $rootScope,$q) { $scope = $rootScope.$new(); - scoresMock = createScoresMock(); + scoresMock = createScoresMock($q); stagesMock = createStagesMock(); controller = $controller('rankingCtrl', { '$scope': $scope, diff --git a/spec/views/scoresSpec.js b/spec/views/scoresSpec.js index 4eaaf2eb..4ddb6574 100644 --- a/spec/views/scoresSpec.js +++ b/spec/views/scoresSpec.js @@ -4,22 +4,25 @@ describe('scores', function() { 'services/log': logMock }); - var $scope, controller, scoresMock, teamsMock, stagesMock; + var $scope, controller, scoresMock, teamsMock, stagesMock,$window,$q; beforeEach(function() { - scoresMock = createScoresMock(); - teamsMock = createTeamsMock(); - stagesMock = createStagesMock(); angular.mock.module(module.name); - angular.mock.inject(function($controller, $rootScope) { + angular.mock.inject(function($controller, $rootScope,_$window_,_$q_) { $scope = $rootScope.$new(); + $window = _$window_; + $q = _$q_; + scoresMock = createScoresMock($q); + teamsMock = createTeamsMock(); + stagesMock = createStagesMock(); controller = $controller('scoresCtrl', { '$scope': $scope, '$scores': scoresMock, '$teams': teamsMock, - '$stages': stagesMock + '$stages': stagesMock, }); }); + $window.alert = jasmine.createSpy('alertSpy'); }); describe('initialization', function() { @@ -30,17 +33,86 @@ describe('scores', function() { }); }); - describe('editing scores',function() { + describe('doSort',function() { + it('should set toggle sort on an already sorted column',function() { + $scope.doSort('index'); + expect($scope.rev).toBe(false); + expect($scope.sort).toBe('index'); + $scope.doSort('index'); + expect($scope.rev).toBe(true); + expect($scope.sort).toBe('index'); + }); + + it('should the sort with rev false when no default given when a different column is sorted',function() { + $scope.doSort('foo'); + expect($scope.rev).toBe(false); + expect($scope.sort).toBe('foo'); + }); + + it('should the sort with rev to the given default when a different column is sorted',function() { + $scope.doSort('foo',true); + expect($scope.rev).toBe(true); + expect($scope.sort).toBe('foo'); + }); + }); + + describe('removeScore',function() { it('should remove a score',function() { $scope.removeScore(1); expect(scoresMock.remove).toHaveBeenCalledWith(1); expect(scoresMock.save).toHaveBeenCalledWith(); }); + }); + + describe('editScore',function() { + it('should edit a score',function() { + $scope.editScore(0); + expect($scope.scores[0].$editing).toBe(true); + }); + }); + + describe('finishEditScore',function() { + it('should call update and save',function() { + $scope.editScore(0); + $scope.finishEditScore(0); + expect(scoresMock.update).toHaveBeenCalledWith(0, {score: 1, index: 0, $editing: true}); + expect(scoresMock.save).toHaveBeenCalled(); + }); + it('should alert if an error is thrown from scores',function() { + scoresMock.update.andThrow('update error'); + $scope.editScore(0); + $scope.finishEditScore(0); + expect($window.alert).toHaveBeenCalledWith('Error updating score: update error'); + }); + }); + + describe('cancelEditScore',function() { + it('should call _update to reset the scores',function() { + $scope.editScore(0); + $scope.cancelEditScore(); + expect(scoresMock._update).toHaveBeenCalled(); + }); + }); + + describe('pollSheets',function() { + xit('should call pollSheets of scores',function() { + $scope.pollSheets(); + expect(scoresMock.pollSheets).toHaveBeenCalled(); + }); + + it('should alert on fail',function() { + scoresMock.pollSheets.andReturn($q.reject(new Error('foo'))); + $scope.pollSheets(); + expect(scoresMock.pollSheets).toHaveBeenCalled(); + $scope.$digest(); + expect($window.alert).toHaveBeenCalledWith('failed to poll sheets: Error: foo'); + }); + }); - xit('should edit a score',function() { - var newScore = {score:4}; - $scope.editScore(1,newScore); - expect($scope.scores[1]).toEqual(newScore); + describe('refresh',function() { + it('should call load of scores',function() { + $scope.refresh(); + expect(scoresMock.load).toHaveBeenCalled(); }); }); }); diff --git a/src/js/views/scores.js b/src/js/views/scores.js index 303a777c..a1c4bea7 100644 --- a/src/js/views/scores.js +++ b/src/js/views/scores.js @@ -6,8 +6,8 @@ define('views/scores',[ ],function(log) { var moduleName = 'scores'; return angular.module(moduleName,[]).controller(moduleName+'Ctrl',[ - '$scope', '$scores','$teams','$stages', - function($scope,$scores,$teams,$stages) { + '$scope', '$scores','$teams','$stages','$window', + function($scope,$scores,$teams,$stages,$window) { log('init scores ctrl'); $scope.sort = 'index'; @@ -17,7 +17,7 @@ define('views/scores',[ $scope.stages = $stages.stages; $scope.doSort = function(col, defaultSort) { - $scope.rev = (String($scope.sort) === String(col)) ? !$scope.rev : defaultSort; + $scope.rev = (String($scope.sort) === String(col)) ? !$scope.rev : !!defaultSort; $scope.sort = col; }; $scope.removeScore = function(index) { @@ -39,7 +39,7 @@ define('views/scores',[ $scores.update(score.index, score); $scores.save(); } catch(e) { - alert("Error updating score: " + e); + $window.alert("Error updating score: " + e); } }; @@ -50,7 +50,7 @@ define('views/scores',[ $scope.pollSheets = function() { return $scores.pollSheets().catch(function(err) { console.log("pollSheets() failed", err); - alert("failed to poll sheets: " + err); + $window.alert("failed to poll sheets: " + err); }); }; From cb0492bd38d745333c8333bf8c4e1318f7ac56ef Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 24 Dec 2014 22:31:56 +0100 Subject: [PATCH 10/76] pass $q to settingsMock for synchronized testing, updated tests Conflicts: spec/services/ng-challengeSpec.js src/js/services/ng-challenge.js --- spec/mocks/settingsMock.js | 6 +++--- spec/services/ng-challengeSpec.js | 20 +++++++++++++------- spec/views/scoresheetSpec.js | 5 +++-- spec/views/settingsSpec.js | 9 ++++++--- src/js/services/ng-challenge.js | 2 +- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/spec/mocks/settingsMock.js b/spec/mocks/settingsMock.js index 82252782..a38458ca 100644 --- a/spec/mocks/settingsMock.js +++ b/spec/mocks/settingsMock.js @@ -1,7 +1,7 @@ -function createSettingsMock(settings) { +function createSettingsMock($q, settings) { return { settings: settings, - init: jasmine.createSpy('settingsInitSpy').andReturn(Q.when(settings)), - save: jasmine.createSpy('settingsSaveSpy').andReturn(Q.when()) + init: jasmine.createSpy('settingsInitSpy').andReturn($q.when(settings)), + save: jasmine.createSpy('settingsSaveSpy').andReturn($q.when()) }; } diff --git a/spec/services/ng-challengeSpec.js b/spec/services/ng-challengeSpec.js index 6da87bbf..f461f482 100644 --- a/spec/services/ng-challengeSpec.js +++ b/spec/services/ng-challengeSpec.js @@ -4,21 +4,26 @@ describe('ng-challenge',function() { var dummyChallenge = {foo:'bar'}; + var fsMock, settingsMock,$q,$rootScope; + fsMock = createFsMock({'foo': JSON.stringify(dummyChallenge)}); + var module = factory('services/ng-challenge',{ 'services/ng-services': ngServices, - 'services/fs': createFsMock({'foo': JSON.stringify(dummyChallenge)}) + 'services/fs': fsMock }); - var settingsMock; - beforeEach(function() { - settingsMock = createSettingsMock({}); + angular.mock.module(module.name); angular.mock.module(function($provide) { - $provide.value('$settings', settingsMock); + $provide.service('$settings', function($q) { + settingsMock = createSettingsMock($q, {}); + return settingsMock; + }); }); - angular.mock.module(module.name); - angular.mock.inject(function($challenge,$q) { + angular.mock.inject(function($challenge,_$q_,_$rootScope_) { challenge = $challenge; + $q = _$q_; + $rootScope = _$rootScope_; }); }); @@ -36,6 +41,7 @@ describe('ng-challenge',function() { expect(challenge.init).toHaveBeenCalledWith(dummyChallenge); done(); }); + $rootScope.$digest(); }); }); diff --git a/spec/views/scoresheetSpec.js b/spec/views/scoresheetSpec.js index 5a45c85c..ac5aefc0 100644 --- a/spec/views/scoresheetSpec.js +++ b/spec/views/scoresheetSpec.js @@ -11,11 +11,12 @@ describe('scoresheet',function() { }; var dummyStage = { id: "qualifying", name: "Voorrondes", rounds: 3 }; var fsMock = createFsMock({"settings.json": []}); - var settingsMock = createSettingsMock({}); + var settingsMock; beforeEach(function() { angular.mock.module(module.name); - angular.mock.inject(function($controller,$rootScope) { + angular.mock.inject(function($controller,$rootScope,$q) { + settingsMock = createSettingsMock($q,{}); $scope = $rootScope.$new(); controller = $controller('scoresheetCtrl', { '$scope': $scope, diff --git a/spec/views/settingsSpec.js b/spec/views/settingsSpec.js index 0829a2d8..33c1bbdf 100644 --- a/spec/views/settingsSpec.js +++ b/spec/views/settingsSpec.js @@ -6,12 +6,13 @@ describe('settings', function() { var $scope, controller; - var settingsMock = createSettingsMock({}); + var settingsMock; beforeEach(function() { angular.mock.module(module.name); - angular.mock.inject(function($controller, $rootScope) { + angular.mock.inject(function($controller, $rootScope, $q) { $scope = $rootScope.$new(); + settingsMock = createSettingsMock($q, {}); controller = $controller('settingsCtrl', { '$scope': $scope, '$stages': {}, @@ -22,7 +23,9 @@ describe('settings', function() { describe('initialization', function() { it('should initialize', function() { - //TODO: check state after reading + //let $settings init + $scope.$digest(); + expect($scope.settings).toEqual({}); }); }); diff --git a/src/js/services/ng-challenge.js b/src/js/services/ng-challenge.js index b2826edf..d9b7686f 100644 --- a/src/js/services/ng-challenge.js +++ b/src/js/services/ng-challenge.js @@ -929,7 +929,7 @@ define('services/ng-challenge',[ }).then(function(response) { return self.init(eval('('+response.data+')')); }); - }).fail(function() { + }).catch(function() { log('error getting field'); }); }, From e9fcea96fbf373a3f83a4f3e8f09c4241f3d69c6 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 24 Dec 2014 17:53:49 +0100 Subject: [PATCH 11/76] tests for ng-settings --- spec/services/ng-settingsSpec.js | 69 ++++++++++++++++++++++++++++++++ src/js/services/ng-settings.js | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 spec/services/ng-settingsSpec.js diff --git a/spec/services/ng-settingsSpec.js b/spec/services/ng-settingsSpec.js new file mode 100644 index 00000000..aeb83963 --- /dev/null +++ b/spec/services/ng-settingsSpec.js @@ -0,0 +1,69 @@ +describe('ng-settings',function() { + var ngServices = factory('services/ng-services'); + var module = factory('services/ng-settings',{ + 'services/ng-services': ngServices, + 'services/log': logMock + }); + + var $settings, $httpBackend, $q, $rootScope, settingsMock, fsMock; + + beforeEach(function() { + angular.mock.module(module.name); + angular.mock.module(function($provide) { + var s = $provide.service('$fs',function($q) { + fsMock = createFsMock({ + 'settings.json': {} + }); + return fsMock; + }); + }); + angular.mock.inject(function(_$settings_, _$q_, _$httpBackend_,_$rootScope_) { + $settings = _$settings_; + $httpBackend = _$httpBackend_; + $q = _$q_; + $rootScope = _$rootScope_; + }); + }); + + + + describe('init',function() { + it('not be inited to begin with and return a promise',function() { + var p = $settings.init(); + expect(typeof p.then).toBe('function'); + }); + }); + + describe('load',function() { + it('should set local settings on success load',function(done) { + $settings.load().then(function(res) { + expect(res).toEqual({}); + expect($settings.settings).toEqual({}); + done(); + }); + }); + it('should write an empty settings file if the file is not there',function() { + fsMock.read.andReturn($q.reject('no file')); + fsMock.write.andReturn($q.when()); + $settings.load(); + $rootScope.$digest(); + expect(fsMock.write).toHaveBeenCalledWith('settings.json',{}); + expect($settings.settings).toEqual({}); + }); + it('should just create local settings if no file could be created',function() { + fsMock.read.andReturn($q.reject('no file')); + fsMock.write.andReturn($q.reject('write error')); + $settings.load(); + $rootScope.$digest(); + expect($settings.settings).toEqual({}); + }); + }); + + describe('save',function() { + it('should write the local settings to the settings.json file',function() { + $settings.settings = 'foo'; + $settings.save(); + expect(fsMock.write).toHaveBeenCalledWith('settings.json','foo'); + }); + }); +}); diff --git a/src/js/services/ng-settings.js b/src/js/services/ng-settings.js index 94fc7e77..84dc36d8 100644 --- a/src/js/services/ng-settings.js +++ b/src/js/services/ng-settings.js @@ -46,7 +46,7 @@ define('services/ng-settings',[ self.settings = {}; return self.settings; }); - }).catch(function() { + }).catch(function(err) { //return ephemeral settings log('unable to create settings file, giving up', err); self.settings = {}; From 01f432fea3e5a66eca52b2eeb004717f5ca9ac45 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 24 Dec 2014 18:21:24 +0100 Subject: [PATCH 12/76] updated xhrSpec --- spec/services/fs-xhrSpec.js | 98 ++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/spec/services/fs-xhrSpec.js b/spec/services/fs-xhrSpec.js index 09c55bee..efd58865 100644 --- a/spec/services/fs-xhrSpec.js +++ b/spec/services/fs-xhrSpec.js @@ -1,37 +1,25 @@ describe('fs-xhr',function() { - var fs = factory('services/fs-xhr',{ - 'q':Q - }); - - //mock xhr get - fs._get = function(url) { + function createJQPromise(success) { return { - done: function(cb) { - cb(url); - return { - fail: function(cb) { - //nothing - } - }; + done: function() { + var p = Q.when(success); + return p.then.apply(p,arguments); } }; - }; + } - //mock xhr post - fs._post = function(url,data) { - return { - done: function(cb) { - cb(url); - return { - fail: function(cb) { - //nothing - } - }; - } - }; + var fakeJQuery = { + get: jasmine.createSpy('jqget').andReturn(createJQPromise('get')), + post: jasmine.createSpy('jqpost').andReturn(createJQPromise('post')), + ajax: jasmine.createSpy('jqajax').andReturn(createJQPromise('ajax')) }; + var fs = factory('services/fs-xhr',{ + 'q':Q, + 'jquery': fakeJQuery + }); + describe('fs signature',function() { it('should have a read method',function() { expect(fs.read).not.toBeUndefined(); @@ -45,26 +33,56 @@ describe('fs-xhr',function() { }); describe('reading',function() { - it('should read a test file',function(done) { - fs.read('foo.txt').then(function(data) { - expect(data).toBe('/fs/foo.txt'); - }).fail(function(data) { - console.log('fail',data); - }).then(function() { - done(); + it('should read a test file',function() { + return fs.read('foo.txt').then(function(data) { + expect(data).toBe('get'); + expect(fakeJQuery.get).toHaveBeenCalledWith('/fs/foo.txt'); + }); + }); + it('should fail on xhr exception',function() { + fakeJQuery.get.andReturn(createJQPromise(Q.reject(new Error('foo')))); + return fs.read('foo.txt').catch(function(err) { + expect(fakeJQuery.get).toHaveBeenCalledWith('/fs/foo.txt'); + expect(err.message).toBe('foo'); }); }); }); describe('writing',function() { - it('should write a test file',function(done) { - fs.write('foo.txt').then(function(data) { - expect(data).toBe('/fs/foo.txt'); - }).fail(function(data) { - console.log('fail',data); - }).then(function() { - done(); + it('should write a test file',function() { + return fs.write('foo.txt','bar').then(function(data) { + expect(fakeJQuery.post).toHaveBeenCalledWith('/fs/foo.txt','bar'); + expect(data).toBe('post'); + }); + }); + it('should fail on xhr exception',function() { + fakeJQuery.post.andReturn(createJQPromise(Q.reject(new Error('foo')))); + return fs.write('foo.txt','bar').catch(function(err) { + expect(fakeJQuery.post).toHaveBeenCalledWith('/fs/foo.txt','bar'); + expect(err.message).toBe('foo'); }); }); }); + + describe('removing',function() { + it('should remove a test file',function() { + return fs.remove('foo.txt').then(function(data) { + expect(fakeJQuery.ajax).toHaveBeenCalledWith('/fs/foo.txt',{ + type: 'DELETE' + }); + expect(data).toBe('ajax'); + }); + }); + it('should fail on xhr exception',function() { + fakeJQuery.ajax.andReturn(createJQPromise(Q.reject(new Error('foo')))); + return fs.remove('foo.txt','bar').catch(function(err) { + expect(fakeJQuery.ajax).toHaveBeenCalledWith('/fs/foo.txt',{ + type: 'DELETE' + }); + expect(err.message).toBe('foo'); + }); + }); + }); + + }); From 4bec4cb685a8d5dfa3644f4b6bae6648209d8b39 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 24 Dec 2014 21:59:04 +0100 Subject: [PATCH 13/76] Added tests for fs-pg add fs-pg spec --- spec/mocks/logMock.js | 4 +- spec/services/fs-pgSpec.js | 129 +++++++++++++++++++++++++++++++++++++ src/js/services/fs-pg.js | 12 ++-- 3 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 spec/services/fs-pgSpec.js diff --git a/spec/mocks/logMock.js b/spec/mocks/logMock.js index 55f8c150..9f69cde8 100644 --- a/spec/mocks/logMock.js +++ b/spec/mocks/logMock.js @@ -1,2 +1,2 @@ -var logMock = function() {}; -logMock.get = function() {}; \ No newline at end of file +var logMock = jasmine.createSpy('log'); +logMock.get = jasmine.createSpy('log.get'); diff --git a/spec/services/fs-pgSpec.js b/spec/services/fs-pgSpec.js new file mode 100644 index 00000000..8e6ad65b --- /dev/null +++ b/spec/services/fs-pgSpec.js @@ -0,0 +1,129 @@ +describe('fs-pg',function() { + + + + var fs = factory('services/fs-pg',{ + 'q':Q, + 'services/log': logMock + }); + + var FileEntry, DirectoryEntry, FileSystem, FileReader, FileWriter; + + beforeEach(function() { + //fake local filesystem as provided by phonegap + //TODO: maybe extract phonegap fs mock? + window.LocalFileSystem = { + PERSISTENT: 0 + }; + FileReader = function() { + this.readAsText = function() { + this.onloadend({ + target: { + result: 'foo' + } + }); + }; + FileReader.instance = this; + }; + FileWriter = function() { + this.write = jasmine.createSpy('FileWriter.write').andCallFake(function() { + this.onwriteend({}); + }); + FileWriter.instance = this; + }; + FileEntry = function() { + this.file = function(success,err) { + success(); + }; + this.createWriter = function(success,err) { + success(new FileWriter()); + }; + this.remove = jasmine.createSpy('FileEntryRemove'); + FileEntry.instance = this; + }; + + DirectoryEntry = function() { + }; + DirectoryEntry.prototype.getDirectory = function(path,options,success,err) { + success(new DirectoryEntry()); + }; + DirectoryEntry.prototype.getFile = function(name,options,success,err) { + success(new FileEntry()); + }; + FileSystem = function() { + this.root = new DirectoryEntry(); + }; + window.FileReader = FileReader; + window.requestFileSystem = jasmine.createSpy('fs').andCallFake(function(a,b,success,err) { + success(new FileSystem()); + }); + }); + + describe('fs signature',function() { + it('should have a read method',function() { + expect(fs.read).not.toBeUndefined(); + }); + it('should have a write method',function() { + expect(fs.write).not.toBeUndefined(); + }); + it('should have a remove method',function() { + expect(fs.remove).not.toBeUndefined(); + }); + }); + + describe('reading',function() { + it('should read a test file',function() { + return fs.read('foo.txt').then(function(data) { + expect(data).toBe('foo'); + }); + }); + it('should read a deeper file',function() { + return fs.read('foo/bar.txt').then(function(data) { + expect(data).toBe('foo'); + }); + }); + it('should fail when there is an error in filesystem',function() { + window.requestFileSystem = jasmine.createSpy('fs').andCallFake(function(a,b,success,err) { + err('no fs'); + }); + return fs.read('foo.txt').catch(function(err) { + expect(logMock).toHaveBeenCalledWith('fail getting file system '); + expect(err).toBe('no fs'); + }); + }); + it('should fail when there is an error in getting the directory',function() { + DirectoryEntry.prototype.getDirectory = function(path,options,success,err) { + err('no dir'); + }; + return fs.read('foo.txt').catch(function(err) { + expect(logMock).toHaveBeenCalledWith('fail getting directory fllscoring'); + expect(err).toBe('no dir'); + }); + }); + }); + + describe('writing',function() { + it('should write a test file',function() { + return fs.write('foo.txt','bar').then(function(data) { + expect(FileWriter.instance.write).toHaveBeenCalledWith('bar'); + }); + }); + it('should fail when there is an error on writing',function() { + window.requestFileSystem = jasmine.createSpy('fs').andCallFake(function(a,b,success,err) { + err('no fs'); + }); + return fs.write('foo.txt','bar').catch(function(err) { + expect(logMock).toHaveBeenCalledWith('fail getting file system '); + expect(err).toBe('no fs'); + }); + }); + }); + + describe('removing',function() { + it('should remove a test file',function() { + return fs.remove('foo.txt').then(function(data) { + expect(FileEntry.instance.remove).toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/src/js/services/fs-pg.js b/src/js/services/fs-pg.js index ee1939e6..e5b0d6c2 100644 --- a/src/js/services/fs-pg.js +++ b/src/js/services/fs-pg.js @@ -29,15 +29,17 @@ define('services/fs-pg',['q','services/log'],function(Q,log) { return getSequence(dir,parts); } return dir; - }).fail(function() { + }).fail(function(err) { log('fail getting directory '+name); + throw err; }); } return getFS().then(function(fs) { return getSequence(fs.root,parts); - }).fail(function() { + }).fail(function(err) { log('fail getting file system '); + throw err; }); } @@ -55,8 +57,9 @@ define('services/fs-pg',['q','services/log'],function(Q,log) { var def = Q.defer(); dir.getFile(fileName,options||null,def.resolve,def.reject); return def.promise; - }).fail(function() { + }).fail(function(err) { log('fail getting path '+dirName); + throw err; }); } @@ -73,8 +76,9 @@ define('services/fs-pg',['q','services/log'],function(Q,log) { var def = Q.defer(); fileEntry.createWriter(def.resolve,def.reject); return def.promise; - }).fail(function() { + }).fail(function(err) { log('fail getting writer '+path); + throw err; }); } From daf1cacdb6615fba323eeba91d61f31d0dc349ef Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 24 Dec 2014 22:00:06 +0100 Subject: [PATCH 14/76] Call done() on promise chain when a promise is returned from jasmine spec runner --- spec/helpers/asyncJasmine.js | 6 +- spec/services/asyncSpec.js | 136 ++++++++++++++++++----------------- 2 files changed, 74 insertions(+), 68 deletions(-) diff --git a/spec/helpers/asyncJasmine.js b/spec/helpers/asyncJasmine.js index 66cca82d..bb1b63e5 100644 --- a/spec/helpers/asyncJasmine.js +++ b/spec/helpers/asyncJasmine.js @@ -63,7 +63,11 @@ // Runner returned a promise. // Wait for it to be resolved or rejected. async = true; - result.then(function() { done(); }, done); + var lastPromise = result.then(function() { done(); }, done); + //thow any other exceptions (if Q) + if (lastPromise.done) { + lastPromise.done(); + } } } diff --git a/spec/services/asyncSpec.js b/spec/services/asyncSpec.js index 49e32cae..84324634 100644 --- a/spec/services/asyncSpec.js +++ b/spec/services/asyncSpec.js @@ -1,81 +1,83 @@ -"use strict"; +describe('async',function() { + "use strict"; -describe('async beforeEach()',function() { - var beforeEachReady = false; - var itReady = false; + describe('async beforeEach()',function() { + var beforeEachReady = false; + var itReady = false; - beforeEach(function(done) { - function ready() { - beforeEachReady = true; - done(); - } - setTimeout(ready, 0); - }); + beforeEach(function(done) { + function ready() { + beforeEachReady = true; + done(); + } + setTimeout(ready, 0); + }); - it('should not call it() until beforeEach() is ready', function(done) { - expect(beforeEachReady).toEqual(true); - function ready() { - itReady = true; - done(); - } - setTimeout(ready, 0); - }); + it('should not call it() until beforeEach() is ready', function(done) { + expect(beforeEachReady).toEqual(true); + function ready() { + itReady = true; + done(); + } + setTimeout(ready, 0); + }); - it('should wait before previous it() is ready', function() { - expect(itReady).toEqual(true); - }); + it('should wait before previous it() is ready', function() { + expect(itReady).toEqual(true); + }); -}); + }); -describe('promises', function() { - var $q; - var beforeEachReady = false; - var itReady = false; + describe('promises', function() { + var $q; + var beforeEachReady = false; + var itReady = false; - beforeEach(function() { - angular.mock.inject(["$q", function(_$q_) { - $q = _$q_; - }]); - }); + beforeEach(function() { + angular.mock.inject(["$q", function(_$q_) { + $q = _$q_; + }]); + }); - beforeEach(function() { - var d = $q.defer(); - function ready() { - beforeEachReady = true; - d.resolve(); - } - setTimeout(ready, 0); - return d.promise; - }); + beforeEach(function() { + var d = $q.defer(); + function ready() { + beforeEachReady = true; + d.resolve(); + } + setTimeout(ready, 0); + return d.promise; + }); - it('should wait for returned promises from beforeEach() to be resolved', function() { - expect(beforeEachReady).toEqual(true); - var d = $q.defer(); - function ready() { - itReady = true; - d.resolve(); - } - setTimeout(ready, 0); - return d.promise; - }); + it('should wait for returned promises from beforeEach() to be resolved', function() { + expect(beforeEachReady).toEqual(true); + var d = $q.defer(); + function ready() { + itReady = true; + d.resolve(); + } + setTimeout(ready, 0); + return d.promise; + }); - it('should wait for returned promises from it() to be resolved', function() { - expect(itReady).toEqual(true); - }); + it('should wait for returned promises from it() to be resolved', function() { + expect(itReady).toEqual(true); + }); - it('should resolve promises asynchronously and not fail with a timeout', function(done) { - var d = $q.defer(); - var p = d.promise; - var resolved = false; - var thenCalled = false; - p.then(function() { - expect(resolved).toEqual(true); - thenCalled = true; - done(); + it('should resolve promises asynchronously and not fail with a timeout', function(done) { + var d = $q.defer(); + var p = d.promise; + var resolved = false; + var thenCalled = false; + p.then(function() { + expect(resolved).toEqual(true); + thenCalled = true; + done(); + }); + expect(thenCalled).toEqual(false); + d.resolve(); + resolved = true; + expect(thenCalled).toEqual(false); }); - expect(thenCalled).toEqual(false); - d.resolve(); - resolved = true; - expect(thenCalled).toEqual(false); }); }); From 0620dc9aa829e07b52e7954fd63dd6cf4094d397 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 13:17:21 +0100 Subject: [PATCH 15/76] remove hardcoded field def, it is not used anymore --- src/js/services/ng-challenge.js | 888 -------------------------------- 1 file changed, 888 deletions(-) diff --git a/src/js/services/ng-challenge.js b/src/js/services/ng-challenge.js index d9b7686f..ddb5c550 100644 --- a/src/js/services/ng-challenge.js +++ b/src/js/services/ng-challenge.js @@ -10,894 +10,6 @@ define('services/ng-challenge',[ var mission; var fallBackChallenge = 'challenge/2014_nl_NL-no-enum'; - var field = { - "title": "World Class", - "missions": [{ - "title": "Reverse Engineering", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • Jullie mand is in de basis.
  • Het model raakt de witte cirkel rond het projectonderwijs-model aan.
  • Jullie hebben een model gemaakt ‘identiek’ aan het model dat het andere team in jullie mand heeft gedaan. De verbindingen tussen de elementen moeten hetzelfde zijn, maar elementen mogen wel ‘gedraaid’ zitten.
  • Het model is in de basis.
Vereiste methode en beperkingen:
  • Geen.
", - "objectives": [{ - "id": "basket", - "title": "Mand in de basis", - "type": "yesno" - }, { - "id": "identical", - "title": "Jullie model ligt in de basis en is ‘identiek’", - "type": "yesno" - }], - "score": [function(basket, identical) { - if (basket === 'no' && identical === 'no') { - return 0 - } - if (basket === 'no' && identical === 'yes') { - return 0 - } - if (basket === 'yes' && identical === 'no') { - return 30 - } - if (basket === 'yes' && identical === 'yes') { - return 45 - } - }] - }, { - "title": "Deuren openen", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • De deur moet ver genoeg geopend zijn zodat de scheidsrechter dit kan zien.
Vereiste methode en beperkingen:
  • De hendel moet omlaag gedrukt zijn.
", - "objectives": [{ - "id": "dooropen", - "title": "Deur geopend door de hendel omlaag te drukken", - "type": "yesno" - }], - "score": [function(dooropen) { - if (dooropen === 'no') { - return 0 - } - if (dooropen === 'yes') { - return 15 - } - }] - }, { - "title": "Projectonderwijs", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • De lussen (welke symbool staan voor kennis en vaardigheden) hangen aan de weegschaal zoals getoond.
Vereiste methode en beperkingen:
  • Geen.
", - "objectives": [{ - "id": "loops", - "title": "Lussen aan de weegschaal", - "options": [{ - "value": "0", - "title": "0" - }, { - "value": "1", - "title": "1" - }, { - "value": "2", - "title": "2" - }, { - "value": "3", - "title": "3" - }, { - "value": "4", - "title": "4" - }, { - "value": "5", - "title": "5" - }, { - "value": "6", - "title": "6" - }, { - "value": "7", - "title": "7" - }, { - "value": "8", - "title": "8" - }], - "type": "enum" - }], - "score": [function(loops) { - if (loops === '0') { - return 0 - } - if (loops === '1') { - return 20 - } - if (loops === '2') { - return 30 - } - if (loops === '3') { - return 40 - } - if (loops === '4') { - return 50 - } - if (loops === '5') { - return 60 - } - if (loops === '6') { - return 70 - } - if (loops === '7') { - return 80 - } - if (loops === '8') { - return 90 - } - }] - }, { - "title": "Stagelopen", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • De LEGO-poppetjes zijn beiden verbonden (op een manier naar keuze) aan een model dat jullie ontwerpen en meenemen. Dit model stelt een vaardigheid, prestatie, carrière of hobby voor dat een speciale betekenis voor jullie team heeft.
  • Het model raakt de witte cirkel rond het projectonderwijs-model aan.
  • Het model is niet in de basis.
  • Het vastmaken van missiemodellen is normaal niet toegestaan vanwege regel 39.4, deze missie is daar een uitzondering op.
  • Het eigen model mag simpel, of complex zijn, het mag primitief of realistisch zijn, de keuze is aan jullie. De keuze wat voor model jullie bouwen, heeft geen invloed op de score.
Vereiste methode en beperkingen:
  • Geen.
", - "objectives": [{ - "id": "modelshown", - "title": "Model getoond aan de scheidsrechter", - "type": "yesno" - }, { - "id": "touchingcicrle", - "title": "Raakt de cirkel, niet in de basis en poppetjes verbonden", - "type": "yesno" - }], - "score": [function(modelshown, touchingcicrle) { - if (modelshown === 'no' && touchingcicrle === 'no') { - return 0 - } - if (modelshown === 'no' && touchingcicrle === 'yes') { - return new Error("Model moet getoond zijn voordat het de cirkel kan aanraken") - } - if (modelshown === 'yes' && touchingcicrle === 'no') { - return 20 - } - if (modelshown === 'yes' && touchingcicrle === 'yes') { - return 35 - } - }] - }, { - "title": "Zoekmachine", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • Het kleurenwiel heeft minimaal een keer gedraaid.
  • Als één kleur verschijnt in het witte frame, dan raakt de lus van de zichtbare kleur het model niet meer aan.
  • Als twee kleuren verschijnen in het witte venster, dan is de lus van de kleur die niet zichtbaar is in het venster, de lus die het model niet meer raakt.
  • Beide lussen die niet verwijderd dienen te worden raken via ‘hun’ gaten het model aan.
Vereiste methode en beperkingen:
  • Alleen de beweging van de schuif heeft het kleurenwiel in beweging gebracht.
", - "objectives": [{ - "id": "wheelspin", - "title": "Alleen de schuif heeft het wiel 1+ keer rondgedraaid", - "type": "yesno" - }, { - "id": "searchloop", - "title": "Alleen de juiste lus is verwijderd", - "type": "yesno" - }], - "score": [function(wheelspin, searchloop) { - if (wheelspin === 'no' && searchloop === 'no') { - return 0 - } - if (wheelspin === 'no' && searchloop === 'yes') { - return 0 - } - if (wheelspin === 'yes' && searchloop === 'no') { - return 15 - } - if (wheelspin === 'yes' && searchloop === 'yes') { - return 60 - } - }] - }, { - "title": "Sport", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • De bal raakt de mat in het doel.
Vereiste methode en beperkingen:
  • Alle onderdelen die met het schot te maken hebben waren volledig ten noordoosten van de ‘schietlijn’ op het moment dat de bal werd losgelaten richting het doel.
", - "objectives": [{ - "id": "ballshot", - "title": "Schot genomen vanuit positie Noord-Oost van de lijn", - "type": "yesno" - }, { - "id": "ballscored", - "title": "Bal raakt de mat in het doel aan het eind van de wedstrijd", - "type": "yesno" - }], - "score": [function(ballshot, ballscored) { - if (ballshot === 'no' && ballscored === 'no') { - return 0 - } - if (ballshot === 'no' && ballscored === 'yes') { - return 0 - } - if (ballshot === 'yes' && ballscored === 'no') { - return 30 - } - if (ballshot === 'yes' && ballscored === 'yes') { - return 60 - } - }] - }, { - "title": "Robotwedstrijden", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • Het blauw-geel-rode robotelement (model) is geïnstalleerd in de robotarm zoals zichtbaar op de afbeelding.
  • De lus raakt niet langer de robotarm aan.
Vereiste methode en beperkingen:
  • Geen strategisch object raakt de robotarm aan.
  • De lus werd alleen door het gebruik van de zwarte schuif losgemaakt.
", - "objectives": [{ - "id": "roboticsinsert", - "title": "Alleen het robotelement is geïnstalleerd in de robotarm", - "type": "yesno" - }, { - "id": "competitionloop", - "title": "Lus raakt de robotarm niet aan", - "type": "yesno" - }], - "score": [function(roboticsinsert, competitionloop) { - if (roboticsinsert === 'no' && competitionloop === 'no') { - return 0 - } - if (roboticsinsert === 'no' && competitionloop === 'yes') { - return 0 - } - if (roboticsinsert === 'yes' && competitionloop === 'no') { - return 25 - } - if (roboticsinsert === 'yes' && competitionloop === 'yes') { - return 55 - } - }] - }, { - "title": "Gebruik de juiste zintuigen en leerstijlen", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • De lus raakt het zintuigen model niet meer aan.
Vereiste methode en beperkingen:
  • De lus werd alleen door het gebruik van de schuif losgemaakt.
", - "objectives": [{ - "id": "sensesloop", - "title": "Lus raakt het model niet aan", - "type": "yesno" - }], - "score": [function(sensesloop) { - if (sensesloop === 'no') { - return 0 - } - if (sensesloop === 'yes') { - return 40 - } - }] - }, { - "title": "Leren/communiceren op afstand", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • Geen.
Vereiste methode en beperkingen:
  • De scheidsrechter heeft gezien dat de schuif door de robot westwaarts is verplaatst.
", - "objectives": [{ - "id": "pullslider", - "title": "Scheids zag de robot de schuif verplaatsen", - "type": "yesno" - }], - "score": [function(pullslider) { - if (pullslider === 'no') { - return 0 - } - if (pullslider === 'yes') { - return 40 - } - }] - }, { - "title": "Outside the Box denken", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • Het ‘idee-model’ raakt niet langer het ‘doos-model’ aan.
  • Als het ‘idee-model’ het ‘doos-model’ niet meer aanraakt, is de afbeelding van de gloeilamp van bovenaf zichtbaar.
Vereiste methode en beperkingen:
  • Het ‘doos-model’ is nooit in de basis geweest.
", - "objectives": [{ - "id": "bulbup", - "title": "Idee-model raakt de doos niet, Doos niet in basis geweest, Lamp is naar boven gericht", - "type": "yesno" - }, { - "id": "bulbdown", - "title": "Idee-model raakt de doos niet, Doos niet in basis geweest, Lamp is naar beneden gericht", - "type": "yesno" - }], - "score": [function(bulbup, bulbdown) { - if (bulbup === 'no' && bulbdown === 'no') { - return 0 - } - if (bulbup === 'no' && bulbdown === 'yes') { - return 25 - } - if (bulbup === 'yes' && bulbdown === 'no') { - return 40 - } - if (bulbup === 'yes' && bulbdown === 'yes') { - return new Error("De lamp kan niet tegelijk naar boven en beneden gericht zijn") - } - }] - }, { - "title": "Gemeenschappelijk leren", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • De ‘kennis & vaardigheden lus’ raakt het gemeenschapsmodel niet meer aan.
Vereiste methode en beperkingen:
  • Geen.
", - "objectives": [{ - "id": "communityloop", - "title": "Lus raakt het model niet aan", - "type": "yesno" - }], - "score": [function(communityloop) { - if (communityloop === 'no') { - return 0 - } - if (communityloop === 'yes') { - return 25 - } - }] - }, { - "title": "Cloud toegang", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • De SD-kaart staat omhoog.
Vereiste methode en beperkingen:
  • De juiste “key” is in de Cloud geplaatst.
", - "objectives": [{ - "id": "sdcardup", - "title": "SD card staat omhoog omdat de juiste \"key\" is ingebracht", - "type": "yesno" - }], - "score": [function(sdcardup) { - if (sdcardup === 'no') { - return 0 - } - if (sdcardup === 'yes') { - return 30 - } - }] - }, { - "title": "Betrokkenheid", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • Het gele gedeelte is naar het zuiden verplaatst.
  • Het rad is duidelijk met de klok mee gedraaid ten opzichte van de start positie. Zie het overzicht voor de score.
Vereiste methode en beperkingen:
  • De wijzer mag alleen verplaatst worden doordat de robot aan het rad te draait.
  • De robot mag het rad maar een keer 180⁰ draaien, per keer dat de basis wordt verlaten. De scheidsrechter zal extra draaiingen ongedaan maken
", - "objectives": [{ - "id": "yellow_moved", - "title": "Gele gedeelte is naar het zuiden verplaatst", - "type": "yesno" - }, { - "id": "dial_major_color", - "title": "Aangewezen kleur", - "options": [{ - "value": "na", - "title": "NVT" - }, { - "value": "red10", - "title": "Rood 10%" - }, { - "value": "orange16", - "title": "Oranje 16%" - }, { - "value": "green22", - "title": "Groen 22%" - }, { - "value": "blue28", - "title": "Blauw 28%" - }, { - "value": "red34", - "title": "Rood 34%" - }, { - "value": "blue40", - "title": "Blauw 40%" - }, { - "value": "green46", - "title": "Groen 46%" - }, { - "value": "orange52", - "title": "Oranje 52%" - }, { - "value": "red58", - "title": "Rood 58%" - }], - "type": "enum" - }, { - "id": "ticks_past_major", - "title": "Klikken voorbij de kleur", - "options": [{ - "value": "na", - "title": "NVT" - }, { - "value": "0", - "title": "0" - }, { - "value": "1", - "title": "1" - }, { - "value": "2", - "title": "2" - }, { - "value": "3", - "title": "3" - }, { - "value": "4", - "title": "4" - }, { - "value": "5", - "title": "5" - }], - "type": "enum" - }], - "score": [function(yellow_moved) { - if (yellow_moved === 'no') { - return 0 - } - if (yellow_moved === 'yes') { - return 20 - } - }, function(yellow_moved, dial_major_color, ticks_past_major) { - if (yellow_moved === 'no' && dial_major_color === 'na' && ticks_past_major === 'na') { - return 0 - } - if (yellow_moved === 'no' && dial_major_color === 'red10' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'orange16' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'green22' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'blue28' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red34' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'blue40' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'green46' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'orange52' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red58' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'na' && ticks_past_major === '0') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red10' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange16' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green22' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue28' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red34' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue40' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green46' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange52' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red58' && ticks_past_major === '0') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'na' && ticks_past_major === '1') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red10' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange16' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green22' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue28' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red34' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue40' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green46' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange52' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red58' && ticks_past_major === '1') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'na' && ticks_past_major === '2') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red10' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange16' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green22' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue28' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red34' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue40' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green46' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange52' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red58' && ticks_past_major === '2') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'na' && ticks_past_major === '3') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red10' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange16' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green22' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue28' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red34' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue40' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green46' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange52' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red58' && ticks_past_major === '3') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'na' && ticks_past_major === '4') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red10' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange16' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green22' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue28' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red34' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue40' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green46' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange52' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red58' && ticks_past_major === '4') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'na' && ticks_past_major === '5') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'no' && dial_major_color === 'red10' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange16' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green22' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue28' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red34' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'blue40' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'green46' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'orange52' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'no' && dial_major_color === 'red58' && ticks_past_major === '5') { - return new Error("De wijzer blijft op \"NVT\" staan als het gele gedeelte niet geactiveerd is") - } - if (yellow_moved === 'yes' && dial_major_color === 'na' && ticks_past_major === 'na') { - return 0 - } - if (yellow_moved === 'yes' && dial_major_color === 'red10' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'orange16' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'green22' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'blue28' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red34' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'blue40' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'green46' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'orange52' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red58' && ticks_past_major === 'na') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'na' && ticks_past_major === '0') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red10' && ticks_past_major === '0') { - return 0.1 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange16' && ticks_past_major === '0') { - return 0.16 - } - if (yellow_moved === 'yes' && dial_major_color === 'green22' && ticks_past_major === '0') { - return 0.22 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue28' && ticks_past_major === '0') { - return 0.28 - } - if (yellow_moved === 'yes' && dial_major_color === 'red34' && ticks_past_major === '0') { - return 0.34 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue40' && ticks_past_major === '0') { - return 0.4 - } - if (yellow_moved === 'yes' && dial_major_color === 'green46' && ticks_past_major === '0') { - return 0.46 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange52' && ticks_past_major === '0') { - return 0.52 - } - if (yellow_moved === 'yes' && dial_major_color === 'red58' && ticks_past_major === '0') { - return 0.58 - } - if (yellow_moved === 'yes' && dial_major_color === 'na' && ticks_past_major === '1') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red10' && ticks_past_major === '1') { - return 0.11 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange16' && ticks_past_major === '1') { - return 0.17 - } - if (yellow_moved === 'yes' && dial_major_color === 'green22' && ticks_past_major === '1') { - return 0.23 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue28' && ticks_past_major === '1') { - return 0.29 - } - if (yellow_moved === 'yes' && dial_major_color === 'red34' && ticks_past_major === '1') { - return 0.35 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue40' && ticks_past_major === '1') { - return 0.41 - } - if (yellow_moved === 'yes' && dial_major_color === 'green46' && ticks_past_major === '1') { - return 0.47 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange52' && ticks_past_major === '1') { - return 0.53 - } - if (yellow_moved === 'yes' && dial_major_color === 'red58' && ticks_past_major === '1') { - return 0.58 - } - if (yellow_moved === 'yes' && dial_major_color === 'na' && ticks_past_major === '2') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red10' && ticks_past_major === '2') { - return 0.12 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange16' && ticks_past_major === '2') { - return 0.18 - } - if (yellow_moved === 'yes' && dial_major_color === 'green22' && ticks_past_major === '2') { - return 0.24 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue28' && ticks_past_major === '2') { - return 0.3 - } - if (yellow_moved === 'yes' && dial_major_color === 'red34' && ticks_past_major === '2') { - return 0.36 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue40' && ticks_past_major === '2') { - return 0.42 - } - if (yellow_moved === 'yes' && dial_major_color === 'green46' && ticks_past_major === '2') { - return 0.48 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange52' && ticks_past_major === '2') { - return 0.54 - } - if (yellow_moved === 'yes' && dial_major_color === 'red58' && ticks_past_major === '2') { - return new Error("De wijzer kan niet zover draaien") - } - if (yellow_moved === 'yes' && dial_major_color === 'na' && ticks_past_major === '3') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red10' && ticks_past_major === '3') { - return 0.13 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange16' && ticks_past_major === '3') { - return 0.19 - } - if (yellow_moved === 'yes' && dial_major_color === 'green22' && ticks_past_major === '3') { - return 0.25 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue28' && ticks_past_major === '3') { - return 0.31 - } - if (yellow_moved === 'yes' && dial_major_color === 'red34' && ticks_past_major === '3') { - return 0.37 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue40' && ticks_past_major === '3') { - return 0.43 - } - if (yellow_moved === 'yes' && dial_major_color === 'green46' && ticks_past_major === '3') { - return 0.49 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange52' && ticks_past_major === '3') { - return 0.55 - } - if (yellow_moved === 'yes' && dial_major_color === 'red58' && ticks_past_major === '3') { - return new Error("De wijzer kan niet zover draaien") - } - if (yellow_moved === 'yes' && dial_major_color === 'na' && ticks_past_major === '4') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red10' && ticks_past_major === '4') { - return 0.14 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange16' && ticks_past_major === '4') { - return 0.2 - } - if (yellow_moved === 'yes' && dial_major_color === 'green22' && ticks_past_major === '4') { - return 0.26 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue28' && ticks_past_major === '4') { - return 0.32 - } - if (yellow_moved === 'yes' && dial_major_color === 'red34' && ticks_past_major === '4') { - return 0.38 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue40' && ticks_past_major === '4') { - return 0.44 - } - if (yellow_moved === 'yes' && dial_major_color === 'green46' && ticks_past_major === '4') { - return 0.5 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange52' && ticks_past_major === '4') { - return 0.56 - } - if (yellow_moved === 'yes' && dial_major_color === 'red58' && ticks_past_major === '4') { - return new Error("De wijzer kan niet zover draaien") - } - if (yellow_moved === 'yes' && dial_major_color === 'na' && ticks_past_major === '5') { - return new Error("Er moet of twee keer \"NVT\" of twee keer een waarde worden gekozen") - } - if (yellow_moved === 'yes' && dial_major_color === 'red10' && ticks_past_major === '5') { - return 0.15 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange16' && ticks_past_major === '5') { - return 0.21 - } - if (yellow_moved === 'yes' && dial_major_color === 'green22' && ticks_past_major === '5') { - return 0.27 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue28' && ticks_past_major === '5') { - return 0.33 - } - if (yellow_moved === 'yes' && dial_major_color === 'red34' && ticks_past_major === '5') { - return 0.39 - } - if (yellow_moved === 'yes' && dial_major_color === 'blue40' && ticks_past_major === '5') { - return 0.45 - } - if (yellow_moved === 'yes' && dial_major_color === 'green46' && ticks_past_major === '5') { - return 0.51 - } - if (yellow_moved === 'yes' && dial_major_color === 'orange52' && ticks_past_major === '5') { - return 0.57 - } - if (yellow_moved === 'yes' && dial_major_color === 'red58' && ticks_past_major === '5') { - return new Error("De wijzer kan niet zover draaien") - } - }] - }, { - "title": "Flexibiliteit", - "description": "De zichtbare situatie aan het einde van de wedstrijd:
  • Het model is 90⁰ gedraaid tegen de richting van de klok in ten opzichte van de beginpositie.
Vereiste methode en beperkingen:
  • Geen.
", - "objectives": [{ - "id": "model_rotated", - "title": "Model is 90 graden tegen de klok in gedraaid", - "type": "yesno" - }], - "score": [function(model_rotated) { - if (model_rotated === 'no') { - return 0 - } - if (model_rotated === 'yes') { - return 15 - } - }] - }, { - "title": "Strafpunten", - "description": "training-desc", - "objectives": [{ - "id": "penalties_objective", - "title": "Robot, rommel of uitvouwstrafpunten", - "options": [{ - "value": "0", - "title": "0" - }, { - "value": "1", - "title": "1" - }, { - "value": "2", - "title": "2" - }, { - "value": "3", - "title": "3" - }, { - "value": "4", - "title": "4" - }, { - "value": "5", - "title": "5" - }, { - "value": "6", - "title": "6" - }, { - "value": "7", - "title": "7" - }, { - "value": "8", - "title": "8" - }], - "type": "enum" - }], - "score": [function(penalties_objective) { - if (penalties_objective === '0') { - return 0 - } - if (penalties_objective === '1') { - return -10 - } - if (penalties_objective === '2') { - return -20 - } - if (penalties_objective === '3') { - return -30 - } - if (penalties_objective === '4') { - return -40 - } - if (penalties_objective === '5') { - return -50 - } - if (penalties_objective === '6') { - return -60 - } - if (penalties_objective === '7') { - return -70 - } - if (penalties_objective === '8') { - return -80 - } - }] - }] - }; - - - - function indexObjectives(missions) { objs = {}; angular.forEach(missions,function(mission) { From 0b695662106709e50aac320df8ebe69eb131d6f6 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 13:36:51 +0100 Subject: [PATCH 16/76] Tests for log --- spec/services/fs-pgSpec.js | 2 -- spec/services/logSpec.js | 28 ++++++++++++++++++++++++++++ src/js/services/log.js | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 spec/services/logSpec.js diff --git a/spec/services/fs-pgSpec.js b/spec/services/fs-pgSpec.js index 8e6ad65b..6b857afe 100644 --- a/spec/services/fs-pgSpec.js +++ b/spec/services/fs-pgSpec.js @@ -1,7 +1,5 @@ describe('fs-pg',function() { - - var fs = factory('services/fs-pg',{ 'q':Q, 'services/log': logMock diff --git a/spec/services/logSpec.js b/spec/services/logSpec.js new file mode 100644 index 00000000..64e7058e --- /dev/null +++ b/spec/services/logSpec.js @@ -0,0 +1,28 @@ +describe('log',function() { + var log = factory('services/log',{ + jquery: $ + }); + + describe('logging',function() { + beforeEach(function() { + //empty the log + var l = log.get(); + l.splice(0,l.length); + }); + it('should start with an empty log',function() { + expect(log.get()).toEqual([]); + }); + it('should add a single string argument to the log',function() { + log('foo'); + expect(log.get()).toEqual(['"foo"']); + }); + it('should add multiple arguments to the log',function() { + log(8,'bars'); + expect(log.get()).toEqual(['8 "bars"']); + }); + it('should log something that cannot be json stringified',function() { + log(8,window); + expect(log.get()).toEqual(['8 [object Window]']); + }); + }); +}); diff --git a/src/js/services/log.js b/src/js/services/log.js index 3f68fd9f..0606a3d6 100644 --- a/src/js/services/log.js +++ b/src/js/services/log.js @@ -1,4 +1,4 @@ -define([ +define('services/log',[ 'jquery' ],function($) { var _log = []; From 0b9c89210dc8e549350bec96069aa7debe9ac2e0 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 13:52:45 +0100 Subject: [PATCH 17/76] Fixed coverage for fs-nw --- spec/helpers/defineShim.js | 10 +++--- spec/services/fs-nwSpec.js | 71 +++++++++++++++++++++----------------- src/js/services/fs-nw.js | 4 +-- 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/spec/helpers/defineShim.js b/spec/helpers/defineShim.js index 34394b0c..90595c98 100644 --- a/spec/helpers/defineShim.js +++ b/spec/helpers/defineShim.js @@ -1,27 +1,27 @@ !function() { var store = {}; var inited = {}; - this.factory = function(name,deps) { - if (inited[name]) { + this.factory = function(name,deps,force) { + if (inited[name] && !force) { return inited[name]; } if (!store[name]) { console.log('unable to find module',name,'in store'); console.log(JSON.stringify(store,null,2)); return; - }; + } deps = deps||{}; var resolvedDeps = store[name].deps.map(function(dep) { return deps[dep]||undefined; }); inited[name] = store[name].factory.apply(this,resolvedDeps); return inited[name]; - } + }; this.define = function(name,deps,factory) { //store factories in a global store store[name] = { factory: factory, deps: deps - } + }; }; }(); diff --git a/spec/services/fs-nwSpec.js b/spec/services/fs-nwSpec.js index 361677e6..3e32a5a5 100644 --- a/spec/services/fs-nwSpec.js +++ b/spec/services/fs-nwSpec.js @@ -1,43 +1,52 @@ describe('fs-nw',function() { - var fs = factory('services/fs-nw',{ - 'q':Q, - 'idbstore': IDBStore - }); - describe('test',function() { - it('should pass',function() { - expect(true).toBe(true); - }); - }); - describe('fs signature',function() { - it('should have a read method',function() { - expect(fs.read).not.toBeUndefined(); + describe('store exists',function() { + var fs = factory('services/fs-nw',{ + 'q':Q, + 'idbstore': window.IDBStore + },true); + describe('reading',function() { + it('should read a test file',function(done) { + fs.write('foo/foo.txt','jsfd978sd').then(function() { + return fs.read('foo/foo.txt'); + }).then(function(data) { + expect(data).toBe('jsfd978sd'); + }).fail(function(data) { + console.log('fail',data); + }).then(function() { + fs.remove('foo/foo.txt').then(done); + }); + }); }); - }); - describe('reading',function() { - it('should read a test file',function(done) { - fs.write('foo/foo.txt','jsfd978sd').then(function() { - return fs.read('foo/foo.txt'); - }).then(function(data) { - expect(data).toBe('jsfd978sd'); - }).fail(function(data) { - console.log('fail',data); - }).then(function() { - fs.remove('foo/foo.txt').then(done); + describe('writing',function() { + it('should write a test file',function(done) { + fs.write('foo/foo.txt','jsfd978sd').then(function(data) { + expect(data).toBe('foo/foo.txt'); + }).fail(function(data) { + console.log('fail',data); + }).then(function() { + fs.remove('foo/foo.txt').then(done); + }); }); }); }); - describe('writing',function() { - it('should write a test file',function(done) { - fs.write('foo/foo.txt','jsfd978sd').then(function(data) { - expect(data).toBe('foo/foo.txt'); - }).fail(function(data) { - console.log('fail',data); - }).then(function() { - fs.remove('foo/foo.txt').then(done); + describe('failure creating store',function() { + var IDBStore = function(config) { + console.log('idbstore'); + config.onError('cannot create store'); + }; + var fs = factory('services/fs-nw',{ + 'q':Q, + 'idbstore': IDBStore + },true); + it('fail store cannot be created',function() { + return fs.read('foo/quxmoo.txt').fail(function(err) { + console.log('foo'); + expect(err).toBe('cannot create store'); }); }); }); + }); diff --git a/src/js/services/fs-nw.js b/src/js/services/fs-nw.js index f92609e1..ccb14b0e 100644 --- a/src/js/services/fs-nw.js +++ b/src/js/services/fs-nw.js @@ -8,8 +8,8 @@ define('services/fs-nw',['q','idbstore'],function(Q,IDBStore) { onStoreReady: function() { def.resolve(store); }, - onError: function() { - def.reject(); + onError: function(err) { + def.reject(err); } }); return def.promise; From f02e7d7f6a3a28fb5c3ddd4db45b1a62c6d34451 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 14:12:30 +0100 Subject: [PATCH 18/76] Added a grunt task to build js files from xml --- Gruntfile.js | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ readme.md | 19 +++++++-------- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ca51b65b..cefd1932 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -105,6 +105,16 @@ module.exports = function(grunt) { src: 'challenges/html/*.html', dest: 'challenges/pdf/' } + }, + + jsChallenge: { + options: { + + }, + files: { + src: 'challenges/xml/*.xml', + dest: 'challenges/js/' + } } }); @@ -118,8 +128,64 @@ module.exports = function(grunt) { grunt.registerTask('phonegap:ios', ['phonegap:login', 'phonegap:build:ios', 'phonegap:logout']); grunt.registerTask('phonegap:android', ['phonegap:login', 'phonegap:build:android', 'phonegap:logout']); grunt.registerTask('html', ['saxon']); + grunt.registerTask('js', ['jsChallenge']); grunt.registerTask('pdf', ['saxon','http-server', 'phantomJSScreenShot']); + grunt.registerMultiTask('jsChallenge', function() { + var options = this.options(); + var npath = require('path'); + var nfs = require('fs'); + var Q = require('q'); + var done = this.async(); + var exec = require('child_process').exec; + + function process(filepath,dest) { + return Q.promise(function(resolve,reject) { + var base = npath.basename(filepath, '.html'); + + var cmd = [ + 'node', + '"tools/buildchallenge.js"', + '"' + filepath + '"', + '>', + '"' + dest + '"' + ].join(' '); + + // console.log(cmd); + // resolve() + exec(cmd, function(error, stdout, stderr) { + if (error !== null) { + console.log('exec error: ' + error); + reject(error); + } + resolve(); + }); + }); + } + + this.files.forEach(function(f) { + f.src.filter(function(filepath) { + // Warn on and remove invalid source files (if nonull was set). + if (!grunt.file.exists(filepath)) { + grunt.log.warn('Source file "' + filepath + '" not found.'); + return false; + } else { + return true; + } + }).map(function(filepath) { + return function() { + var base = npath.basename(filepath, '.xml'); + var dest = npath.resolve(f.dest, base) + '.js'; + // console.log(filepath); + // console.log(dest); + return process(filepath,dest); + }; + }).reduce(function(pending,promise) { + return pending.then(promise); + },Q()).then(done,done); + }); + }); + grunt.registerMultiTask('saxon', function() { var options = this.options(); var saxonPath = options.saxonPath; diff --git a/readme.md b/readme.md index e33dc92e..4374afc7 100644 --- a/readme.md +++ b/readme.md @@ -66,9 +66,16 @@ For the phonegap build, copy `pgbuildconfig.example.json` to `pgbuildconfig.json For iOS, see [Building for iOS](https://github.com/FirstLegoLeague/fllscoring/wiki/Building-for-iOS) -To build js challenge files from the xml description files, use +(Only) when XML definition files have changed: +----------------------------- + +- run `grunt html` +- run `grunt pdf` +- run `grunt js` + +This will rebuild html, pdf and js versions of the challenge. - node tools\buildchallenge.js challenges\xml\2014.xml > challenges\js\2014.js +These files are also included in the repo: `challenges/html`, `challenges/pdf`, `challenges/js` Documentation ------------- @@ -79,14 +86,6 @@ Documentation - [interface](docs/user_interface/readme.md) - [internationalization](docs/i18n/readme.md) -Generating HTML and PDF scoresheets ------------------------------ - -- run `grunt html` -- run `grunt pdf` - -These files are also included in the repo: `challenges/html` and `challenges/pdf` - TODO's -------- From 5cc7bdfce6b088aa627abcee29a25e3eac78b689 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 14:52:43 +0100 Subject: [PATCH 19/76] More tests for teams controller --- spec/views/teamsSpec.js | 284 ++++++++++++++++++++++++++-------------- src/js/views/teams.js | 12 +- 2 files changed, 191 insertions(+), 105 deletions(-) diff --git a/spec/views/teamsSpec.js b/spec/views/teamsSpec.js index 2d7fe25f..f3e6445b 100644 --- a/spec/views/teamsSpec.js +++ b/spec/views/teamsSpec.js @@ -31,128 +31,216 @@ describe('teams', function() { translationNeeded: false }; - beforeEach(function() { - angular.mock.module(module.name); - angular.mock.inject(function($controller, $rootScope, _$httpBackend_) { - $scope = $rootScope.$new(); - $httpBackend = _$httpBackend_; - $httpBackend.when('GET','http://fll.mobilesorcery.nl/api/public/teams/') - .respond([ - mockRemoteTeam - ]); - $teams = createTeamsMock([mockTeam]); - controller = $controller('teamsCtrl', { - '$scope': $scope, - '$teams': $teams + describe('missing teams.json on storage',function() { + beforeEach(function() { + angular.mock.module(module.name); + angular.mock.inject(function($controller, $rootScope) { + $scope = $rootScope.$new(); + $teams = createTeamsMock([]); + controller = $controller('teamsCtrl', { + '$scope': $scope, + '$teams': $teams + }); }); + return $scope.init(); }); - return $scope.init(); - }); - beforeEach(function() { - //spy setPage method; - $scope.setPage = jasmine.createSpy('setPage'); - }) - - describe('initialization', function() { - it('should initialize', function() { - expect($scope.teams).toEqual([mockTeam]); - expect($scope.newTeam).toEqual({}); - expect($scope.editMode).toBe(false); - }); - - }); - - xdescribe('missing teams.json on storage',function() { - beforeEach(function() { - // TODO: this test is broken, because $scope.init() is already called - // before this test starts, as construction of the controller has - // been done by an earlier beforeEach() call. - // So, the teams have already been loaded. - $teams.teams = []; - }) it('should initialize in editmode when no teams found on storage', function() { expect($scope.teams).toEqual([]); expect($scope.newTeam).toEqual({}); expect($scope.editMode).toBe(true); + expect($scope.status).toBe('No stored teams found, you may add them by hand'); }); }); - describe('load', function() { - it('should call the web service for new teams',function() { - $scope.load(); - $scope.saveTeams = jasmine.createSpy('saveTeamsSpy').andReturn(Q.when()); - $httpBackend.flush(); - expect($scope.saveTeams).toHaveBeenCalled(); - expect($scope.teams).toEqual([mockTeam]) + describe('stored teams',function() { + beforeEach(function() { + angular.mock.module(module.name); + angular.mock.inject(function($controller, $rootScope, _$httpBackend_) { + $scope = $rootScope.$new(); + $httpBackend = _$httpBackend_; + $teams = createTeamsMock([mockTeam]); + controller = $controller('teamsCtrl', { + '$scope': $scope, + '$teams': $teams + }); + }); + return $scope.init(); }); - }); - describe('selectTeam', function() { - it('shoud select the scoresheet page', function() { - var team = mockTeam; - var eventSpy = jasmine.createSpy('eventSpy'); - $scope.$root.$on('selectTeam', eventSpy); - $scope.selectTeam(team); - expect($scope.setPage).toHaveBeenCalledWith('scoresheet'); - expect(eventSpy).toHaveBeenCalled(); - expect(eventSpy.mostRecentCall.args[1]).toBe(team); + beforeEach(function() { + //spy setPage method; + $scope.setPage = jasmine.createSpy('setPage'); }); - }); - describe('canAddTeam', function() { - it('should not allow adding when name or number is missing', function() { - $scope.newTeam = {}; - expect($scope.canAddTeam()).toBe(false); + describe('initialization', function() { + it('should initialize', function() { + expect($scope.teams).toEqual([mockTeam]); + expect($scope.newTeam).toEqual({}); + expect($scope.editMode).toBe(false); + }); + }); - }); - describe('addTeam', function() { - it('should add the newTeam from scope to the teams list and blank the new team and save it', function() { - $scope.saveTeams = jasmine.createSpy('saveTeams').andReturn(Q.when()); - $scope.newTeam = mockTeam; - $scope.addTeam(); - expect($teams.add).toHaveBeenCalledWith(mockTeam); - expect($scope.newTeam).toEqual({}); - expect($scope.saveTeams).toHaveBeenCalled(); + describe('load', function() { + it('should call the web service for new teams',function() { + $httpBackend.when('GET','http://fll.mobilesorcery.nl/api/public/teams/') + .respond([ + mockRemoteTeam + ]); + $scope.load(); + $scope.saveTeams = jasmine.createSpy('saveTeamsSpy').andReturn(Q.when()); + $httpBackend.flush(); + expect($teams.clear).toHaveBeenCalled(); + expect($scope.saveTeams).toHaveBeenCalled(); + expect($scope.teams).toEqual([mockTeam]); + }); + it('should log failing get when teams cannot be found',function() { + $httpBackend.when('GET','http://fll.mobilesorcery.nl/api/public/teams/') + .respond(404); + $scope.load(); + $httpBackend.flush(); + expect(logMock).toHaveBeenCalledWith('failed retrieving teams'); + }); }); - it('should not add a team when data is incomplete', function() { - $scope.saveTeams = jasmine.createSpy('saveTeams').andReturn(Q.when()); - $scope.newTeam = {foo:'bar'}; - $scope.addTeam(); - expect($teams.add).not.toHaveBeenCalled(); - expect($scope.newTeam).toEqual({foo:'bar'}); - expect($scope.saveTeams).not.toHaveBeenCalled(); + + describe('import',function() { + it('should set import mode to true and clear the importRaw field',function() { + $scope.importRaw = 'foo'; + expect($scope.importMode).toBe(false); + $scope.import(); + expect($scope.importMode).toBe(true); + expect($scope.importRaw).toBe(''); + }); }); - }); - describe('removeTeam', function() { - it('should remove the team with the given index', function() { - $scope.saveTeams = jasmine.createSpy('saveTeams').andReturn(Q.when()); - $scope.removeTeam(123); - expect($teams.remove).toHaveBeenCalledWith(123); - expect($scope.saveTeams).toHaveBeenCalled(); + describe('finishImport',function() { + beforeEach(function() { + $scope.importMode = true; + $scope.importLines = [[42,'FooBars']]; + $scope.importNumberColumn = 1; + $scope.importNameColumn = 2; + }); + it('should set import mode to false',function() { + $scope.finishImport(); + expect($scope.importMode).toBe(false); + }); + it('should clear the teams',function() { + $scope.finishImport(); + expect($teams.clear).toHaveBeenCalled(); + }); + it('should add the teams in the lines',function() { + $scope.finishImport(); + expect($teams.add).toHaveBeenCalledWith({ + number: 42, + name: 'FooBars' + }); + }); }); - }); - describe('saveTeams', function() { - it('should call $teams.save', function() { - $scope.teams = [mockTeam]; - $scope.saveTeams(); - expect($teams.save).toHaveBeenCalled(); + describe('parsing data',function() { + it('should populate importLines',function() { + $scope.importLines = []; + $scope.importRaw = '42\tFooBar\n7\tQuxMoo'; + $scope.$digest(); + expect($scope.importLines).toEqual([ + ['42','FooBar'], + ['7','QuxMoo'] + ]); + expect($scope.importNumberExample).toEqual('42'); + expect($scope.importNameExample).toEqual('FooBar'); + }); + + it('should skip the first line if it is a header',function() { + $scope.importLines = []; + $scope.importRaw = 'Number\tName\n7\tQuxMoo'; + $scope.importHeader = true; + $scope.$digest(); + expect($scope.importLines).toEqual([ + ['7','QuxMoo'] + ]); + expect($scope.importNumberExample).toEqual('7'); + expect($scope.importNameExample).toEqual('QuxMoo'); + }); + + it('should not populate example lines if no data given',function() { + $scope.importLines = []; + $scope.importNumberExample = 'numberExample'; + $scope.importNameExample = 'nameExample'; + $scope.importRaw = ''; + $scope.$digest(); + expect($scope.importLines).toEqual([]); + expect($scope.importNumberExample).toEqual(''); + expect($scope.importNameExample).toEqual(''); + }); + }); + + describe('selectTeam', function() { + it('shoud select the scoresheet page', function() { + var team = mockTeam; + var eventSpy = jasmine.createSpy('eventSpy'); + $scope.$root.$on('selectTeam', eventSpy); + $scope.selectTeam(team); + expect($scope.setPage).toHaveBeenCalledWith('scoresheet'); + expect(eventSpy).toHaveBeenCalled(); + expect(eventSpy.mostRecentCall.args[1]).toBe(team); + }); }); - }); - describe('toggleExtended',function() { - it('should not toggle when in edit mode',function() { - $scope.editMode = true; - expect($scope.toggleExtended(true)).toBe(true); - expect($scope.toggleExtended(false)).toBe(false); + describe('canAddTeam', function() { + it('should not allow adding when name or number is missing', function() { + $scope.newTeam = {}; + expect($scope.canAddTeam()).toBe(false); + }); }); - it('should toggle when not in edit mode',function() { - $scope.editMode = false; - expect($scope.toggleExtended(true)).toBe(false); - expect($scope.toggleExtended(false)).toBe(true); + + describe('addTeam', function() { + it('should add the newTeam from scope to the teams list and blank the new team and save it', function() { + $scope.saveTeams = jasmine.createSpy('saveTeams').andReturn(Q.when()); + $scope.newTeam = mockTeam; + $scope.addTeam(); + expect($teams.add).toHaveBeenCalledWith(mockTeam); + expect($scope.newTeam).toEqual({}); + expect($scope.saveTeams).toHaveBeenCalled(); + }); + it('should not add a team when data is incomplete', function() { + $scope.saveTeams = jasmine.createSpy('saveTeams').andReturn(Q.when()); + $scope.newTeam = {foo:'bar'}; + $scope.addTeam(); + expect($teams.add).not.toHaveBeenCalled(); + expect($scope.newTeam).toEqual({foo:'bar'}); + expect($scope.saveTeams).not.toHaveBeenCalled(); + }); + }); + + describe('removeTeam', function() { + it('should remove the team with the given index', function() { + $scope.saveTeams = jasmine.createSpy('saveTeams').andReturn(Q.when()); + $scope.removeTeam(123); + expect($teams.remove).toHaveBeenCalledWith(123); + expect($scope.saveTeams).toHaveBeenCalled(); + }); + }); + + describe('saveTeams', function() { + it('should call $teams.save', function() { + $scope.teams = [mockTeam]; + $scope.saveTeams(); + expect($teams.save).toHaveBeenCalled(); + }); + }); + + describe('toggleExtended',function() { + it('should not toggle when in edit mode',function() { + $scope.editMode = true; + expect($scope.toggleExtended(true)).toBe(true); + expect($scope.toggleExtended(false)).toBe(false); + }); + it('should toggle when not in edit mode',function() { + $scope.editMode = false; + expect($scope.toggleExtended(true)).toBe(false); + expect($scope.toggleExtended(false)).toBe(true); + }); }); }); }); diff --git a/src/js/views/teams.js b/src/js/views/teams.js index ad66b878..45e952d1 100644 --- a/src/js/views/teams.js +++ b/src/js/views/teams.js @@ -18,6 +18,7 @@ define('views/teams',[ $scope.editMode = false; $scope.teamNumberPattern = /^\d+$/; $scope.status = "Initializing..."; + $scope.importMode = false; var initialized = null; @@ -79,22 +80,16 @@ define('views/teams',[ }; $scope.$watch('importRaw',function(data) { - if (!data) { - return; - } parseData($scope.importRaw); }); $scope.$watch('importHeader',function(data) { - if (!data) { - return; - } parseData($scope.importRaw); }); function parseData(data) { //parse raw import, split lines - var lines = data.split(/[\n\r]/); + var lines = data?data.split(/[\n\r]/):[]; if ($scope.importHeader) { lines.shift(); } @@ -109,6 +104,9 @@ define('views/teams',[ if (lines[0]) { $scope.importNumberExample = lines[0][$scope.importNumberColumn -1]; $scope.importNameExample = lines[0][$scope.importNameColumn -1]; + } else { + $scope.importNumberExample = ''; + $scope.importNameExample = ''; } $scope.importLines = lines; From 9a5193291bb14ee8475b41833d8f6df0d04af1ee Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 15:06:34 +0100 Subject: [PATCH 20/76] Added grunt challenge task for brevity --- Gruntfile.js | 1 + challenges/pdf/2012.pdf | Bin 34036 -> 34036 bytes challenges/pdf/2014.pdf | Bin 37809 -> 37809 bytes challenges/pdf/2014_nl_NL-no-enum.pdf | Bin 38082 -> 38082 bytes challenges/pdf/2014_nl_NL.pdf | Bin 37939 -> 37939 bytes readme.md | 6 ++++-- 6 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index cefd1932..c1a82885 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -130,6 +130,7 @@ module.exports = function(grunt) { grunt.registerTask('html', ['saxon']); grunt.registerTask('js', ['jsChallenge']); grunt.registerTask('pdf', ['saxon','http-server', 'phantomJSScreenShot']); + grunt.registerTask('challenge', ['js', 'pdf']); //html is generated with pdf grunt.registerMultiTask('jsChallenge', function() { var options = this.options(); diff --git a/challenges/pdf/2012.pdf b/challenges/pdf/2012.pdf index 6fe127d66546e62b58a5437687d31d511baffdec..7bad4086f4ae6986480c8f49f23df2c3f4e3b18b 100644 GIT binary patch delta 21 ccmey;$@Ha@X~H!QBU3|D0}~^QjrYV_0AYj(F#rGn delta 21 ccmey;$@Ha@X~H!QLnA{=Q)5$;jrYV_0AZR4Gynhq diff --git a/challenges/pdf/2014.pdf b/challenges/pdf/2014.pdf index ad47d2177554c3e38620af56d15bd1deba67946d..a1f15af278905999fd7f48dbcc7dbc33fa94fd3b 100644 GIT binary patch delta 21 dcmdnEoN427rU}@LS2&(`9 delta 21 dcmdnEoN427rU}>Hr~5D2>@M92)6(L diff --git a/challenges/pdf/2014_nl_NL-no-enum.pdf b/challenges/pdf/2014_nl_NL-no-enum.pdf index 293d6f29312468b31667bd4566313ac522c006d2..1afe5d496feba145a4e52b1739b6ae8cf49121b4 100644 GIT binary patch delta 21 dcmX@KlIhS&rU}_ diff --git a/challenges/pdf/2014_nl_NL.pdf b/challenges/pdf/2014_nl_NL.pdf index 43f7082d6df29f83ea374ab9b8952a34b77ae231..7f6a96f433afc95dbeff79bdb69083609aab7249 100644 GIT binary patch delta 21 dcmdnIf@$*#rU} diff --git a/readme.md b/readme.md index 4374afc7..575fe651 100644 --- a/readme.md +++ b/readme.md @@ -69,12 +69,14 @@ For iOS, see [Building for iOS](https://github.com/FirstLegoLeague/fllscoring/wi (Only) when XML definition files have changed: ----------------------------- +- run `grunt challenge` + +This will rebuild html, pdf and js versions of the challenge. This can also be done individually if you'd wish: + - run `grunt html` - run `grunt pdf` - run `grunt js` -This will rebuild html, pdf and js versions of the challenge. - These files are also included in the repo: `challenges/html`, `challenges/pdf`, `challenges/js` Documentation From 70588caa165a9e7a5d149744bc0987a543e3127d Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 15:27:41 +0100 Subject: [PATCH 21/76] Added missing tests for ng-teams --- spec/services/ng-teamsSpec.js | 79 ++++++++++++++++++++++++++++------- src/js/services/ng-teams.js | 4 +- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/spec/services/ng-teamsSpec.js b/spec/services/ng-teamsSpec.js index 3c4f5d4f..a2372c9f 100644 --- a/spec/services/ng-teamsSpec.js +++ b/spec/services/ng-teamsSpec.js @@ -7,6 +7,7 @@ describe('ng-teams',function() { var $teams; var rawMockTeam = { number: "123", name: "Oefenrondes", cityState: "foo" }; + var rawMockTeam2 = { number: "123", name: "Oefenrondes", translationNeeded: true }; var savedMockTeam = { number: 123, name: "Oefenrondes", @@ -32,6 +33,19 @@ describe('ng-teams',function() { pitLocation: "", translationNeeded: false }; + var mockTeam2 = { + index: 0, + number: 123, + name: "Oefenrondes", + affiliation: "", + cityState: "", + country: "", + coach1: "", + coach2: "", + judgingGroup: "", + pitLocation: "", + translationNeeded: true + }; var fsMock; beforeEach(function() { @@ -54,26 +68,61 @@ describe('ng-teams',function() { }); }); - describe('loading', function() { + describe('save',function() { + it('should write teams to teams.json',function() { + return $teams.save().then(function() { + expect(fsMock.write).toHaveBeenCalledWith('teams.json',[savedMockTeam]) + }); + }); + + it('should log an error if writing fails',function() { + fsMock.write.andReturn(Q.reject('foo')); + return $teams.save().then(function() { + expect(logMock).toHaveBeenCalledWith('teams write error','foo'); + }); + }); + }); + + describe('load', function() { it('should load and sanitize teams',function() { return $teams.load().then(function() { expect($teams.teams).toEqual([mockTeam]); }); }); + + it('should log an error if loading fails',function() { + fsMock.read.andReturn(Q.reject('foo')); + return $teams.load().then(function() { + expect(logMock).toHaveBeenCalledWith('teams read error','foo'); + }); + }); }); - describe('getting',function() { - it('should get a sanitized team', function() { - expect($teams.get(123)).toEqual(mockTeam); + describe('remove',function() { + it('should remove the provided id',function() { + expect($teams.teams).toEqual([mockTeam]); + $teams.remove(123); + expect($teams.teams).toEqual([]); }); + + it('should not remove the team if not found',function() { + expect($teams.teams).toEqual([mockTeam]); + $teams.remove(42); + expect($teams.teams).toEqual([mockTeam]); + }) }); - describe('adding',function() { + describe('add',function() { it('should add a team to the list and add autogen properties',function() { $teams.clear(); var res = $teams.add(rawMockTeam); expect($teams.teams).toEqual([mockTeam]); }); + it('should add a team to the list and add autogen properties',function() { + $teams.clear(); + var res = $teams.add(rawMockTeam2); + expect($teams.teams).toEqual([mockTeam2]); + }); it('should reject duplicate team ids',function() { $teams.clear(); $teams.add(rawMockTeam); @@ -90,20 +139,18 @@ describe('ng-teams',function() { }); }); - describe('saving',function() { - it('should write teams to teams.json',function() { - return $teams.save().then(function() { - expect(fsMock.write).toHaveBeenCalledWith('teams.json',[savedMockTeam]) - }); + describe('get',function() { + it('should get a sanitized team', function() { + expect($teams.get(123)).toEqual(mockTeam); }); }); - describe('removing',function() { - it('should remove the provided id',function() { - expect($teams.teams).toEqual([mockTeam]); - $teams.remove(123); - expect($teams.teams).toEqual([]); + describe('_update',function() { + it('should throw an error if team is present twice',function() { + $teams._rawTeams = [rawMockTeam,rawMockTeam]; + expect(function() { + $teams._update() + }).toThrow('duplicate team number 123'); }); }); - }); diff --git a/src/js/services/ng-teams.js b/src/js/services/ng-teams.js index 6bd975ee..06340b58 100644 --- a/src/js/services/ng-teams.js +++ b/src/js/services/ng-teams.js @@ -109,11 +109,11 @@ define('services/ng-teams',[ Teams.prototype._update = function() { var self = this; - this._teamsMap = Object.create(null); + this._teamsMap = {}; this.teams.splice(0, this.teams.length); // clear without creating new object this._rawTeams.forEach(function(team, index) { if (team.number in self._teamsMap) { - // shouldn't ever happen, unless one fiddles with + // should never happen, unless one fiddles with // the raw storage throw new Error("duplicate team number " + team.number); } From fc53d56889c0839bcd8f326b16782fe1408ade7a Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 16:25:50 +0100 Subject: [PATCH 22/76] updated stages spec --- spec/services/ng-stagesSpec.js | 76 +++++++++++++++++++++++++--------- src/js/services/ng-stages.js | 2 +- 2 files changed, 58 insertions(+), 20 deletions(-) diff --git a/spec/services/ng-stagesSpec.js b/spec/services/ng-stagesSpec.js index be151f89..b1863542 100644 --- a/spec/services/ng-stagesSpec.js +++ b/spec/services/ng-stagesSpec.js @@ -1,6 +1,6 @@ -"use strict"; - describe('ng-stages',function() { + "use strict"; + var ngServices = factory('services/ng-services'); var module = factory('services/ng-stages',{ 'services/ng-services': ngServices, @@ -32,27 +32,67 @@ describe('ng-stages',function() { return $stages.init(); }); - describe('initializing',function() { + describe('init',function() { it('should load stages by default', function() { expect($stages.stages).toEqual([mockStageSanitized]); }); }); - describe('loading', function() { + describe('save',function() { + it('should write stages to stages.json',function() { + return $stages.save().then(function() { + expect(fsMock.write).toHaveBeenCalledWith('stages.json',[mockStage]); + }); + }); + it('should log an error if writing fails',function() { + fsMock.write.andReturn(Q.reject('aargh')); + return $stages.save().then(function() { + expect(logMock).toHaveBeenCalledWith('stages write error','aargh'); + }); + }); + }); + + describe('load', function() { it('should load and sanitize stages',function() { return $stages.load().then(function() { expect($stages.stages).toEqual([mockStageSanitized]); }); }); + it('should log an error if reading fails',function() { + fsMock.read.andReturn(Q.reject('squeek')); + return $stages.load().then(function() { + expect(logMock).toHaveBeenCalledWith('stages read error','squeek'); + }); + }); + it('should initialize with default stages if reading fails',function() { + fsMock.read.andReturn(Q.reject('squeek')); + return $stages.load().then(function() { + expect(logMock).toHaveBeenCalledWith('stages using defaults'); + expect($stages.allStages).toEqual([ + {index:0,id:"practice",name:"Oefenrondes",rounds:2,$rounds:[1,2]}, + {index:1,id:"qualifying",name:"Voorrondes",rounds:3,$rounds:[1,2,3]}, + {index:2,id:"quarter",name:"Kwartfinales",rounds:0,$rounds:[]}, + {index:3,id:"semi",name:"Halve finales",rounds:0,$rounds:[]}, + {index:4,id:"final",name:"Finale",rounds:1,$rounds:[1]} + ]); + }); + }); }); - describe('getting',function() { - it('should get a sanitized stage', function() { - expect($stages.get("practice")).toEqual(mockStageSanitized); + describe('remove',function() { + it('should remove the provided id',function() { + expect($stages.stages).toEqual([mockStageSanitized]); + $stages.remove("practice"); + expect($stages.stages).toEqual([]); + }); + it('should do nothing if id not found',function() { + expect($stages.stages).toEqual([mockStageSanitized]); + $stages.remove("foobar"); + expect($stages.stages).toEqual([mockStageSanitized]); }); }); - describe('adding',function() { + describe('add',function() { it('should add a stage to the list and add autogen properties',function() { $stages.clear(); var res = $stages.add(mockStage); @@ -78,20 +118,18 @@ describe('ng-stages',function() { }); }); - describe('saving',function() { - it('should write stages to stages.json',function() { - return $stages.save().then(function() { - expect(fsMock.write).toHaveBeenCalledWith('stages.json',[mockStage]) - }); + describe('get',function() { + it('should get a sanitized stage', function() { + expect($stages.get("practice")).toEqual(mockStageSanitized); }); }); - describe('removing',function() { - it('should remove the provided id',function() { - expect($stages.stages).toEqual([mockStageSanitized]); - $stages.remove("practice"); - expect($stages.stages).toEqual([]); + describe('_update',function() { + it('should throw an error if stage is present twice',function() { + $stages._rawStages = [mockStage,mockStage]; + expect(function() { + $stages._update(); + }).toThrow('duplicate stage id practice'); }); }); - }); diff --git a/src/js/services/ng-stages.js b/src/js/services/ng-stages.js index 8d72304c..0375fc09 100644 --- a/src/js/services/ng-stages.js +++ b/src/js/services/ng-stages.js @@ -71,7 +71,7 @@ define('services/ng-stages',[ log('stages using defaults'); self.add({ id: "practice", name: "Oefenrondes", rounds: 2 }); self.add({ id: "qualifying", name: "Voorrondes", rounds: 3 }); - self.add({ id: "quarter", name: "Kwart finales", rounds: 0 }); + self.add({ id: "quarter", name: "Kwartfinales", rounds: 0 }); self.add({ id: "semi", name: "Halve finales", rounds: 0 }); self.add({ id: "final", name: "Finale", rounds: 1 }); }); From 6535ef018a8d04d1b6038da97a5cd0bd4988f98a Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 16:26:01 +0100 Subject: [PATCH 23/76] lint --- spec/services/ng-teamsSpec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/services/ng-teamsSpec.js b/spec/services/ng-teamsSpec.js index a2372c9f..4fa04b70 100644 --- a/spec/services/ng-teamsSpec.js +++ b/spec/services/ng-teamsSpec.js @@ -71,7 +71,7 @@ describe('ng-teams',function() { describe('save',function() { it('should write teams to teams.json',function() { return $teams.save().then(function() { - expect(fsMock.write).toHaveBeenCalledWith('teams.json',[savedMockTeam]) + expect(fsMock.write).toHaveBeenCalledWith('teams.json',[savedMockTeam]); }); }); @@ -109,7 +109,7 @@ describe('ng-teams',function() { expect($teams.teams).toEqual([mockTeam]); $teams.remove(42); expect($teams.teams).toEqual([mockTeam]); - }) + }); }); describe('add',function() { @@ -149,7 +149,7 @@ describe('ng-teams',function() { it('should throw an error if team is present twice',function() { $teams._rawTeams = [rawMockTeam,rawMockTeam]; expect(function() { - $teams._update() + $teams._update(); }).toThrow('duplicate team number 123'); }); }); From 5008e974590e8bc97cf21061bb3126e4ea04d48e Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 16:26:44 +0100 Subject: [PATCH 24/76] More tests for scores (needs a bit of love still) --- spec/services/ng-scoresSpec.js | 157 +++++++++++++++++++++++---------- 1 file changed, 110 insertions(+), 47 deletions(-) diff --git a/spec/services/ng-scoresSpec.js b/spec/services/ng-scoresSpec.js index b01b0d4c..0e1116d5 100644 --- a/spec/services/ng-scoresSpec.js +++ b/spec/services/ng-scoresSpec.js @@ -1,6 +1,5 @@ -"use strict"; - describe('ng-scores',function() { + "use strict"; var ngServices = factory('services/ng-services'); var module = factory('services/ng-scores',{ 'services/ng-services': ngServices, @@ -76,13 +75,67 @@ describe('ng-scores',function() { }); } - describe('initialize',function() { + describe('init',function() { it('should load mock score initially',function() { expect(filteredScores()).toEqual([mockScore]); }); }); - describe('adding scores',function() { + describe('clear',function() { + it('should clear the scores',function() { + expect(filteredScores()).toEqual([mockScore]); + $scores.clear(); + expect(filteredScores()).toEqual([]); + }); + }); + + describe('save',function() { + it('should write scores to scores.json',function() { + return $scores.save().then(function() { + expect(fsMock.write).toHaveBeenCalledWith( + 'scores.json', + { + version: 2, + scores: [rawMockScore], + sheets: [] + } + ); + }); + }); + + it('should log an error if writing fails',function() { + fsMock.write.andReturn(Q.reject('write err')); + return $scores.save().then(function() { + expect(logMock).toHaveBeenCalledWith('scores write error','write err'); + }); + }); + }); + + describe('load',function() { + it('should load from scores.json',function() { + return $scores.load().then(function() { + expect(fsMock.read).toHaveBeenCalledWith('scores.json'); + expect(filteredScores()).toEqual([mockScore]); + }); + }); + + it('should log an error if loading fails',function() { + fsMock.read.andReturn(Q.reject('read err')); + return $scores.load().then(function() { + expect(logMock).toHaveBeenCalledWith('scores read error','read err'); + }); + }); + }); + + describe('remove',function() { + it('should remove the provided index', function() { + expect(filteredScores()).toEqual([mockScore]); + $scores.remove(0); + expect(filteredScores()).toEqual([]); + }); + }); + + describe('add',function() { beforeEach(function() { $scores.clear(); expect(filteredScores()).toEqual([]); @@ -128,52 +181,20 @@ describe('ng-scores',function() { expect($scores.scores[0].score).toEqual(null); expect($scores.validationErrors.length).toEqual(1); }); - }); - - describe('loading',function() { - it('should load from scores.json',function() { - return $scores.load().then(function() { - expect(fsMock.read).toHaveBeenCalledWith('scores.json'); - expect(filteredScores()).toEqual([mockScore]); - }); + it('should store the edited date of a score',function() { + var tmp = angular.copy(mockScore); + tmp.edited = new Date(2015,1,7); + $scores.add(tmp); + expect($scores.scores[0].edited).toEqual('Sat Feb 07 2015 00:00:00 GMT+0100 (W. Europe Standard Time)'); }); }); - describe('clearing',function() { - it('should clear the scores',function() { - expect(filteredScores()).toEqual([mockScore]); + describe('update', function() { + beforeEach(function() { $scores.clear(); - expect(filteredScores()).toEqual([]); - }); - }); - - describe('saving',function() { - it('should write scores to scores.json',function() { - return $scores.save().then(function() { - expect(fsMock.write).toHaveBeenCalledWith( - 'scores.json', - { - version: 2, - scores: [rawMockScore], - sheets: [] - } - ); - }); - }); - }); - - describe('removing',function() { - it('should remove the provided index', function() { - expect(filteredScores()).toEqual([mockScore]); - $scores.remove(0); - expect(filteredScores()).toEqual([]); + $scores.add(mockScore); }); - }); - - describe('modification', function() { it('should mark modified scores', function() { - $scores.clear(); - $scores.add(mockScore); mockScore.score++; // Simply changing the added score shouldn't matter... expect($scores.scores[0].score).toEqual(150); @@ -185,14 +206,24 @@ describe('ng-scores',function() { expect($scores.scores[0].edited).toBeTruthy(); }); it('should accept numeric scores as strings',function() { - $scores.clear(); - $scores.add(mockScore); mockScore.score = "151"; $scores.update(0, mockScore); // Note: the 'accepted' score should really be a number, not a string expect($scores.scores[0].originalScore).toEqual(150); expect($scores.scores[0].score).toEqual(151); }); + it('should throw an error if a score out of range is edited',function() { + var f = function() { + $scores.update(-1,mockScore); + }; + expect(f).toThrow('unknown score index: -1'); + }); + it('should throw an error if a score out of range is edited',function() { + var f = function() { + $scores.update(1,mockScore); + }; + expect(f).toThrow('unknown score index: 1'); + }); }); describe('scoreboard', function() { @@ -316,7 +347,7 @@ describe('ng-scores',function() { ], true); $scores.scores.forEach(function(score) { expect(score.error).toBeInstanceOf($scores.InvalidScoreError); - }) + }); expect(board["test"].length).toEqual(0); expect($scores.validationErrors.length).toEqual(6); }); @@ -420,6 +451,38 @@ describe('ng-scores',function() { ); }); }); + + describe('error recovery',function() { + it('should continue with no sheets when a 404 is returned',function() { + fsMock.list.andReturn(Q.reject({status:404})); + $scores.save = jasmine.createSpy('save'); + return $scores.pollSheets().then(function() { + expect(fsMock.write).not.toHaveBeenCalled(); + expect($scores.save).not.toHaveBeenCalled(); + }); + }); + + it('throw an error if an http error is received',function() { + fsMock.list.andReturn(Q.reject({status:500,responseText:'server error',statusText:'foo'})); + return $scores.pollSheets().catch(function(err) { + expect(err.message).toEqual('error 500 (foo): server error'); + }); + }); + + it('should rethrow the error if something just goes wrong',function() { + fsMock.list.andReturn(Q.reject(new Error('squeek'))); + return $scores.pollSheets().catch(function(err) { + expect(err.message).toEqual('squeek'); + }); + }); + + it('should throw an unknown error if strange stuff is returned',function() { + fsMock.list.andReturn(Q.reject('darn')); + return $scores.pollSheets().catch(function(err) { + expect(err.message).toEqual('unknown error: darn'); + }); + }); + }); }); }); From 6efb5e28fc31a7e17bcff0d47636719af1c51e67 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Thu, 25 Dec 2014 16:56:28 +0100 Subject: [PATCH 25/76] fix travis tests (shifted date) --- spec/services/ng-scoresSpec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/services/ng-scoresSpec.js b/spec/services/ng-scoresSpec.js index 0e1116d5..f1c90c07 100644 --- a/spec/services/ng-scoresSpec.js +++ b/spec/services/ng-scoresSpec.js @@ -181,11 +181,11 @@ describe('ng-scores',function() { expect($scores.scores[0].score).toEqual(null); expect($scores.validationErrors.length).toEqual(1); }); - it('should store the edited date of a score',function() { + it('should store the edited date of a score as string',function() { var tmp = angular.copy(mockScore); tmp.edited = new Date(2015,1,7); $scores.add(tmp); - expect($scores.scores[0].edited).toEqual('Sat Feb 07 2015 00:00:00 GMT+0100 (W. Europe Standard Time)'); + expect(typeof $scores.scores[0].edited).toBe('string'); }); }); From f6fcd55478b9c81c801a7602b818ddbb705b3e9f Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sun, 28 Dec 2014 13:07:34 +0100 Subject: [PATCH 26/76] fix getting fallbackchallenge --- src/js/services/ng-challenge.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/services/ng-challenge.js b/src/js/services/ng-challenge.js index ddb5c550..c1166d01 100644 --- a/src/js/services/ng-challenge.js +++ b/src/js/services/ng-challenge.js @@ -34,7 +34,7 @@ define('services/ng-challenge',[ }).fail(function() { //temp: get from remote service return $settings.init().then(function(settings) { - var url = (settings.host||'')+'/'+fallBackChallenge; + var url = (settings.host||'')+fallBackChallenge; return $http.get(url,{ transformResponse: function(d) {return d;} }); From 8a2f1fad0bd52fd9183b7f3652589dccccaf67de Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sun, 28 Dec 2014 13:43:46 +0100 Subject: [PATCH 27/76] Directly close the team and round dialog after choosing an option --- src/js/views/scoresheet.js | 11 ++--------- src/views/scoresheet.html | 8 -------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/js/views/scoresheet.js b/src/js/views/scoresheet.js index b668ee03..d9c1d8a2 100644 --- a/src/js/views/scoresheet.js +++ b/src/js/views/scoresheet.js @@ -304,9 +304,6 @@ define('views/scoresheet',[ $scope.selectTeamPop = function(team) { $scope.team = team; - }; - - $scope.ok = function () { $modalInstance.close($scope.team); }; @@ -323,6 +320,8 @@ define('views/scoresheet',[ $scope.selectRoundPop = function(stage, round) { $scope.stage = stage; $scope.round = round; + log("after OK: " + $scope.round); + $modalInstance.close({"stage": $scope.stage, "round": $scope.round}); }; // function that should be in the lib: @@ -330,12 +329,6 @@ define('views/scoresheet',[ return new Array(num); }; - $scope.ok = function () { - log("after OK: " + $scope.round); - $modalInstance.close({"stage": $scope.stage, "round": $scope.round}); - - }; - $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; diff --git a/src/views/scoresheet.html b/src/views/scoresheet.html index e0f10873..5334f074 100644 --- a/src/views/scoresheet.html +++ b/src/views/scoresheet.html @@ -146,10 +146,6 @@ - From ee66b9ea91e28a3bd77a33eb5fcf9ff1ae46b6ba Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sun, 28 Dec 2014 13:52:29 +0100 Subject: [PATCH 28/76] Add cancel button to team import --- spec/views/teamsSpec.js | 13 +++++++++++++ src/js/views/teams.js | 4 ++++ src/views/teams.html | 1 + 3 files changed, 18 insertions(+) diff --git a/spec/views/teamsSpec.js b/spec/views/teamsSpec.js index f3e6445b..31a0cb76 100644 --- a/spec/views/teamsSpec.js +++ b/spec/views/teamsSpec.js @@ -138,6 +138,19 @@ describe('teams', function() { }); }); + describe('cancelImport',function() { + beforeEach(function() { + $scope.importMode = true; + $scope.importLines = [[42,'FooBars']]; + $scope.importNumberColumn = 1; + $scope.importNameColumn = 2; + }); + it('should set import mode to false',function() { + $scope.cancelImport(); + expect($scope.importMode).toBe(false); + }); + }); + describe('parsing data',function() { it('should populate importLines',function() { $scope.importLines = []; diff --git a/src/js/views/teams.js b/src/js/views/teams.js index 45e952d1..947912dc 100644 --- a/src/js/views/teams.js +++ b/src/js/views/teams.js @@ -79,6 +79,10 @@ define('views/teams',[ }); }; + $scope.cancelImport = function() { + $scope.importMode = false; + }; + $scope.$watch('importRaw',function(data) { parseData($scope.importRaw); }); diff --git a/src/views/teams.html b/src/views/teams.html index 167d7e01..6987b761 100644 --- a/src/views/teams.html +++ b/src/views/teams.html @@ -32,6 +32,7 @@ +
From efbce185a172d20ada8252c3a09b01c21e3b0475 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sun, 28 Dec 2014 14:54:15 +0100 Subject: [PATCH 29/76] Use handshakeservice and simple css for dialogs, saves a lot of dependency code, simpler interface --- src/css/dialog.css | 34 +++++++ src/css/main.css | 3 +- src/js/services/ng-handshake.js | 42 ++++++++ src/js/views/scoresheet.js | 173 +++++++++++--------------------- src/views/scoresheet.html | 139 +++++++++++++------------ 5 files changed, 207 insertions(+), 184 deletions(-) create mode 100644 src/css/dialog.css create mode 100644 src/js/services/ng-handshake.js diff --git a/src/css/dialog.css b/src/css/dialog.css new file mode 100644 index 00000000..23d75155 --- /dev/null +++ b/src/css/dialog.css @@ -0,0 +1,34 @@ +.fll-dialog { + position: fixed; + z-index: 10; + left: 50%; + top: 50%; + width: 600px; + height: 400px; + margin-left: -300px; + margin-top: -200px; + border: 1px solid #999; + border: 1px solid rgba(0,0,0,0.3); + background-color: white; + border-radius: 6px; + box-shadow: 0 3px 7px rgba(0,0,0,0.3); + overflow: hidden; +} + +.fll-dialog h1 { + margin: 0; + line-height: 30px; + font-family: inherit; + font-weight: bold; + font-size: 24.5px; + color: inherit; + text-rendering: optimizelegibility; + padding: 9px 15px; + border-bottom: 1px solid #eee; + height: 30px; +} + +.fll-dialog section { + overflow: auto; + height: 350px; +} diff --git a/src/css/main.css b/src/css/main.css index c40940ae..81e178ef 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -3,7 +3,8 @@ @import url('scoresheet.css'); @import url('teams.css'); @import url('spinner.css'); +@import url('dialog.css'); table.table td.clearCell, table.table th.clearCell { background-color: #ffffff !important; -} \ No newline at end of file +} diff --git a/src/js/services/ng-handshake.js b/src/js/services/ng-handshake.js new file mode 100644 index 00000000..ff08755d --- /dev/null +++ b/src/js/services/ng-handshake.js @@ -0,0 +1,42 @@ +/** + * handshake service + * + * $emit method starts the handshake, returns a promise to be + * resolved when the handshake is done + * + * $on method listens to a handshake, return a value or a new promise to + * resolve the handshake + * + * + */ +define('services/ng-handshake',[ + 'services/ng-services' +],function(module) { + return module.factory('$handshake',[ + '$rootScope','$q', + function($rootScope,$q) { + return { + $emit: function() { + var def = $q.defer(); + var args = $.makeArray(arguments); + args.splice(1,0,def); + args[0] = 'handShake.'+args[0]; + $rootScope.$emit.apply($rootScope,args); + return def.promise; + }, + $on: function(name,cb) { + return $rootScope.$on('handShake.'+name,function(e) { + var args = $.makeArray(arguments); + var def = args.splice(1,1)[0]; + var res = cb.apply(null,args); + $q.when(res).then(def.resolve,def.reject); + return res; + }); + }, + defer: function() { + return $q.defer(); + } + }; + } + ]); +}); diff --git a/src/js/views/scoresheet.js b/src/js/views/scoresheet.js index d9c1d8a2..d27a1887 100644 --- a/src/js/views/scoresheet.js +++ b/src/js/views/scoresheet.js @@ -7,6 +7,7 @@ define('views/scoresheet',[ 'services/ng-teams', 'services/ng-stages', 'services/ng-settings', + 'services/ng-handshake', 'directives/sigpad', 'directives/spinner', 'angular' @@ -14,8 +15,8 @@ define('views/scoresheet',[ var moduleName = 'scoresheet'; return angular.module(moduleName, []).controller(moduleName + 'Ctrl', [ - '$scope','$fs','$stages','$settings','$modal','$challenge','$window','$q','$teams', - function($scope,$fs,$stages,$settings,$modal,$challenge,$window,$q,$teams) { + '$scope','$fs','$stages','$settings','$challenge','$window','$q','$teams','$handshake', + function($scope,$fs,$stages,$settings,$challenge,$window,$q,$teams,$handshake) { log('init scoresheet ctrl'); // Set up defaults @@ -191,146 +192,94 @@ define('views/scoresheet',[ }); }; - /* Methods used by Modal windows */ - $scope.chooseTeam = function(team) { - $scope.team = team; - }; - - $scope.$root.$on('chooseTeam',function(e,team) { - $scope.chooseTeam(team); - }); - - $scope.chooseStage = function(stage) { - $scope.stage = stage; - }; - - $scope.$root.$on('chooseStage',function(e,stage) { - $scope.chooseStage(stage); - }); - - $scope.chooseRound = function(round) { - $scope.round = round; - }; - - $scope.$root.$on('chooseRound',function(e,round) { - $scope.chooseRound(round); - }); - $scope.openDescriptionModal = function (size, mission) { - - var modalInstance = $modal.open({ - templateUrl: 'descriptionModalContent.html', - controller: 'DescriptionModalInstanceCtrl', - size: size, - resolve: { - mission: function () { - return mission; - } - } - }); - - modalInstance.result.then(function (selectedItem) { - $scope.selected = selectedItem; - }, function () { - log('Description dismissed at: ' + new Date()); - }); - }; - + $handshake.$emit('showDescription',mission); + }; $scope.openTeamModal = function (size, teams) { - - var modalInstance = $modal.open({ - - - templateUrl: 'teamModalContent.html', - controller: 'TeamModalInstanceCtrl', - size: size, - resolve: { - teams: function () { - return teams; + $handshake.$emit('chooseTeam',teams).then(function(result) { + if (result) { + $scope.team = result.team; } - } - }); - - modalInstance.result.then(function (selectedTeam) { - $scope.$root.$emit('chooseTeam',selectedTeam); - }, function () { - log('Team select dismissed at: ' + new Date()); }); }; $scope.openRoundModal = function (size, stages) { - - var modalInstance = $modal.open({ - - templateUrl: 'roundModalContent.html', - controller: 'RoundModalInstanceCtrl', - size: size, - resolve: { - stages: function () { - return stages; + $handshake.$emit('chooseRound',stages).then(function(result) { + if (result) { + $scope.stage = result.stage; + $scope.round = result.round; } - } - }); - - modalInstance.result.then(function (result) { - $scope.$root.$emit('chooseStage',result.stage); - $scope.$root.$emit('chooseRound',result.round); - }, function () { - log('Round select dismissed at: ' + new Date()); }); }; } - ]).controller('DescriptionModalInstanceCtrl',[ - '$scope', '$modalInstance', 'mission', - function ($scope, $modalInstance, mission) { - - $scope.mission = mission; + ]).controller('DescriptionDialogController',[ + '$scope', '$handshake', + function ($scope, $handshake) { + var defer; + + $handshake.$on('showDescription',function(e,mission) { + $scope.mission = mission; + $scope.dialogVisible = true; + }); - $scope.ok = function () { - $modalInstance.close(); - }; + $scope.ok = function () { + $scope.dialogVisible = false; + }; - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); - }; + $scope.cancel = function () { + $scope.dialogVisible = false; + }; } - ]).controller('TeamModalInstanceCtrl',[ - '$scope', '$modalInstance', 'teams', - function ($scope, $modalInstance, teams) { - - $scope.teams = teams; + ]).controller('TeamDialogController',[ + '$scope', '$handshake', + function ($scope, $handshake) { + var defer; + + $handshake.$on('chooseTeam',function(e,teams) { + $scope.teams = teams; + $scope.dialogVisible = true; + defer = $handshake.defer(); + return defer.promise; + }); $scope.selectTeamPop = function(team) { - $scope.team = team; - $modalInstance.close($scope.team); + $scope.dialogVisible = false; + defer.resolve({team:team}); }; $scope.cancel = function () { - $modalInstance.dismiss('cancel'); + $scope.dialogVisible = false; + defer.resolve(); }; } - ]).controller('RoundModalInstanceCtrl',[ - '$scope', '$modalInstance', 'stages', - function ($scope, $modalInstance, stages) { - - $scope.stages = stages; - - $scope.selectRoundPop = function(stage, round) { - $scope.stage = stage; - $scope.round = round; - log("after OK: " + $scope.round); - $modalInstance.close({"stage": $scope.stage, "round": $scope.round}); - }; + ]).controller('RoundDialogController',[ + '$scope', '$handshake', + function ($scope, $handshake) { + var defer; + + $handshake.$on('chooseRound',function(e,stages) { + $scope.stages = stages; + $scope.dialogVisible = true; + defer = $handshake.defer(); + return defer.promise; + }); // function that should be in the lib: $scope.getNumber = function(num) { return new Array(num); }; + $scope.selectRoundPop = function(stage, round) { + log("after OK: " + $scope.round); + $scope.dialogVisible = false; + defer.resolve({stage:stage, round:round}); + }; + $scope.cancel = function () { - $modalInstance.dismiss('cancel'); + $scope.dialogVisible = false; + defer.resolve(); }; } ]); diff --git a/src/views/scoresheet.html b/src/views/scoresheet.html index 5334f074..0f2ddedd 100644 --- a/src/views/scoresheet.html +++ b/src/views/scoresheet.html @@ -1,5 +1,5 @@ -
-
+
+

{{errorMessage}} @@ -37,19 +37,7 @@

Team & round

-
- - -
-
+

{{mission.title}} @@ -120,63 +108,72 @@

- - - + + + + +
+
+
+

+ {{mission.title}} + +

+
+ +
+
From 2b360f995ab973b8195e138b28d22e334ce49c7e Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sun, 28 Dec 2014 15:13:38 +0100 Subject: [PATCH 30/76] Add styling for dialogs on small screens --- src/css/dialog.css | 18 ++++++++++++++++++ src/css/elements.css | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/css/dialog.css b/src/css/dialog.css index 23d75155..67e0230c 100644 --- a/src/css/dialog.css +++ b/src/css/dialog.css @@ -31,4 +31,22 @@ .fll-dialog section { overflow: auto; height: 350px; + position: absolute; + top: 48px; + width: 100%; + bottom: 0px; + left: 0px; +} + + +/* small window dialog overrides */ +.smallWindow .fll-dialog { + left: 0; + top: 0; + width: 100%; + height: 100%; + margin-left: 0; + margin-top: 0; + position: absolute; + border: none; } diff --git a/src/css/elements.css b/src/css/elements.css index 70ce1a53..9fe7823e 100644 --- a/src/css/elements.css +++ b/src/css/elements.css @@ -84,6 +84,7 @@ table { -webkit-overflow-scrolling: touch; overflow-scrolling: touch; padding-bottom: 40px; + position: relative; } .viewMain.teams { transform: translateX(0); @@ -159,7 +160,7 @@ table { } .btn-enum { - + } #teams .table-teams { From c994c716ddf87ca50288d61fce14b64ca0945a80 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sun, 28 Dec 2014 15:13:46 +0100 Subject: [PATCH 31/76] fix tests --- spec/views/scoresheetSpec.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/spec/views/scoresheetSpec.js b/spec/views/scoresheetSpec.js index ac5aefc0..0a8e2ca7 100644 --- a/spec/views/scoresheetSpec.js +++ b/spec/views/scoresheetSpec.js @@ -23,7 +23,7 @@ describe('scoresheet',function() { '$fs': fsMock, '$settings': settingsMock, '$stages': {}, - '$modal': {}, + '$handshake': {}, '$teams': {}, '$challenge': challengeMock, '$window': { @@ -48,13 +48,6 @@ describe('scoresheet',function() { }); }); - describe('chooseTeam', function() { - it('should set the team on the scope', function() { - $scope.chooseTeam(dummyTeam); - expect($scope.team).toBe(dummyTeam); - }); - }); - describe('discard', function() { it('should discard form', function() { $scope.signature = "dummy"; From 15c2d51f089e6b3749f3fbea62dd516be17649f3 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Sun, 28 Dec 2014 15:50:28 +0100 Subject: [PATCH 32/76] Extracted dialog controllers, added tests --- karma.conf.js | 1 + .../DescriptionDialogControllerSpec.js | 45 +++++++++++ spec/controllers/RoundDialogControllerSpec.js | 60 ++++++++++++++ spec/controllers/TeamControllerSpec.js | 51 ++++++++++++ spec/mocks/handshakeMock.js | 26 +++++++ spec/views/scoresheetSpec.js | 8 +- .../DescriptionDialogController.js | 26 +++++++ src/js/controllers/RoundDialogController.js | 37 +++++++++ src/js/controllers/TeamDialogController.js | 30 +++++++ src/js/views/scoresheet.js | 78 +++---------------- 10 files changed, 292 insertions(+), 70 deletions(-) create mode 100644 spec/controllers/DescriptionDialogControllerSpec.js create mode 100644 spec/controllers/RoundDialogControllerSpec.js create mode 100644 spec/controllers/TeamControllerSpec.js create mode 100644 spec/mocks/handshakeMock.js create mode 100644 src/js/controllers/DescriptionDialogController.js create mode 100644 src/js/controllers/RoundDialogController.js create mode 100644 src/js/controllers/TeamDialogController.js diff --git a/karma.conf.js b/karma.conf.js index 94694f65..f6d4a0bc 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -24,6 +24,7 @@ module.exports = function(config) { 'src/js/services/*.js', 'src/js/views/*.js', 'src/js/filters/*.js', + 'src/js/controllers/*.js', 'spec/mocks/*.js', 'spec/**/*Spec.js' ], diff --git a/spec/controllers/DescriptionDialogControllerSpec.js b/spec/controllers/DescriptionDialogControllerSpec.js new file mode 100644 index 00000000..75122b99 --- /dev/null +++ b/spec/controllers/DescriptionDialogControllerSpec.js @@ -0,0 +1,45 @@ +describe('DescriptionDialogController',function() { + + var module = factory('controllers/DescriptionDialogController',{ + // 'services/log': logMock, + }); + + var $scope, controller, handshakeMock; + + beforeEach(function() { + angular.mock.module(module.name); + angular.mock.inject(function($controller,$rootScope,$q) { + $scope = $rootScope.$new(); + handshakeMock = createHandshakeMock(); + controller = $controller('DescriptionDialogController', { + '$scope': $scope, + '$handshake': handshakeMock + }); + }); + }); + + describe('handshake receive',function() { + it('should set the mission and show the dialog',function() { + var mission = {}; + handshakeMock.fire('showDescription',{},mission); + expect($scope.mission).toEqual(mission); + expect($scope.dialogVisible).toBe(true); + }); + }); + + describe('ok',function() { + it('should hide the dialog',function() { + $scope.dialogVisible = true; + $scope.ok(); + expect($scope.dialogVisible).toBe(false); + }); + }); + + describe('cancel',function() { + it('should hide the dialog',function() { + $scope.dialogVisible = true; + $scope.cancel(); + expect($scope.dialogVisible).toBe(false); + }); + }); +}); diff --git a/spec/controllers/RoundDialogControllerSpec.js b/spec/controllers/RoundDialogControllerSpec.js new file mode 100644 index 00000000..faf9f70f --- /dev/null +++ b/spec/controllers/RoundDialogControllerSpec.js @@ -0,0 +1,60 @@ +describe('RoundDialogController',function() { + + var module = factory('controllers/RoundDialogController',{ + 'services/log': logMock, + }); + + var $scope, controller, handshakeMock; + + beforeEach(function() { + angular.mock.module(module.name); + angular.mock.inject(function($controller,$rootScope,$q) { + $scope = $rootScope.$new(); + handshakeMock = createHandshakeMock($q); + controller = $controller('RoundDialogController', { + '$scope': $scope, + '$handshake': handshakeMock + }); + }); + }); + + describe('handshake receive',function() { + it('should set the mission and show the dialog',function() { + var stages = []; + handshakeMock.fire('chooseRound',{},stages); + expect($scope.stages).toEqual(stages); + expect($scope.dialogVisible).toBe(true); + }); + }); + + describe('getNumber',function() { + it('should return an array with the specified length',function() { + var a = $scope.getNumber(2); + expect(a.length).toBe(2); + expect(a instanceof Array).toBe(true); + }); + }); + + describe('ok',function() { + it('should hide the dialog',function() { + handshakeMock.fire('chooseRound',{},[]); + $scope.dialogVisible = true; + $scope.selectRoundPop('foo','bar'); + expect($scope.dialogVisible).toBe(false); + expect(handshakeMock.getPromise().resolve).toHaveBeenCalledWith({ + stage: 'foo', + round: 'bar' + }); + }); + }); + + describe('cancel',function() { + it('should hide the dialog',function() { + handshakeMock.fire('chooseRound',{},[]); + $scope.dialogVisible = true; + $scope.cancel(); + expect($scope.dialogVisible).toBe(false); + expect(handshakeMock.getPromise().resolve).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/controllers/TeamControllerSpec.js b/spec/controllers/TeamControllerSpec.js new file mode 100644 index 00000000..3fd6e994 --- /dev/null +++ b/spec/controllers/TeamControllerSpec.js @@ -0,0 +1,51 @@ +describe('TeamDialogController',function() { + + var module = factory('controllers/TeamDialogController',{ + 'services/log': logMock, + }); + + var $scope, controller, handshakeMock; + + beforeEach(function() { + angular.mock.module(module.name); + angular.mock.inject(function($controller,$rootScope,$q) { + $scope = $rootScope.$new(); + handshakeMock = createHandshakeMock($q); + controller = $controller('TeamDialogController', { + '$scope': $scope, + '$handshake': handshakeMock + }); + }); + }); + + describe('handshake receive',function() { + it('should set the mission and show the dialog',function() { + var teams = []; + handshakeMock.fire('chooseTeam',{},teams); + expect($scope.teams).toEqual(teams); + expect($scope.dialogVisible).toBe(true); + }); + }); + + describe('selectTeamPop ',function() { + it('should hide the dialog',function() { + handshakeMock.fire('chooseTeam',{},[]); + $scope.dialogVisible = true; + $scope.selectTeamPop('foo'); + expect($scope.dialogVisible).toBe(false); + expect(handshakeMock.getPromise().resolve).toHaveBeenCalledWith({ + team: 'foo', + }); + }); + }); + + describe('cancel',function() { + it('should hide the dialog',function() { + handshakeMock.fire('chooseTeam',{},[]); + $scope.dialogVisible = true; + $scope.cancel(); + expect($scope.dialogVisible).toBe(false); + expect(handshakeMock.getPromise().resolve).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/mocks/handshakeMock.js b/spec/mocks/handshakeMock.js new file mode 100644 index 00000000..0e38bdb1 --- /dev/null +++ b/spec/mocks/handshakeMock.js @@ -0,0 +1,26 @@ +var createHandshakeMock = function($q) { + var handlers = {}; + var promise; + return { + $on: jasmine.createSpy('handshake.on').andCallFake(function(e,cb) { + handlers[e] = cb; + }), + $emit: jasmine.createSpy('handshake.emit'), + defer: jasmine.createSpy('handshake.defer').andCallFake(function() { + promise = { + resolve: jasmine.createSpy('promise.resolve'), + reject: jasmine.createSpy('promise.reject') + }; + return promise; + }), + fire: function(e) { + if (handlers[e]) { + var args = $.makeArray(arguments); + handlers[e].apply(null,args.slice(1)); + } + }, + getPromise: function() { + return promise; + } + }; +}; diff --git a/spec/views/scoresheetSpec.js b/spec/views/scoresheetSpec.js index 0a8e2ca7..f890e193 100644 --- a/spec/views/scoresheetSpec.js +++ b/spec/views/scoresheetSpec.js @@ -1,7 +1,10 @@ describe('scoresheet',function() { var module = factory('views/scoresheet',{ - 'services/log': logMock + 'services/log': logMock, + 'controllers/DescriptionDialogController': factory('controllers/DescriptionDialogController'), + 'controllers/TeamDialogController': factory('controllers/TeamDialogController'), + 'controllers/RoundDialogController': factory('controllers/RoundDialogController') }); var $scope, controller; @@ -14,6 +17,9 @@ describe('scoresheet',function() { var settingsMock; beforeEach(function() { + angular.mock.module('DescriptionDialog'); + angular.mock.module('TeamDialog'); + angular.mock.module('RoundDialog'); angular.mock.module(module.name); angular.mock.inject(function($controller,$rootScope,$q) { settingsMock = createSettingsMock($q,{}); diff --git a/src/js/controllers/DescriptionDialogController.js b/src/js/controllers/DescriptionDialogController.js new file mode 100644 index 00000000..e245cfc1 --- /dev/null +++ b/src/js/controllers/DescriptionDialogController.js @@ -0,0 +1,26 @@ +define('controllers/DescriptionDialogController',[ + 'services/ng-handshake', + 'angular' +], function() { + var moduleName = 'DescriptionDialog'; + + return angular.module(moduleName, []).controller('DescriptionDialogController',[ + '$scope', '$handshake', + function ($scope, $handshake) { + var defer; + + $handshake.$on('showDescription',function(e,mission) { + $scope.mission = mission; + $scope.dialogVisible = true; + }); + + $scope.ok = function () { + $scope.dialogVisible = false; + }; + + $scope.cancel = function () { + $scope.dialogVisible = false; + }; + } + ]); +}); diff --git a/src/js/controllers/RoundDialogController.js b/src/js/controllers/RoundDialogController.js new file mode 100644 index 00000000..d047f1bc --- /dev/null +++ b/src/js/controllers/RoundDialogController.js @@ -0,0 +1,37 @@ +define('controllers/RoundDialogController',[ + 'services/log', + 'services/ng-handshake', + 'angular' +], function(log) { + var moduleName = 'RoundDialog'; + + return angular.module(moduleName, []).controller('RoundDialogController',[ + '$scope', '$handshake', + function ($scope, $handshake) { + var defer; + + $handshake.$on('chooseRound',function(e,stages) { + $scope.stages = stages; + $scope.dialogVisible = true; + defer = $handshake.defer(); + return defer.promise; + }); + + // function that should be in the lib: + $scope.getNumber = function(num) { + return new Array(num); + }; + + $scope.selectRoundPop = function(stage, round) { + log("after OK: " + $scope.round); + $scope.dialogVisible = false; + defer.resolve({stage:stage, round:round}); + }; + + $scope.cancel = function () { + $scope.dialogVisible = false; + defer.resolve(); + }; + } + ]); +}); diff --git a/src/js/controllers/TeamDialogController.js b/src/js/controllers/TeamDialogController.js new file mode 100644 index 00000000..3e69c91f --- /dev/null +++ b/src/js/controllers/TeamDialogController.js @@ -0,0 +1,30 @@ +define('controllers/TeamDialogController',[ + 'services/ng-handshake', + 'angular' +], function() { + var moduleName = 'TeamDialog'; + + return angular.module(moduleName, []).controller('TeamDialogController',[ + '$scope', '$handshake', + function ($scope, $handshake) { + var defer; + + $handshake.$on('chooseTeam',function(e,teams) { + $scope.teams = teams; + $scope.dialogVisible = true; + defer = $handshake.defer(); + return defer.promise; + }); + + $scope.selectTeamPop = function(team) { + $scope.dialogVisible = false; + defer.resolve({team:team}); + }; + + $scope.cancel = function () { + $scope.dialogVisible = false; + defer.resolve(); + }; + } + ]); +}); diff --git a/src/js/views/scoresheet.js b/src/js/views/scoresheet.js index d27a1887..42efafd4 100644 --- a/src/js/views/scoresheet.js +++ b/src/js/views/scoresheet.js @@ -10,11 +10,19 @@ define('views/scoresheet',[ 'services/ng-handshake', 'directives/sigpad', 'directives/spinner', + 'controllers/DescriptionDialogController', + 'controllers/TeamDialogController', + 'controllers/RoundDialogController', 'angular' ], function(log, fs) { var moduleName = 'scoresheet'; + var module = angular.module(moduleName, [ + 'DescriptionDialog', + 'TeamDialog', + 'RoundDialog' + ]); - return angular.module(moduleName, []).controller(moduleName + 'Ctrl', [ + return module.controller(moduleName + 'Ctrl', [ '$scope','$fs','$stages','$settings','$challenge','$window','$q','$teams','$handshake', function($scope,$fs,$stages,$settings,$challenge,$window,$q,$teams,$handshake) { log('init scoresheet ctrl'); @@ -214,73 +222,5 @@ define('views/scoresheet',[ }; } - ]).controller('DescriptionDialogController',[ - '$scope', '$handshake', - function ($scope, $handshake) { - var defer; - - $handshake.$on('showDescription',function(e,mission) { - $scope.mission = mission; - $scope.dialogVisible = true; - }); - - $scope.ok = function () { - $scope.dialogVisible = false; - }; - - $scope.cancel = function () { - $scope.dialogVisible = false; - }; - } - ]).controller('TeamDialogController',[ - '$scope', '$handshake', - function ($scope, $handshake) { - var defer; - - $handshake.$on('chooseTeam',function(e,teams) { - $scope.teams = teams; - $scope.dialogVisible = true; - defer = $handshake.defer(); - return defer.promise; - }); - - $scope.selectTeamPop = function(team) { - $scope.dialogVisible = false; - defer.resolve({team:team}); - }; - - $scope.cancel = function () { - $scope.dialogVisible = false; - defer.resolve(); - }; - } - ]).controller('RoundDialogController',[ - '$scope', '$handshake', - function ($scope, $handshake) { - var defer; - - $handshake.$on('chooseRound',function(e,stages) { - $scope.stages = stages; - $scope.dialogVisible = true; - defer = $handshake.defer(); - return defer.promise; - }); - - // function that should be in the lib: - $scope.getNumber = function(num) { - return new Array(num); - }; - - $scope.selectRoundPop = function(stage, round) { - log("after OK: " + $scope.round); - $scope.dialogVisible = false; - defer.resolve({stage:stage, round:round}); - }; - - $scope.cancel = function () { - $scope.dialogVisible = false; - defer.resolve(); - }; - } ]); }); From 7f8b37826b24d44020e845dcb89ff90991e04fbd Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Mon, 29 Dec 2014 10:41:32 +0100 Subject: [PATCH 33/76] Added basic tests for dialog methods in scoresheet controller --- .../DescriptionDialogControllerSpec.js | 2 +- spec/mocks/handshakeMock.js | 2 +- spec/views/scoresheetSpec.js | 26 +++++++++++++++++-- src/js/views/scoresheet.js | 6 ++--- src/views/scoresheet.html | 10 +++---- 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/spec/controllers/DescriptionDialogControllerSpec.js b/spec/controllers/DescriptionDialogControllerSpec.js index 75122b99..e132e660 100644 --- a/spec/controllers/DescriptionDialogControllerSpec.js +++ b/spec/controllers/DescriptionDialogControllerSpec.js @@ -10,7 +10,7 @@ describe('DescriptionDialogController',function() { angular.mock.module(module.name); angular.mock.inject(function($controller,$rootScope,$q) { $scope = $rootScope.$new(); - handshakeMock = createHandshakeMock(); + handshakeMock = createHandshakeMock($q); controller = $controller('DescriptionDialogController', { '$scope': $scope, '$handshake': handshakeMock diff --git a/spec/mocks/handshakeMock.js b/spec/mocks/handshakeMock.js index 0e38bdb1..55d815a0 100644 --- a/spec/mocks/handshakeMock.js +++ b/spec/mocks/handshakeMock.js @@ -5,7 +5,7 @@ var createHandshakeMock = function($q) { $on: jasmine.createSpy('handshake.on').andCallFake(function(e,cb) { handlers[e] = cb; }), - $emit: jasmine.createSpy('handshake.emit'), + $emit: jasmine.createSpy('handshake.emit').andReturn($q.when()), defer: jasmine.createSpy('handshake.defer').andCallFake(function() { promise = { resolve: jasmine.createSpy('promise.resolve'), diff --git a/spec/views/scoresheetSpec.js b/spec/views/scoresheetSpec.js index f890e193..84f891da 100644 --- a/spec/views/scoresheetSpec.js +++ b/spec/views/scoresheetSpec.js @@ -14,7 +14,7 @@ describe('scoresheet',function() { }; var dummyStage = { id: "qualifying", name: "Voorrondes", rounds: 3 }; var fsMock = createFsMock({"settings.json": []}); - var settingsMock; + var settingsMock, handshakeMock; beforeEach(function() { angular.mock.module('DescriptionDialog'); @@ -23,13 +23,14 @@ describe('scoresheet',function() { angular.mock.module(module.name); angular.mock.inject(function($controller,$rootScope,$q) { settingsMock = createSettingsMock($q,{}); + handshakeMock = createHandshakeMock($q); $scope = $rootScope.$new(); controller = $controller('scoresheetCtrl', { '$scope': $scope, '$fs': fsMock, '$settings': settingsMock, '$stages': {}, - '$handshake': {}, + '$handshake': handshakeMock, '$teams': {}, '$challenge': challengeMock, '$window': { @@ -91,4 +92,25 @@ describe('scoresheet',function() { }); }); }); + + describe('openDesciptionModal',function() { + it('should emit a showDescription handshake',function() { + $scope.openDescriptionModal('foo'); + expect(handshakeMock.$emit).toHaveBeenCalledWith('showDescription','foo'); + }); + }); + + describe('openTeamModal',function() { + it('should emit a chooseTeam handshake',function() { + $scope.openTeamModal('foo'); + expect(handshakeMock.$emit).toHaveBeenCalledWith('chooseTeam','foo'); + }); + }); + + describe('openRoundModal',function() { + it('should emit a chooseRound handshake',function() { + $scope.openRoundModal('foo'); + expect(handshakeMock.$emit).toHaveBeenCalledWith('chooseRound','foo'); + }); + }); }) diff --git a/src/js/views/scoresheet.js b/src/js/views/scoresheet.js index 42efafd4..916bb78a 100644 --- a/src/js/views/scoresheet.js +++ b/src/js/views/scoresheet.js @@ -200,11 +200,11 @@ define('views/scoresheet',[ }); }; - $scope.openDescriptionModal = function (size, mission) { + $scope.openDescriptionModal = function (mission) { $handshake.$emit('showDescription',mission); }; - $scope.openTeamModal = function (size, teams) { + $scope.openTeamModal = function (teams) { $handshake.$emit('chooseTeam',teams).then(function(result) { if (result) { $scope.team = result.team; @@ -212,7 +212,7 @@ define('views/scoresheet',[ }); }; - $scope.openRoundModal = function (size, stages) { + $scope.openRoundModal = function (stages) { $handshake.$emit('chooseRound',stages).then(function(result) { if (result) { $scope.stage = result.stage; diff --git a/src/views/scoresheet.html b/src/views/scoresheet.html index 0f2ddedd..fcaa7d44 100644 --- a/src/views/scoresheet.html +++ b/src/views/scoresheet.html @@ -12,13 +12,13 @@

Team & round

@@ -37,7 +37,7 @@

Team & round

-
+

{{mission.title}} @@ -75,13 +75,13 @@

Team & round

- + ({{team.number}}) {{team.name}}
- + {{stage.name}}: {{round}}
From 59f986786455fba91e37158e30470e5c9ef4327b Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Mon, 29 Dec 2014 10:53:12 +0100 Subject: [PATCH 34/76] extracted dialogs to separate view file --- src/css/dialog.css | 7 ++-- src/views/dialogs.html | 68 +++++++++++++++++++++++++++++++++++ src/views/main.html | 1 + src/views/mainScoring.html | 3 +- src/views/scoresheet.html | 73 ++------------------------------------ 5 files changed, 76 insertions(+), 76 deletions(-) create mode 100644 src/views/dialogs.html diff --git a/src/css/dialog.css b/src/css/dialog.css index 67e0230c..584bebdc 100644 --- a/src/css/dialog.css +++ b/src/css/dialog.css @@ -1,6 +1,6 @@ .fll-dialog { position: fixed; - z-index: 10; + z-index: 2000; left: 50%; top: 50%; width: 600px; @@ -30,12 +30,11 @@ .fll-dialog section { overflow: auto; - height: 350px; position: absolute; top: 48px; width: 100%; - bottom: 0px; - left: 0px; + bottom: 0; + left: 0; } diff --git a/src/views/dialogs.html b/src/views/dialogs.html new file mode 100644 index 00000000..4c789aba --- /dev/null +++ b/src/views/dialogs.html @@ -0,0 +1,68 @@ +
+

+ Select a team + +

+
+
- + ({{team.number}}) {{team.name}}
- + {{stage.name}}: {{round}}
+ + + + + + + + + + + + +
#Name

{{team.number}}

{{team.name}} +
+ {{team.affiliation}}, {{team.cityState}} +
+ +
+ +
+

+ Select a round + +

+
+ + + + + + + +
+

{{stage.name}}

+
+
+
+ +
+
+
+
+
+ +
+

+ {{mission.title}} + +

+
+ +
+
diff --git a/src/views/main.html b/src/views/main.html index dbdad435..94d08b89 100644 --- a/src/views/main.html +++ b/src/views/main.html @@ -16,5 +16,6 @@ ng-class="'view-'+page" >
+
diff --git a/src/views/mainScoring.html b/src/views/mainScoring.html index 22227dff..65441ca7 100644 --- a/src/views/mainScoring.html +++ b/src/views/mainScoring.html @@ -13,4 +13,5 @@ ng-class="'view-'+page" > - \ No newline at end of file +
+ diff --git a/src/views/scoresheet.html b/src/views/scoresheet.html index fcaa7d44..67351b8d 100644 --- a/src/views/scoresheet.html +++ b/src/views/scoresheet.html @@ -1,5 +1,5 @@ -
-
+
+

{{errorMessage}} @@ -107,73 +107,4 @@

- -
-

- Select a team - -

-
- - - - - - - - - - - - - -
#Name

{{team.number}}

{{team.name}} -
- {{team.affiliation}}, {{team.cityState}} -
-
-
- -
-

- Select a round - -

-
- - - - - - - -
-

{{stage.name}}

-
-
-
- -
-
-
-
-
- -
-

- {{mission.title}} - -

-
- -
-
From 7e25093052d08141f1923d7015bafecbaa98591d Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Mon, 29 Dec 2014 11:14:39 +0100 Subject: [PATCH 35/76] Added shim to dialogs, step towards material design --- src/css/dialog.css | 11 +++- src/views/dialogs.html | 130 +++++++++++++++++++++-------------------- 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/src/css/dialog.css b/src/css/dialog.css index 584bebdc..460ddbd6 100644 --- a/src/css/dialog.css +++ b/src/css/dialog.css @@ -1,3 +1,12 @@ +.fll-dialog-shim { + position: fixed; + z-index: 1999; + left: 0; + top: 0; + bottom: 0; + right: 0; + background-color: rgba(0,0,0,0.6); +} .fll-dialog { position: fixed; z-index: 2000; @@ -11,7 +20,7 @@ border: 1px solid rgba(0,0,0,0.3); background-color: white; border-radius: 6px; - box-shadow: 0 3px 7px rgba(0,0,0,0.3); + box-shadow: 0 16px 48px rgba(0,0,0,0.6); overflow: hidden; } diff --git a/src/views/dialogs.html b/src/views/dialogs.html index 4c789aba..a8a52a54 100644 --- a/src/views/dialogs.html +++ b/src/views/dialogs.html @@ -1,68 +1,74 @@ -
-

- Select a team - -

-
- - - - - - - - - - - - - -
#Name

{{team.number}}

{{team.name}} -
- {{team.affiliation}}, {{team.cityState}} -
-
+
+
+

+ Select a team + +

+
+ + + + + + + + + + + + + +
#Name

{{team.number}}

{{team.name}} +
+ {{team.affiliation}}, {{team.cityState}} +
+
+
-
-

- Select a round - -

-
- - - - - + + +
-

{{stage.name}}

-
-
-
- +
+
+

+ Select a round + +

+
+ + + + + - - -
+

{{stage.name}}

+
+
+
+ +
- -
-
+
+
+
-
-

- {{mission.title}} - -

-
- -
+
+
+

+ {{mission.title}} + +

+
+ +
+
From a73013bf89859d0a9336035f4ec411d3152abd9e Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Mon, 29 Dec 2014 11:56:22 +0100 Subject: [PATCH 36/76] Recreated team import as a dialog --- ...lerSpec.js => TeamDialogControllerSpec.js} | 0 .../TeamImportDialogControllerSpec.js | 89 +++++++++++++++ spec/mocks/handshakeMock.js | 9 +- spec/views/teamsSpec.js | 103 ++++-------------- .../controllers/TeamImportDialogController.js | 68 ++++++++++++ src/js/views/teams.js | 71 +++--------- src/views/dialogs.html | 43 ++++++++ src/views/teams.html | 36 ------ 8 files changed, 247 insertions(+), 172 deletions(-) rename spec/controllers/{TeamControllerSpec.js => TeamDialogControllerSpec.js} (100%) create mode 100644 spec/controllers/TeamImportDialogControllerSpec.js create mode 100644 src/js/controllers/TeamImportDialogController.js diff --git a/spec/controllers/TeamControllerSpec.js b/spec/controllers/TeamDialogControllerSpec.js similarity index 100% rename from spec/controllers/TeamControllerSpec.js rename to spec/controllers/TeamDialogControllerSpec.js diff --git a/spec/controllers/TeamImportDialogControllerSpec.js b/spec/controllers/TeamImportDialogControllerSpec.js new file mode 100644 index 00000000..4806f9ec --- /dev/null +++ b/spec/controllers/TeamImportDialogControllerSpec.js @@ -0,0 +1,89 @@ +describe('TeamImportDialogController',function() { + + var module = factory('controllers/TeamImportDialogController',{ + 'services/log': logMock, + }); + + var $scope, controller, handshakeMock; + + beforeEach(function() { + angular.mock.module(module.name); + angular.mock.inject(function($controller,$rootScope,$q) { + $scope = $rootScope.$new(); + handshakeMock = createHandshakeMock($q); + controller = $controller('TeamImportDialogController', { + '$scope': $scope, + '$handshake': handshakeMock + }); + }); + }); + + describe('parsing data',function() { + it('should populate importLines',function() { + $scope.importLines = []; + $scope.importRaw = '42\tFooBar\n7\tQuxMoo'; + $scope.$digest(); + expect($scope.importLines).toEqual([ + ['42','FooBar'], + ['7','QuxMoo'] + ]); + expect($scope.importNumberExample).toEqual('42'); + expect($scope.importNameExample).toEqual('FooBar'); + }); + + it('should skip the first line if it is a header',function() { + $scope.importLines = []; + $scope.importRaw = 'Number\tName\n7\tQuxMoo'; + $scope.importHeader = true; + $scope.$digest(); + expect($scope.importLines).toEqual([ + ['7','QuxMoo'] + ]); + expect($scope.importNumberExample).toEqual('7'); + expect($scope.importNameExample).toEqual('QuxMoo'); + }); + + it('should not populate example lines if no data given',function() { + $scope.importLines = []; + $scope.importNumberExample = 'numberExample'; + $scope.importNameExample = 'nameExample'; + $scope.importRaw = ''; + $scope.$digest(); + expect($scope.importLines).toEqual([]); + expect($scope.importNumberExample).toEqual(''); + expect($scope.importNameExample).toEqual(''); + }); + }); + + describe('handshake receive',function() { + it('should set the mission and show the dialog',function() { + handshakeMock.fire('importTeams'); + expect($scope.dialogVisible).toBe(true); + }); + }); + + describe('ok ',function() { + it('should hide the dialog',function() { + handshakeMock.fire('importTeams',{},[]); + $scope.dialogVisible = true; + $scope.importLines = [[42,'foo']]; + $scope.importNumberColumn = 1; + $scope.importNameColumn = 2; + $scope.ok(); + expect($scope.dialogVisible).toBe(false); + expect(handshakeMock.getPromise().resolve).toHaveBeenCalledWith({ + teams: [{number:42,name:'foo'}], + }); + }); + }); + + describe('cancel',function() { + it('should hide the dialog',function() { + handshakeMock.fire('importTeams',{},[]); + $scope.dialogVisible = true; + $scope.cancel(); + expect($scope.dialogVisible).toBe(false); + expect(handshakeMock.getPromise().resolve).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/mocks/handshakeMock.js b/spec/mocks/handshakeMock.js index 55d815a0..ba32e83a 100644 --- a/spec/mocks/handshakeMock.js +++ b/spec/mocks/handshakeMock.js @@ -1,11 +1,14 @@ var createHandshakeMock = function($q) { var handlers = {}; var promise; + var result; return { $on: jasmine.createSpy('handshake.on').andCallFake(function(e,cb) { handlers[e] = cb; }), - $emit: jasmine.createSpy('handshake.emit').andReturn($q.when()), + $emit: jasmine.createSpy('handshake.emit').andCallFake(function() { + return $q.when(result) + }), defer: jasmine.createSpy('handshake.defer').andCallFake(function() { promise = { resolve: jasmine.createSpy('promise.resolve'), @@ -21,6 +24,10 @@ var createHandshakeMock = function($q) { }, getPromise: function() { return promise; + }, + //sets the response after the emit it resolved + respond: function(res) { + result = res; } }; }; diff --git a/spec/views/teamsSpec.js b/spec/views/teamsSpec.js index 31a0cb76..2dad71aa 100644 --- a/spec/views/teamsSpec.js +++ b/spec/views/teamsSpec.js @@ -1,10 +1,11 @@ describe('teams', function() { var module = factory('views/teams', { - 'services/log': logMock + 'services/log': logMock, + 'controllers/TeamImportDialogController': factory('controllers/TeamImportDialogController') }); - var $scope, controller, $httpBackend, $teams; + var $scope, controller, $httpBackend, $teams, handshakeMock; var mockTeam = { name: 'foo', number: 123, @@ -34,12 +35,14 @@ describe('teams', function() { describe('missing teams.json on storage',function() { beforeEach(function() { angular.mock.module(module.name); - angular.mock.inject(function($controller, $rootScope) { + angular.mock.inject(function($controller, $rootScope, $q) { $scope = $rootScope.$new(); $teams = createTeamsMock([]); + handshakeMock = createHandshakeMock($q); controller = $controller('teamsCtrl', { '$scope': $scope, - '$teams': $teams + '$teams': $teams, + '$handshake': handshakeMock }); }); return $scope.init(); @@ -55,14 +58,17 @@ describe('teams', function() { describe('stored teams',function() { beforeEach(function() { + angular.mock.module('TeamImportDialog'); angular.mock.module(module.name); - angular.mock.inject(function($controller, $rootScope, _$httpBackend_) { + angular.mock.inject(function($controller, $rootScope, _$httpBackend_,$q) { $scope = $rootScope.$new(); $httpBackend = _$httpBackend_; $teams = createTeamsMock([mockTeam]); + handshakeMock = createHandshakeMock($q); controller = $controller('teamsCtrl', { '$scope': $scope, - '$teams': $teams + '$teams': $teams, + '$handshake': handshakeMock }); }); return $scope.init(); @@ -105,86 +111,21 @@ describe('teams', function() { }); describe('import',function() { - it('should set import mode to true and clear the importRaw field',function() { - $scope.importRaw = 'foo'; - expect($scope.importMode).toBe(false); - $scope.import(); - expect($scope.importMode).toBe(true); - expect($scope.importRaw).toBe(''); - }); - }); - - describe('finishImport',function() { - beforeEach(function() { - $scope.importMode = true; - $scope.importLines = [[42,'FooBars']]; - $scope.importNumberColumn = 1; - $scope.importNameColumn = 2; - }); - it('should set import mode to false',function() { - $scope.finishImport(); - expect($scope.importMode).toBe(false); - }); - it('should clear the teams',function() { - $scope.finishImport(); - expect($teams.clear).toHaveBeenCalled(); - }); - it('should add the teams in the lines',function() { - $scope.finishImport(); - expect($teams.add).toHaveBeenCalledWith({ - number: 42, - name: 'FooBars' + it('should emit the importTeams handshake and add teams on result',function() { + handshakeMock.respond({ + teams: [{number:42,name:'foo'}] }); - }); - }); - - describe('cancelImport',function() { - beforeEach(function() { - $scope.importMode = true; - $scope.importLines = [[42,'FooBars']]; - $scope.importNumberColumn = 1; - $scope.importNameColumn = 2; - }); - it('should set import mode to false',function() { - $scope.cancelImport(); - expect($scope.importMode).toBe(false); - }); - }); - - describe('parsing data',function() { - it('should populate importLines',function() { - $scope.importLines = []; - $scope.importRaw = '42\tFooBar\n7\tQuxMoo'; - $scope.$digest(); - expect($scope.importLines).toEqual([ - ['42','FooBar'], - ['7','QuxMoo'] - ]); - expect($scope.importNumberExample).toEqual('42'); - expect($scope.importNameExample).toEqual('FooBar'); - }); - - it('should skip the first line if it is a header',function() { - $scope.importLines = []; - $scope.importRaw = 'Number\tName\n7\tQuxMoo'; - $scope.importHeader = true; + $scope.import(); + expect(handshakeMock.$emit).toHaveBeenCalledWith('importTeams'); $scope.$digest(); - expect($scope.importLines).toEqual([ - ['7','QuxMoo'] - ]); - expect($scope.importNumberExample).toEqual('7'); - expect($scope.importNameExample).toEqual('QuxMoo'); + expect($teams.add).toHaveBeenCalledWith({number:42,name:'foo'}); }); - it('should not populate example lines if no data given',function() { - $scope.importLines = []; - $scope.importNumberExample = 'numberExample'; - $scope.importNameExample = 'nameExample'; - $scope.importRaw = ''; + it('should be ok when no result is returned',function() { + $scope.import(); + expect(handshakeMock.$emit).toHaveBeenCalledWith('importTeams'); $scope.$digest(); - expect($scope.importLines).toEqual([]); - expect($scope.importNumberExample).toEqual(''); - expect($scope.importNameExample).toEqual(''); + expect($teams.add).not.toHaveBeenCalled(); }); }); diff --git a/src/js/controllers/TeamImportDialogController.js b/src/js/controllers/TeamImportDialogController.js new file mode 100644 index 00000000..e8e1c08a --- /dev/null +++ b/src/js/controllers/TeamImportDialogController.js @@ -0,0 +1,68 @@ +define('controllers/TeamImportDialogController',[ + 'services/ng-handshake', + 'angular' +], function() { + var moduleName = 'TeamImportDialog'; + + return angular.module(moduleName, []).controller('TeamImportDialogController',[ + '$scope', '$handshake', + function ($scope, $handshake) { + var defer; + + function parseData(data) { + //parse raw import, split lines + var lines = data?data.split(/[\n\r]/):[]; + if ($scope.importHeader) { + lines.shift(); + } + lines = lines.map(function(line) { + //split by tab character + return line.split(/\t/); + }); + //try to guess names and number columns + $scope.importNumberColumn = 1; + $scope.importNameColumn = 2; + + if (lines[0]) { + $scope.importNumberExample = lines[0][$scope.importNumberColumn -1]; + $scope.importNameExample = lines[0][$scope.importNameColumn -1]; + } else { + $scope.importNumberExample = ''; + $scope.importNameExample = ''; + } + + $scope.importLines = lines; + } + + $scope.$watch('importRaw',function(data) { + parseData($scope.importRaw); + }); + + $scope.$watch('importHeader',function(data) { + parseData($scope.importRaw); + }); + + $handshake.$on('importTeams',function(e) { + $scope.dialogVisible = true; + defer = $handshake.defer(); + return defer.promise; + }); + + $scope.ok = function() { + $scope.dialogVisible = false; + var teams = $scope.importLines.map(function(line) { + return { + number: line[$scope.importNumberColumn -1], + name: line[$scope.importNameColumn -1] + }; + }); + defer.resolve({teams:teams}); + }; + + $scope.cancel = function () { + $scope.dialogVisible = false; + defer.resolve(); + }; + } + ]); +}); diff --git a/src/js/views/teams.js b/src/js/views/teams.js index 947912dc..c5dc75ad 100644 --- a/src/js/views/teams.js +++ b/src/js/views/teams.js @@ -1,15 +1,19 @@ define('views/teams',[ 'services/log', 'services/ng-teams', + 'services/ng-handshake', + 'controllers/TeamImportDialogController', 'angular' ], function(log) { var moduleName = 'teams'; - return angular.module(moduleName, []).config(['$httpProvider', function($httpProvider) { + return angular.module(moduleName, [ + 'TeamImportDialog' + ]).config(['$httpProvider', function($httpProvider) { delete $httpProvider.defaults.headers.common["X-Requested-With"]; }]).controller(moduleName + 'Ctrl', [ - '$scope','$http','$q','$teams', - function($scope,$http,$q,$teams) { + '$scope','$http','$q','$teams','$handshake', + function($scope,$http,$q,$teams,$handshake) { log('init teams ctrl'); $scope.log = log.get(); @@ -64,60 +68,19 @@ define('views/teams',[ }; $scope.import = function() { - $scope.importMode = true; - $scope.importRaw = ''; - }; - - $scope.finishImport = function() { - $scope.importMode = false; - $teams.clear(); - $scope.importLines.forEach(function(line) { - $teams.add({ - number: line[$scope.importNumberColumn -1], - name: line[$scope.importNameColumn -1] - }); + $handshake.$emit('importTeams').then(function(result) { + if (result) { + $teams.clear(); + result.teams.forEach(function(team) { + $teams.add({ + number: team.number, + name: team.name + }); + }); + } }); }; - $scope.cancelImport = function() { - $scope.importMode = false; - }; - - $scope.$watch('importRaw',function(data) { - parseData($scope.importRaw); - }); - - $scope.$watch('importHeader',function(data) { - parseData($scope.importRaw); - }); - - function parseData(data) { - //parse raw import, split lines - var lines = data?data.split(/[\n\r]/):[]; - if ($scope.importHeader) { - lines.shift(); - } - lines = lines.map(function(line) { - //split by tab character - return line.split(/\t/); - }); - //try to guess names and number columns - $scope.importNumberColumn = 1; - $scope.importNameColumn = 2; - - if (lines[0]) { - $scope.importNumberExample = lines[0][$scope.importNumberColumn -1]; - $scope.importNameExample = lines[0][$scope.importNameColumn -1]; - } else { - $scope.importNumberExample = ''; - $scope.importNameExample = ''; - } - - $scope.importLines = lines; - } - - - $scope.selectTeam = function(team) { $scope.setPage('scoresheet'); $scope.$root.$emit('selectTeam',team); diff --git a/src/views/dialogs.html b/src/views/dialogs.html index a8a52a54..7bafa2ef 100644 --- a/src/views/dialogs.html +++ b/src/views/dialogs.html @@ -1,3 +1,46 @@ +
+
+

+ Import teams + +

+
+

+ Paste a team list below +

+

+ +

+

+ +

+

+ Number column + + ({{importNumberExample}}) +

+

+ Name column + + ({{importNameExample}}) +

+ + + + + +
+ {{field}} +
+ + +
+
+
+

diff --git a/src/views/teams.html b/src/views/teams.html index 6987b761..184224e0 100644 --- a/src/views/teams.html +++ b/src/views/teams.html @@ -1,40 +1,4 @@
- -
-

- Paste a team list below -

-

- -

-

- -

-

- Number column - - ({{importNumberExample}}) -

-

- Name column - - ({{importNameExample}}) -

- - - - - -
- {{field}} -
- - -
-
+
+
+
Date: Wed, 4 Feb 2015 09:47:08 +0100 Subject: [PATCH 61/76] Allow full screen mode when saved to the desktop on ios devices --- src/index.html | 1 + src/nocache.html | 1 + 2 files changed, 2 insertions(+) diff --git a/src/index.html b/src/index.html index 73d01a01..1243ae36 100644 --- a/src/index.html +++ b/src/index.html @@ -3,6 +3,7 @@ + diff --git a/src/nocache.html b/src/nocache.html index 4c1c6626..ef05d188 100644 --- a/src/nocache.html +++ b/src/nocache.html @@ -3,6 +3,7 @@ + From 19192dc0dcf4dc990caeacf4e54304ef1b0c38b0 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 09:47:18 +0100 Subject: [PATCH 62/76] Minor style changes --- src/css/elements.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/css/elements.css b/src/css/elements.css index c09b95f2..04e03f0a 100644 --- a/src/css/elements.css +++ b/src/css/elements.css @@ -157,6 +157,8 @@ table { .drawer .nav li i { width: 24px; margin-right: 32px; + display: inline-block; + width: 20px; } } @@ -171,6 +173,7 @@ table { } .viewMain { margin-top: 56px; + overflow: hidden; } .viewMain > div { @@ -214,6 +217,7 @@ table { } .viewMain { margin-top: 64px; + overflow: hidden; } .viewMain > div { background-color: white; @@ -262,6 +266,7 @@ table { .viewMain { margin-top: 64px; margin-left: 320px; + overflow: hidden; } .viewMain > div { background-color: white; From 0293cda3f7c8b02d07969fb7e0cd2ea686e86831 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 12:46:20 +0100 Subject: [PATCH 63/76] Show table in scores overview, make editable --- src/js/services/ng-scores.js | 5 ++++- src/views/scores.html | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/js/services/ng-scores.js b/src/js/services/ng-scores.js index fe8adfd1..59521d1d 100644 --- a/src/js/services/ng-scores.js +++ b/src/js/services/ng-scores.js @@ -284,7 +284,8 @@ define('services/ng-scores',[ score: sanitizeScore(entry.score), // can be Number, null, "dnc", etc. originalScore: parseInt(entry.originalScore !== undefined ? entry.originalScore : entry.score, 10), edited: entry.edited !== undefined ? String(entry.edited) : undefined, // timestamp, e.g. "Wed Nov 26 2014 21:11:43 GMT+0100 (CET)" - published: !!entry.published + published: !!entry.published, + table: entry.table }; } @@ -372,6 +373,7 @@ define('services/ng-scores',[ stageId: sheet.stageId !== undefined ? sheet.stageId : sheet.stage.id, round: sheet.round, score: sheet.score, + table: sheet.table }; self.add(score); // Mark as processed @@ -435,6 +437,7 @@ define('services/ng-scores',[ originalScore: _score.originalScore, edited: _score.edited, published: _score.published, + table: _score.table, modified: false, error: null }; diff --git a/src/views/scores.html b/src/views/scores.html index f26cbc82..b173c6fb 100644 --- a/src/views/scores.html +++ b/src/views/scores.html @@ -10,6 +10,7 @@ # Stage Round + Table Team Name Score @@ -33,7 +34,15 @@ {{score.round}} - + + + + + + {{score.table}} + + + @@ -42,7 +51,7 @@ {{score.team.number}} - + {{score.team.name}} @@ -52,7 +61,7 @@ {{score.score}} - + From c545ec80f90a46723b445b7c2a1edfc85a1525b5 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 12:55:45 +0100 Subject: [PATCH 64/76] Added message setting and service to wrap posting to a bus --- src/js/services/ng-message.js | 27 +++++++++++++++++++++++++++ src/views/settings.html | 5 +++++ 2 files changed, 32 insertions(+) create mode 100644 src/js/services/ng-message.js diff --git a/src/js/services/ng-message.js b/src/js/services/ng-message.js new file mode 100644 index 00000000..4607ed87 --- /dev/null +++ b/src/js/services/ng-message.js @@ -0,0 +1,27 @@ +/** + * sets up services for a message bus + */ +define('services/ng-message',[ + 'services/ng-services', + 'services/log', + 'services/ng-settings' +],function(module,log) { + "use strict"; + + return module.service('$message',[ + '$http','$settings', + function($http,$settings) { + + return { + send: function(msg) { + return $settings.init().then(function(settings) { + if (settings.messageBus) { + var url = settings.messageBus; + return $http.post(url,msg); + } + }); + } + }; + } + ]); +}); diff --git a/src/views/settings.html b/src/views/settings.html index 7a352466..c45620d1 100644 --- a/src/views/settings.html +++ b/src/views/settings.html @@ -63,6 +63,11 @@

{{stage.name}}

(shared host to get data from and save data to)

+

+ + + (message bus endpoint for http POST) +

From 1eb13174a0ee5389ee11393465c9701fce0acb1f Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 12:59:21 +0100 Subject: [PATCH 65/76] drawer behind dialog shim --- src/css/elements.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css/elements.css b/src/css/elements.css index 04e03f0a..59d9a90d 100644 --- a/src/css/elements.css +++ b/src/css/elements.css @@ -112,7 +112,7 @@ table { transform: translate(-100%); -webkit-transition: -webkit-transform 0.2s; transition: transform 0.2s; - z-index: 2000; + z-index: 1998; border-right: 1px solid rgba(0,0,0,0.14); } .drawer.visible { From 089a7c91809fea40ad433cbbdf867c33a432f7ee Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 13:04:20 +0100 Subject: [PATCH 66/76] Remove table layout --- src/views/scoresheet.html | 51 ++++++++++++--------------------------- 1 file changed, 16 insertions(+), 35 deletions(-) diff --git a/src/views/scoresheet.html b/src/views/scoresheet.html index 39604e19..6a7def70 100644 --- a/src/views/scoresheet.html +++ b/src/views/scoresheet.html @@ -9,27 +9,14 @@

{{field.title}}

Team & round

- - - - - - - - - - - -
- - ({{team.number}}) {{team.name}} -
- - {{stage.name}}: {{round}} -
- - -
+

+ + ({{team.number}}) {{team.name}} +

+

+ + {{stage.name}}: {{round}} +

Total score: {{score()}}
@@ -72,20 +59,14 @@

Team & round

- - - - - - - -
- - ({{team.number}}) {{team.name}} -
- - {{stage.name}}: {{round}} -
+

+ + ({{team.number}}) {{team.name}} +

+

+ + {{stage.name}}: {{round}} +

Total score: {{score()}}
From f4c83f11c91e8ed7bb0a95f1788380b8cbb9b5ef Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 13:12:29 +0100 Subject: [PATCH 67/76] Added table input in scoresheet, use instead of settings --- src/js/views/scoresheet.js | 7 ++++++- src/views/scoresheet.html | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/js/views/scoresheet.js b/src/js/views/scoresheet.js index 7397b8db..57263bed 100644 --- a/src/js/views/scoresheet.js +++ b/src/js/views/scoresheet.js @@ -168,6 +168,9 @@ define('views/scoresheet',[ if (inComplete()) { list.push('Some missions are incomplete'); } + if (!$scope.table) { + list.push('No table number entered'); + } return list; }; @@ -183,6 +186,7 @@ define('views/scoresheet',[ $scope.team = null; $scope.stage = null; $scope.round = null; + $scope.table = null; $scope.missions.forEach(function(mission) { mission.objectives.forEach(function(objective) { delete objective["value"]; @@ -210,7 +214,8 @@ define('views/scoresheet',[ data.team = $scope.team; data.stage = $scope.stage; data.round = $scope.round; - data.table = $scope.settings.table; + // data.table = $scope.settings.table; + data.table = $scope.table; data.signature = $scope.signature; data.score = $scope.score(); diff --git a/src/views/scoresheet.html b/src/views/scoresheet.html index 6a7def70..68d3e9cb 100644 --- a/src/views/scoresheet.html +++ b/src/views/scoresheet.html @@ -17,6 +17,9 @@

Team & round

{{stage.name}}: {{round}}

+

+ Table: +

Total score: {{score()}}
@@ -67,6 +70,9 @@

Team & round

{{stage.name}}: {{round}}

+

+ Table: +

Total score: {{score()}}
From 7a95f753c9d989863a0e9a1aea68958235e1de21 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 13:40:06 +0100 Subject: [PATCH 68/76] Style fix for drawer shim --- src/css/elements.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css/elements.css b/src/css/elements.css index 59d9a90d..d46be0b4 100644 --- a/src/css/elements.css +++ b/src/css/elements.css @@ -134,7 +134,7 @@ table { width: 100%; height: 100%; background-color: black; - z-index: 1999; + z-index: 1997; -webkit-transition: opacity 0.2s; transition: opacity 0.2s; pointer-events: none; From 76756861a4aabd585b4113f4d8cdb5b64ea13a13 Mon Sep 17 00:00:00 2001 From: rikkertkoppes Date: Wed, 4 Feb 2015 13:40:35 +0100 Subject: [PATCH 69/76] Added decorative image to drawer header --- ...del-lego-mindstorms-education-ev3-45560.PNG | Bin 0 -> 252859 bytes src/views/main.html | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/img/tank-bot-model-lego-mindstorms-education-ev3-45560.PNG diff --git a/src/img/tank-bot-model-lego-mindstorms-education-ev3-45560.PNG b/src/img/tank-bot-model-lego-mindstorms-education-ev3-45560.PNG new file mode 100644 index 0000000000000000000000000000000000000000..768534a5730c03c4764bf885e09cdf2e3e0379b6 GIT binary patch literal 252859 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𝔬6 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 F{{w={{currentPage}}

- +

-