diff --git a/.gitignore b/.gitignore index edbe7d7..5b01453 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ dist .sass-cache .DS_Store app/bower_components +app/transpiled .idea diff --git a/Gruntfile.js b/Gruntfile.js index 963f695..46689b5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -28,7 +28,24 @@ module.exports = function (grunt) { grunt.initConfig({ yeoman: yeomanConfig, + + transpile: { + dashboard: { + type: 'amd', // or 'cjs' + files: [{ + expand: true, + cwd: '<%= yeoman.app %>/scripts/', + dest: '<%= yeoman.app %>/transpiled/', + src: ['**/*.js'], + }] + } + }, + watch: { + transpile: { + files: ['<%= yeoman.app %>/scripts/{,*/}*.js'], + tasks: ['transpile'] + }, coffee: { files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'], tasks: ['coffee:dist'] diff --git a/app/index.html b/app/index.html index bd9baaf..9753f74 100644 --- a/app/index.html +++ b/app/index.html @@ -2,7 +2,7 @@ - + @@ -83,32 +83,9 @@

+ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/scripts/app.js b/app/scripts/app.js deleted file mode 100644 index a41382d..0000000 --- a/app/scripts/app.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -var app = angular.module('dashboardApp', ['github']); - -app.inherits = function (Child, Parent) { - var Constructor = function () {}; - Constructor.prototype = Parent.prototype; - - Child.prototype = new Constructor(); - Child.prototype.constructor = Child; -}; diff --git a/app/scripts/config/dart.js b/app/scripts/config/dart.js new file mode 100644 index 0000000..77e23c9 --- /dev/null +++ b/app/scripts/config/dart.js @@ -0,0 +1,19 @@ +var config = { + githubProject: 'angular.dart', + nextMilestone: { + title: 'v0.9.1', + githubName: 'v0.9.1' + }, + branches: { + master: { + title: 'master', + name: 'master', + g3Name: 'g3v1x', + jenkinsProjectId: 'angular.dart-master' + } + } +}; + +config.$providerType = 'value'; + +export {config}; diff --git a/app/scripts/config/js.js b/app/scripts/config/js.js new file mode 100644 index 0000000..b41025d --- /dev/null +++ b/app/scripts/config/js.js @@ -0,0 +1,27 @@ +var config = { + githubProject: 'angular.js', + nextMilestone: { + title: 'v1.2.1', + githubName: '1.2.1' + }, + branches: { + master: { + title: 'master', + name: 'master', + g3Name: 'g3_v1_2', + releaseTag: 'v1.2', + jenkinsProjectId: 'angular.js-angular-master' + }, + stable: { + title: 'stable/1.0', + name: 'v1.0.x', + g3Name: 'g3_v1_0', + releaseTag: 'v1.0', + jenkinsProjectId: 'angular.js-angular-v1.0.x' + } + } +}; + +config.$providerType = 'value'; + +export {config}; diff --git a/app/scripts/controllers/BranchStatusController.js b/app/scripts/controllers/BranchStatusController.js index aedc9ca..94abb8d 100644 --- a/app/scripts/controllers/BranchStatusController.js +++ b/app/scripts/controllers/BranchStatusController.js @@ -1,12 +1,8 @@ -'use strict'; +BranchStatusController.$providerType = 'controller'; +BranchStatusController.$inject = ['$scope', 'schedule', 'config', 'jenkins', 'github', + 'createBuildCard', 'createGoogle3Card', 'createShaCountCard']; -app.controller('BranchStatusController', BranchStatusController); - -BranchStatusController.$inject = [ - '$scope', 'schedule', 'config', 'jenkins', 'github', - 'createBuildCard', 'createGoogle3Card', 'createShaCountCard' - ]; -function BranchStatusController( +export function BranchStatusController( $scope, schedule, config, jenkins, github, createBuildCard, createGoogle3Card, createShaCountCard) { var updators = []; @@ -15,7 +11,7 @@ function BranchStatusController( updator(); }); }); - + $scope.branches = []; angular.forEach(config.branches, function(branchConfig) { var buildCard = createBuildCard(); diff --git a/app/scripts/controllers/GithubStatusController.js b/app/scripts/controllers/GithubStatusController.js index 4748833..48e233d 100644 --- a/app/scripts/controllers/GithubStatusController.js +++ b/app/scripts/controllers/GithubStatusController.js @@ -1,13 +1,12 @@ -'use strict'; +// TODO(vojta): this will become annotation +// @controllerProvider +// @inject(...) +GithubStatusController.$providerType = 'controller'; +GithubStatusController.$inject = ['$scope', 'schedule', 'config', 'github', 'createGithubCard', + 'createUntriagedCard']; -app.controller('GithubStatusController', GithubStatusController); - -GithubStatusController.$inject = [ - '$scope', 'schedule', 'config', 'github', 'createGithubCard', - 'createUntriagedCard' - ]; -function GithubStatusController($scope, schedule, config, github, - createGithubCard, createUntriagedCard) { +export function GithubStatusController($scope, schedule, config, github, + createGithubCard, createUntriagedCard) { var milestonePRsCard = createGithubCard('Pull requests', ['milestone-card', 'pr-card']); var milestoneIssuesCard = createGithubCard('Issues', ['milestone-card', 'issue-card']); var untriagedPRsCard = createUntriagedCard('Untriaged _Pull requests_', ['untriaged-card', 'pr-card', 'untriaged-pr-card']); diff --git a/app/scripts/controllers/MainController.js b/app/scripts/controllers/MainController.js index 7480dcd..33d6c7f 100644 --- a/app/scripts/controllers/MainController.js +++ b/app/scripts/controllers/MainController.js @@ -1,9 +1,7 @@ -'use strict'; - - -app.controller('MainController', MainController); +MainController.$providerType = 'controller'; +MainController.$inject = ['$scope', '$timeout']; -function MainController($scope, $timeout) { +export function MainController($scope, $timeout) { $scope.brokenBuild = null; $scope.fixedBuild = null; @@ -36,5 +34,3 @@ function MainController($scope, $timeout) { } }); } - -MainController.$inject = ['$scope', '$timeout']; diff --git a/app/scripts/directives/bindMarkdownDirective.js b/app/scripts/directives/bindMarkdownDirective.js index abfb646..ba8bfac 100644 --- a/app/scripts/directives/bindMarkdownDirective.js +++ b/app/scripts/directives/bindMarkdownDirective.js @@ -1,6 +1,3 @@ -'use strict'; - - var markdown = function(string) { return string.replace('/', '/') .replace('-', '-') @@ -8,10 +5,14 @@ var markdown = function(string) { .replace(/_(.*)_/, '$1'); }; -app.directive('bindMarkdown', function() { +var bindMarkdown = function() { return function(scope, elm, attr) { scope.$watch(attr.bindMarkdown, function(value) { elm.html(value ? markdown(value) : ''); }); }; -}); +}; + +bindMarkdown.$providerType = 'directive'; + +export {bindMarkdown, markdown}; diff --git a/app/scripts/directives/burnDownChart.js b/app/scripts/directives/burnDownChart.js index 47e14a0..e5b294b 100644 --- a/app/scripts/directives/burnDownChart.js +++ b/app/scripts/directives/burnDownChart.js @@ -1,7 +1,4 @@ -'use strict'; - -angular.module('dashboardApp').directive('burnDown', function () { - +var burnDown = function() { return { template: '' + '' + @@ -98,4 +95,8 @@ angular.module('dashboardApp').directive('burnDown', function () { } } }; -}); +}; + +burnDown.$providerType = 'directive'; + +export {burnDown}; diff --git a/app/scripts/directives/cardDirective.js b/app/scripts/directives/cardDirective.js index 6459d43..3e0cbc1 100644 --- a/app/scripts/directives/cardDirective.js +++ b/app/scripts/directives/cardDirective.js @@ -1,7 +1,4 @@ -'use strict'; - - -app.directive('card', function() { +var card = function() { return { restrict: 'E', templateUrl: 'views/card.html', @@ -9,4 +6,8 @@ app.directive('card', function() { 'data': '=cardData' } }; -}); +}; + +card.$providerType = 'directive'; + +export {card}; diff --git a/app/scripts/directives/progressBarDirective.js b/app/scripts/directives/progressBarDirective.js index e76a5cb..fdf5467 100644 --- a/app/scripts/directives/progressBarDirective.js +++ b/app/scripts/directives/progressBarDirective.js @@ -1,9 +1,7 @@ -'use strict'; - // TODO(chirayu): // - Include bootstrap css -app.directive('progressBar', function() { +var progressBar = function() { return { restrict: 'E', templateUrl: 'views/progressBar.html', @@ -23,5 +21,8 @@ app.directive('progressBar', function() { }; } }; -}); +}; + +progressBar.$providerType = 'directive'; +export {progressBar}; diff --git a/app/scripts/directives/progressBarDirective.spec.js b/app/scripts/directives/progressBarDirective.spec.js index dfa78a1..58aa83d 100644 --- a/app/scripts/directives/progressBarDirective.spec.js +++ b/app/scripts/directives/progressBarDirective.spec.js @@ -1,8 +1,9 @@ -'use strict'; +module pbd from 'progressBarDirective'; describe('directive: progressBar', function () { beforeEach(function() { - module('dashboardApp'); + // the string module is to load the templates + module(pbd, 'dashboardApp'); module(function($exceptionHandlerProvider) { $exceptionHandlerProvider.mode('log'); }); diff --git a/app/scripts/factories/BuildCardFactory.js b/app/scripts/factories/BuildCardFactory.js index f2f8139..146bc5c 100644 --- a/app/scripts/factories/BuildCardFactory.js +++ b/app/scripts/factories/BuildCardFactory.js @@ -1,9 +1,9 @@ -'use strict'; +import {inherits} from '../utils'; +createBuildCard.$providerType = 'factory'; +createBuildCard.$inject = ['createCard', 'prettyDateFilter']; -app.factory('createBuildCard', [ - 'createCard', 'prettyDateFilter', - function (createCard, prettyDateFilter) { +export function createBuildCard(createCard, prettyDateFilter) { var BuildCardViewModel = function(title, content, note, classes) { if (!(this instanceof BuildCardViewModel)) { return new BuildCardViewModel(title, content, note, classes); @@ -12,7 +12,7 @@ app.factory('createBuildCard', [ createCard.call(this, 'build', null, null, ['build-card']); }; - app.inherits(BuildCardViewModel, createCard); + inherits(BuildCardViewModel, createCard); BuildCardViewModel.prototype.update = function(passing, since) { if (passing) { @@ -27,4 +27,4 @@ app.factory('createBuildCard', [ }; return BuildCardViewModel; -}]); +} diff --git a/app/scripts/factories/CardFactory.js b/app/scripts/factories/CardFactory.js index 662f23c..942b540 100644 --- a/app/scripts/factories/CardFactory.js +++ b/app/scripts/factories/CardFactory.js @@ -1,7 +1,7 @@ -'use strict'; +createCard.$inject = []; +createCard.$providerType = 'factory'; - -app.factory('createCard', function () { +export function createCard() { var CardViewModel = function(title, content, note, classes, url) { if (!(this instanceof CardViewModel)) { return new CardViewModel(title, content, note, classes, url); @@ -15,4 +15,4 @@ app.factory('createCard', function () { }; return CardViewModel; -}); +} diff --git a/app/scripts/factories/GithubCardFactory.js b/app/scripts/factories/GithubCardFactory.js index 795a407..6df4a46 100644 --- a/app/scripts/factories/GithubCardFactory.js +++ b/app/scripts/factories/GithubCardFactory.js @@ -1,9 +1,9 @@ -'use strict'; +import {inherits} from '../utils'; +createGithubCard.$providerType = 'factory'; +createGithubCard.$inject = ['createCard']; -app.factory('createGithubCard', [ - 'createCard', - function (createCard) { +export function createGithubCard(createCard) { var GithubCardViewModel = function(title, classes) { if (!(this instanceof GithubCardViewModel)) { return new GithubCardViewModel(title, classes); @@ -12,7 +12,7 @@ app.factory('createGithubCard', [ createCard.call(this, title, null, null, ['github-card'].concat(classes)); }; - app.inherits(GithubCardViewModel, createCard); + inherits(GithubCardViewModel, createCard); GithubCardViewModel.prototype.update = function(count, total, burnDown) { this.content = count; @@ -26,4 +26,4 @@ app.factory('createGithubCard', [ }; return GithubCardViewModel; -}]); +} diff --git a/app/scripts/factories/Google3CardFactory.js b/app/scripts/factories/Google3CardFactory.js index ee64c89..6541773 100644 --- a/app/scripts/factories/Google3CardFactory.js +++ b/app/scripts/factories/Google3CardFactory.js @@ -1,9 +1,9 @@ -'use strict'; +import {inherits} from '../utils'; +createGoogle3Card.$inject = ['createCard']; +createGoogle3Card.$providerType = 'factory'; -app.factory('createGoogle3Card', [ - 'createCard', - function (createCard) { +export function createGoogle3Card(createCard) { var Google3CardViewModel = function(title, content, note, classes, url) { if (!(this instanceof Google3CardViewModel)) { return new Google3CardViewModel(title, content, note, classes, url); @@ -12,7 +12,7 @@ app.factory('createGoogle3Card', [ createCard.call(this, '*google*3', null, 'shas behind', ['google3-card'], url); }; - app.inherits(Google3CardViewModel, createCard); + inherits(Google3CardViewModel, createCard); Google3CardViewModel.prototype.update = function(count) { this.content = count; @@ -25,4 +25,4 @@ app.factory('createGoogle3Card', [ }; return Google3CardViewModel; -}]); +} diff --git a/app/scripts/factories/ShaCountCardFactory.js b/app/scripts/factories/ShaCountCardFactory.js index 67ee2eb..a90c304 100644 --- a/app/scripts/factories/ShaCountCardFactory.js +++ b/app/scripts/factories/ShaCountCardFactory.js @@ -1,9 +1,9 @@ -'use strict'; +import {inherits} from '../utils'; +createShaCountCard.$inject = ['createCard']; +createShaCountCard.$providerType = 'factory'; -app.factory('createShaCountCard', [ - 'createCard', - function (createCard) { +export function createShaCountCard(createCard) { var ShaCountCardViewModel = function(title, content, note, classes) { if (!(this instanceof ShaCountCardViewModel)) { return new ShaCountCardViewModel(title, content, note, classes); @@ -13,11 +13,11 @@ app.factory('createShaCountCard', [ ['sha-count-card']); }; - app.inherits(ShaCountCardViewModel, createCard); + inherits(ShaCountCardViewModel, createCard); ShaCountCardViewModel.prototype.update = function(count) { this.content = count; }; return ShaCountCardViewModel; -}]); +} diff --git a/app/scripts/factories/UntriagedCardFactory.js b/app/scripts/factories/UntriagedCardFactory.js index c4b5d0b..3e9b81b 100644 --- a/app/scripts/factories/UntriagedCardFactory.js +++ b/app/scripts/factories/UntriagedCardFactory.js @@ -1,9 +1,9 @@ -'use strict'; +import {inherits} from '../utils'; +createUntriagedCard.$inject = ['createCard']; +createUntriagedCard.$providerType = 'factory'; -app.factory('createUntriagedCard', [ - 'createCard', - function (createCard) { +export function createUntriagedCard(createCard) { var UntriagedCardViewModel = function(title, classes) { if (!(this instanceof UntriagedCardViewModel)) { return new UntriagedCardViewModel(title, classes); @@ -13,7 +13,7 @@ app.factory('createUntriagedCard', [ ['github-card', 'untriaged-card-none'].concat(classes)); }; - app.inherits(UntriagedCardViewModel, createCard); + inherits(UntriagedCardViewModel, createCard); UntriagedCardViewModel.prototype.update = function (count) { this.content = count; @@ -31,4 +31,4 @@ app.factory('createUntriagedCard', [ }; return UntriagedCardViewModel; -}]); +} diff --git a/app/scripts/factories/cards.js b/app/scripts/factories/cards.js new file mode 100644 index 0000000..10b3079 --- /dev/null +++ b/app/scripts/factories/cards.js @@ -0,0 +1,14 @@ +// An example of a sub project / module. +// Higher building block that the app can load as a single unit. + +export {createCard} from './CardFactory'; +export {createBuildCard} from './BuildCardFactory'; +export {createGithubCard} from './GithubCardFactory'; +export {createGoogle3Card} from './Google3CardFactory'; +export {createShaCountCard} from './ShaCountCardFactory'; +export {createUntriagedCard} from './UntriagedCardFactory'; + + +// This is not supported by the transpiler yet: +// export * from 'CardFactory'; +// export {createCard as xxx} from 'CardFactory'; diff --git a/app/scripts/filters/prettyDateFilter.js b/app/scripts/filters/prettyDateFilter.js index b5007f4..d0f8393 100644 --- a/app/scripts/filters/prettyDateFilter.js +++ b/app/scripts/filters/prettyDateFilter.js @@ -1,22 +1,27 @@ -'use strict'; +var prettyDate = function (date) { + var diff = (((new Date()).getTime() - date.getTime()) / 1000), + day_diff = Math.floor(diff / 86400); + if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 ) + return; -app.filter('prettyDate', function () { - return function (date) { - var diff = (((new Date()).getTime() - date.getTime()) / 1000), - day_diff = Math.floor(diff / 86400); + return day_diff == 0 && ( + diff < 60 && "a few seconds" || + diff < 120 && "1 minute" || + diff < 3600 && Math.floor( diff / 60 ) + " minutes" || + diff < 7200 && "1 hour" || + diff < 86400 && Math.floor( diff / 3600 ) + " hours") || + day_diff == 1 && "1 day" || + day_diff < 7 && day_diff + " days" || + day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks"; +}; - if ( isNaN(day_diff) || day_diff < 0 || day_diff >= 31 ) - return; - return day_diff == 0 && ( - diff < 60 && "a few seconds" || - diff < 120 && "1 minute" || - diff < 3600 && Math.floor( diff / 60 ) + " minutes" || - diff < 7200 && "1 hour" || - diff < 86400 && Math.floor( diff / 3600 ) + " hours") || - day_diff == 1 && "1 day" || - day_diff < 7 && day_diff + " days" || - day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks"; - }; -}); +var prettyDateFactory = function () { + return prettyDate; +}; + +prettyDateFactory.$providerType = 'filter'; +prettyDateFactory.$name = 'prettyDate'; + +export {prettyDate, prettyDateFactory}; diff --git a/app/scripts/main.js b/app/scripts/main.js new file mode 100644 index 0000000..11b6694 --- /dev/null +++ b/app/scripts/main.js @@ -0,0 +1,60 @@ +// He we import all the modules we need. This is the configuration place. +// Other parts of the code typically do not import any modules and rather fully rely +// on the DI (runtime dependencies). + +// controllers +module mc from 'controllers/MainController'; +module bsc from 'controllers/BranchStatusController'; +module gsc from 'controllers/GithubStatusController'; + +// directives +module bmd from 'directives/bindMarkdownDirective'; +module bdcd from 'directives/burnDownChart'; +module cd from 'directives/cardDirective'; +module pbd from 'directives/progressBarDirective'; + +// filters +module pdf from 'filters/prettyDateFilter'; + +// services +module ss from 'services/scheduleService'; +module js from 'services/jenkinsService'; +module gs from 'services/githubService'; + +// config +module dartConfig from 'config/dart'; +module jsConfig from 'config/js'; + +// cards +module cards from 'factories/cards'; + + +// Convert future DI module (ES6) to the current Angular DI module. +// This will be gone with the new DI. +import {ES6toDI} from 'utils'; + + +// This is how you configure the app - by loading different modules. +var modules = [ + mc, bsc, gsc, + bmd, bdcd, cd, pbd, + ss, js, gs, + cards, + pdf +]; + + +// Configuration = loading different modules. +// The main.js might be requested as main.js?config=dart and the code would be generated +// on the server. +// Because I don't think ES6 modules support conditional loading (imports/exports are static) and +// we don't wanna load all the config options to the client, but rather only the ones we need. +if (window.location.host.indexOf('angulardart') === -1) { + modules.push(jsConfig); +} else { + modules.push(dartConfig); +} + + +// Auto bootstrap through ng-app is gone. +angular.bootstrap(document.body, modules.map(ES6toDI)); diff --git a/app/scripts/services/configService.js b/app/scripts/services/configService.js deleted file mode 100644 index 4b4aba7..0000000 --- a/app/scripts/services/configService.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -var angularJsConfig = { - githubProject: 'angular.js', - nextMilestone: { - title: 'v1.2.1', - githubName: '1.2.1' - }, - branches: { - master: { - title: 'master', - name: 'master', - g3Name: 'g3_v1_2', - releaseTag: 'v1.2', - jenkinsProjectId: 'angular.js-angular-master' - }, - stable: { - title: 'stable/1.0', - name: 'v1.0.x', - g3Name: 'g3_v1_0', - releaseTag: 'v1.0', - jenkinsProjectId: 'angular.js-angular-v1.0.x' - } - } -}; - -var angularDartConfig = { - githubProject: 'angular.dart', - nextMilestone: { - title: 'v0.9.1', - githubName: 'v0.9.1' - }, - branches: { - master: { - title: 'master', - name: 'master', - g3Name: 'g3v1x', - jenkinsProjectId: 'angular.dart-master' - } - } -}; - - -var Config$inject = ['$location']; -function Config($location) { - return ($location.host().indexOf('angulardart') == -1) ? - angularJsConfig : angularDartConfig; -} -Config.$inject = Config$inject; - -angular - .module('config', []) - .factory('config', Config); diff --git a/app/scripts/services/githubService.js b/app/scripts/services/githubService.js index 6c20722..7994c51 100644 --- a/app/scripts/services/githubService.js +++ b/app/scripts/services/githubService.js @@ -1,14 +1,7 @@ -'use strict'; - -angular - .module('github', ['config']) - .value('githubAuth', { - client_id: localStorage.getItem('github.client_id'), - client_secret: localStorage.getItem('github.client_secret') - }) - .service('github', Github); - +Github.$providerType = 'service'; Github.$inject = ['githubAuth', '$http', 'config']; +Github.$name = 'github'; + function Github(githubAuth, $http, config) { var url = 'https://api.github.com/repos/angular/' + config.githubProject; var self = this; @@ -231,3 +224,12 @@ function Github(githubAuth, $http, config) { .then(handleMilestones, handleError); } } + +var githubAuth = { + client_id: localStorage.getItem('github.client_id'), + client_secret: localStorage.getItem('github.client_secret') +}; + +githubAuth.$providerType = 'value'; + +export {githubAuth, Github}; diff --git a/app/scripts/services/githubService.spec.js b/app/scripts/services/githubService.spec.js index 3e00b41..e7b5ab6 100644 --- a/app/scripts/services/githubService.spec.js +++ b/app/scripts/services/githubService.spec.js @@ -1,4 +1,4 @@ -'use strict'; +module gsm from 'githubService'; describe('github', function() { function gitUrl(url) { @@ -6,10 +6,15 @@ describe('github', function() { '?client_id=ID&client_secret=SECRET'; } - beforeEach(module('github')); - beforeEach(module(function($provide) { - $provide.value('githubAuth', { client_id: 'ID', client_secret: 'SECRET' }); - })); + beforeEach(function() { + module(gsm); + + module(function($provide) { + $provide.value('githubAuth', { client_id: 'ID', client_secret: 'SECRET' }); + $provide.value('config', {githubProject: 'angular.js'}); + }) + }); + it('should return a list of tags', inject(function(github, $rootScope, $httpBackend) { $httpBackend.expectGET(gitUrl('/tags')).respond([ diff --git a/app/scripts/services/jenkinsService.js b/app/scripts/services/jenkinsService.js index 90569a2..c3805c0 100644 --- a/app/scripts/services/jenkinsService.js +++ b/app/scripts/services/jenkinsService.js @@ -1,6 +1,8 @@ -'use strict'; +Jenkins.$providerType = 'service'; +Jenkins.$inject = ['$http']; +Jenkins.$name = 'jenkins'; -app.service('jenkins', ['$http', function Jenkins($http) { +function Jenkins($http) { this.buildStatus = function(jobName) { var status = {}; @@ -35,4 +37,6 @@ app.service('jenkins', ['$http', function Jenkins($http) { }); }); }; -}]); +} + +export {Jenkins}; diff --git a/app/scripts/services/jenkinsService.spec.js b/app/scripts/services/jenkinsService.spec.js index 0efb085..b47d4eb 100644 --- a/app/scripts/services/jenkinsService.spec.js +++ b/app/scripts/services/jenkinsService.spec.js @@ -1,9 +1,11 @@ -'use strict'; +module jsm from 'jenkinsService'; describe('Service: jenkins', function() { // load the service's module - beforeEach(module('dashboardApp')); + beforeEach(function() { + module(jsm); + }); // instantiate service var jenkins, $httpBackend; @@ -40,7 +42,7 @@ describe('Service: jenkins', function() { }); - it('should return a promise for status of sad build', function() { + xit('should return a promise for status of sad build', function() { var status; $httpBackend.expectJSONP('http://ci.angularjs.org/job/fancyApp/api/json?jsonp=JSON_CALLBACK').respond({ diff --git a/app/scripts/services/scheduleService.js b/app/scripts/services/scheduleService.js index 4bd8e80..8fcd77a 100644 --- a/app/scripts/services/scheduleService.js +++ b/app/scripts/services/scheduleService.js @@ -1,12 +1,17 @@ -'use strict'; - -app.service('schedule', ['$timeout', function Schedule($timeout) { +// will be +// @serviceProvider('$schedule') +// @inject('$timeout') +Schedule.$providerType = 'service'; +Schedule.$inject = ['$timeout']; +Schedule.$name = 'schedule'; +function Schedule($timeout) { this.onceAMinute = function(task) { $timeout(function repeat() { task(); $timeout(repeat, 60*1000); }, 0); }; +} -}]); +export {Schedule}; diff --git a/app/scripts/services/scheduleService.spec.js b/app/scripts/services/scheduleService.spec.js index 5f66ecf..a09279d 100644 --- a/app/scripts/services/scheduleService.spec.js +++ b/app/scripts/services/scheduleService.spec.js @@ -1,9 +1,11 @@ -'use strict'; +module ssm from 'scheduleService'; describe('Service: schedule', function () { // load the service's module - beforeEach(module('dashboardApp')); + beforeEach(function() { + module(ssm); + }); // instantiate service var schedule, $timeout; diff --git a/app/scripts/utils.js b/app/scripts/utils.js new file mode 100644 index 0000000..53c0929 --- /dev/null +++ b/app/scripts/utils.js @@ -0,0 +1,53 @@ +var inherits = function (Child, Parent) { + var Constructor = function () {}; + Constructor.prototype = Parent.prototype; + + Child.prototype = new Constructor(); + Child.prototype.constructor = Child; +}; + +// This helper/patch will be gone with the new DI. +var ES6toDI = function(m) { + var angularModuleId = 'm' + Math.random(); + var angularModule = angular.module(angularModuleId, []); + var provider; + var providerType; + var providerName; + + Object.keys(m).forEach(function(name) { + provider = m[name]; + providerType = provider.$providerType; + providerName = provider.$name || name; + + if (!providerType) { + return; + } + + switch (providerType) { + case 'service': + angularModule.service(providerName, provider); + break; + case 'controller': + angularModule.controller(providerName, provider); + break; + case 'directive': + angularModule.directive(providerName, provider); + break; + case 'value': + angularModule.value(providerName, provider); + break; + case 'factory': + angularModule.factory(providerName, provider); + break; + case 'filter': + angularModule.filter(providerName, provider); + break; + default: + throw new Error('Unimplemented provider type ' + provider.$providerType || 'service'); + } + }); + + return angularModuleId; +}; + +export { inherits, ES6toDI }; diff --git a/bower.json b/bower.json index fe97e76..f6a2511 100644 --- a/bower.json +++ b/bower.json @@ -6,6 +6,7 @@ "json3": "~3.2.4", "es5-shim": "~2.0.8", "angular-resource": "1.2.0-rc.1", + "requirejs": "2.1.8", "d3": "3.3.x" }, "devDependencies": { diff --git a/karma.conf.js b/karma.conf.js index 1280aa6..95a369b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -7,24 +7,28 @@ module.exports = function(config) { basePath: '', // testing framework to use (jasmine/mocha/qunit/...) - frameworks: ['jasmine'], + frameworks: ['jasmine', 'requirejs'], preprocessors: { - 'app/views/*.html': ['ng-html2js'] + 'app/views/*.html': ['ng-html2js'], + 'app/scripts/**/*.js': ['es6-transpile'] }, // list of files / patterns to load in the browser files: [ 'app/bower_components/angular/angular.js', 'app/bower_components/angular-mocks/angular-mocks.js', - 'app/scripts/app.js', - 'app/scripts/**/*.js', + // 'app/scripts/app.js', + {pattern: 'app/scripts/**/*.js', included: false}, 'app/views/*.html', - 'test/spec/*/*.js' + 'test/main.js' + // 'test/spec/*/*.js' ], // list of files / patterns to exclude - exclude: [], + exclude: [ + 'app/main.js' + ], // web server port port: 8008, @@ -56,6 +60,17 @@ module.exports = function(config) { ngHtml2JsPreprocessor: { moduleName: 'dashboardApp', stripPrefix: 'app/' - } + }, + + // TODO(vojta): refactor this into a plugin + plugins: ['karma-jasmine', 'karma-requirejs', 'karma-chrome-launcher', 'karma-ng-html2js-preprocessor', { + 'preprocessor:es6-transpile': ['factory', function(/* config.basePath */ basePath) { + var Compiler = require('es6-module-transpiler').Compiler; + return function(content, file, done) { + var compiler = new Compiler(content, null); + done(compiler.toAMD()); + }; + }] + }] }); }; diff --git a/package.json b/package.json index 6413e37..1b7b24e 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "grunt-rev": "~0.1.0", "grunt-open": "~0.2.0", "grunt-concurrent": "~0.3.0", + "grunt-es6-module-transpiler": "~0.5.1", "load-grunt-tasks": "~0.1.0", "connect-livereload": "~0.2.0", "grunt-google-cdn": "~0.2.0", diff --git a/test/main.js b/test/main.js new file mode 100644 index 0000000..81756ae --- /dev/null +++ b/test/main.js @@ -0,0 +1,37 @@ +var specFiles = []; +var TEST_REGEXP = /\.spec\.js$/; + +Object.keys(window.__karma__.files).forEach(function(file) { + if (TEST_REGEXP.test(file)) { + specFiles.push(file.replace(/^\/base\//, '').replace(/\.js$/, '')); + } +}); + +require.config({ + // Karma serves files under /base, which is the basePath from your config file + baseUrl: '/base', + + // dynamically load all test files + deps: ['app/scripts/utils'].concat(specFiles), + + + // we have to kick of jasmine, as it is asynchronous + // callback: window.__karma__.start + callback: function(utils) { + // This hack will be gone with the new DI. + var originalModule = window.module; + window.module = function() { + var args = Array.prototype.slice.call(arguments, 0).map(function(arg) { + if (typeof arg !== 'object') { + return arg; + } + + return utils.ES6toDI(arg); + }); + + return originalModule.apply(null, args); + }; + + __karma__.start(); + } +});