diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 0000000..ba0accc --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "app/bower_components" +} diff --git a/.gitignore b/.gitignore index c677dbc..83ee456 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ -bower_components -node_modules -target +bower_components/ +node_modules/ +target/ #IDEs #IntelliJ Idea -.idea +.idea/ *.iml diff --git a/.jshintrc b/.jshintrc index 6562015..ebe04ec 100644 --- a/.jshintrc +++ b/.jshintrc @@ -19,6 +19,12 @@ "trailing": true, "smarttabs": true, "globals": { - "angular": true + "angular": true, + "describe": true, + "it": true, + "expect": true, + "module": true, + "inject": true, + "beforeEach": true } } diff --git a/Gruntfile.js b/Gruntfile.js index db7b7af..2ce0368 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,55 +1,93 @@ /*jshint camelcase:false*/ -'use strict'; - -// # Globbing -// for performance reasons we're only matching one level down: -// 'test/spec/{,*/}*.js' -// use this if you want to recursively match all subfolders: -// 'test/spec/**/*.js' module.exports = function (grunt) { + 'use strict'; grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-karma'); + require('load-grunt-tasks')(grunt); + + var config = { app: 'app' }; grunt.initConfig({ - config: config, watch: { - livereload: { - options: { - livereload: '<%= connect.options.livereload %>' - }, files: ['<%= config.app %>/**/*.html', '<%= config.app %>/**/*.js'] - } - }, connect: { - options: { - port: 9000, livereload: 35729, hostname: 'localhost' - }, livereload: { - options: { - open: true, middleware: function (connect) - { - return [connect().use('/bower_components', connect.static('./bower_components')), connect.static(config.app) - - ]; + config: config, + watch: { + livereload: { + options: { + livereload: '<%= connect.options.livereload %>' + }, + files: ['<%= config.app %>/**/*.html', '<%= config.app %>/**/*.js'] + } + }, + + connect: { + options: { + port: 9000, + livereload: 35729, + hostname: '127.0.0.1' + }, + test: { + options: { + base: ['app'], + port: 9001 + } + }, + livereload: { + options: { + open: true, + middleware: function (connect) + { + return [connect().use('/bower_components', connect.static('./bower_components')), connect.static(config.app) + + ]; + } + } + } + }, + karma: { + options: { + configFile: 'test/karma.conf.js' + }, + unit: { + singleRun: true + }, + dev: { + singleRun: false + } + }, + jshint: { + default: { + options: { + jshintrc: true + }, + files: { + src: ['app/**/*.js', 'test/**/*.js', '!app/bower_components/**/*.js'] + } + }, + verify: { + options: { + jshintrc: true, + reporter: 'checkstyle', + reporterOutput: 'target/jshint.xml' + }, + files: {src: ['app/**/*.js', 'test/**/*.js', '!app/bower_components/**/*.js']} } } } - }, - karma: { - unit: { - configFile: 'test/karma.conf.js' - } - } - }); + ); + + grunt.registerTask('serve', ['connect:livereload', 'watch']); + + grunt.registerTask('verify', ['jshint:verify', 'karma:unit']); - grunt.registerTask('serve', function () - { - grunt.task.run(['connect:livereload', 'watch']); - }); + grunt.registerTask('test:dev', ['karma:dev']); grunt.registerTask('default', ['serve']); }; diff --git a/README.md b/README.md index f6a8d77..35d3181 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -#Excersie 1: Bind Posts +# Excersie 1: Bind Posts -##Introduction +## Introduction This lesson is about following skills: @@ -17,10 +17,10 @@ Expected result of this exercise is an application which allows user to display | 1 | Jack | Diving Deep with Dependency Injection | | 2 | Jill | Practical End-to-End Testing with Protractor | -##Before you start, read about... +## Before you start, read about... * ng-repeat: [https://docs.angularjs.org/api/ng/directive/ngRepeat](https://docs.angularjs.org/api/ng/directive/ngRepeat) -##The exercise +## The exercise To complete this exercise you need to follow these steps: @@ -28,7 +28,7 @@ To complete this exercise you need to follow these steps: * use `ng-repeat` to display the rows -##Setup +## Setup You should have installed `npm`, `bower`, `grunt` packages to run this example. First, run sequentially ``` diff --git a/app/BlogPostCtrl.js b/app/BlogPostCtrl.js index fcc176e..b3ecb5d 100644 --- a/app/BlogPostCtrl.js +++ b/app/BlogPostCtrl.js @@ -6,6 +6,5 @@ } - var module = angular.module("exerciseApp", []); - module.controller('BlogPostCtrl', [BlogPostCtrl]); + angular.module('app', []).controller('BlogPostCtrl', [BlogPostCtrl]); })(); diff --git a/app/index.html b/app/index.html index 5a4a2a9..c79921f 100644 --- a/app/index.html +++ b/app/index.html @@ -1,28 +1,31 @@ - + Angular Exercise 1 - -
- - - - - - - - - - - - - - - -
IDAuthorTitle
+ +
+
+ + + + + + + + + + + + + + + + +
IDAuthorTitle
+
diff --git a/bower.json b/bower.json index 79d29ee..5cadc47 100644 --- a/bower.json +++ b/bower.json @@ -5,9 +5,8 @@ "angular": "1.2.16", "angular-resource": "1.2.16", "bootstrap": "3.1.1" -}, + }, "devDependencies": { "angular-mocks": "1.2.16" - }, - "appPath": "app" + } } diff --git a/package.json b/package.json index 6236d9a..78e9d6b 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,25 @@ { "name": "angular-exercises", - "description": "Angular training", + "description": "angular training", "version": "0.0.0", + "repository": "https://github.com/Real-Skill/angular-exercises.git", "dependencies": {}, "devDependencies": { - "grunt": "0.4.2", - "grunt-contrib-jshint": "0.8.0", - "grunt-contrib-watch": "0.6.1", + "grunt": "0.4.5", + "grunt-cli": "0.1.13", "grunt-contrib-connect": "0.7.1", - "grunt-karma": "0.9.0", - "karma-phantomjs-launcher": "0.1.4", - "karma": "0.12.16", - "karma-coverage": "0.2.4", - "karma-jasmine": "0.1.5", - "karma-spec-reporter": "0.0.13" - }, - "engines": { - "node": ">=0.10.0" + "grunt-contrib-jshint": "0.11.3", + "grunt-contrib-watch": "0.6.1", + "grunt-karma": "2.0.0", + "karma": "1.4.1", + "karma-coverage": "0.3.1", + "karma-jasmine": "1.1.0", + "karma-junit-reporter": "0.2.2", + "karma-phantomjs-launcher": "1.0.2", + "karma-spec-reporter": "0.0.13", + "load-grunt-tasks": "0.4.0" }, - "repository": { - "type": "git", - "url": "https://github.com/aniaw/angular-exercises.git" + "scripts": { + "test": "grunt verify --force" } } diff --git a/test/.jshintrc b/test/.jshintrc deleted file mode 100644 index 4f0effd..0000000 --- a/test/.jshintrc +++ /dev/null @@ -1,44 +0,0 @@ -{ - "globals": { - "angular": true, - "xdescribe": true, - "describe": true, - "afterEach": true, - "beforeEach": true, - "it": true, - "xit": true, - "expect": true, - "module": true, - "inject": true, - "jasmine": true, - "spyOn": true, - "mockApi": true, - "browser": true - }, - "browser": true, - "camelcase": true, - "curly": true, - "eqeqeq": true, - "eqnull": true, - "forin": true, - "freeze": true, - "immed": true, - "indent": 4, - "jquery": true, - "latedef": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonbsp": true, - "nonew": true, - "plusplus": false, - "quotmark": "single", - "undef": true, - "unused": true, - "strict": true, - "trailing": true, - "maxdepth": 2, - "maxstatements": 0, - "maxcomplexity": 10, - "maxlen": 160 -} diff --git a/test/karma.conf.js b/test/karma.conf.js index 0fec918..430d0ee 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -1,5 +1,5 @@ -/*global module*/ -module.exports = function (config) { +module.exports = function (config) +{ 'use strict'; config.set({ @@ -13,26 +13,31 @@ module.exports = function (config) { frameworks: ['jasmine'], // list of files / patterns to load in the browser - files: [ - 'bower_components/angular/angular.js', - 'bower_components/angular-mocks/angular-mocks.js', - 'app/**/*.js', 'test/spec/**/*.js' - ], + files: ['app/bower_components/angular/angular.js', + 'app/bower_components/angular-mocks/angular-mocks.js', + 'app/*.js', + 'app/!(bower_components)/**/*.js', + 'test/unit/**/*.spec.js'], // list of files / patterns to exclude exclude: [], - // test results reporter to use - // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' - reporters: ['spec', 'coverage'], + reporters: ['spec', 'coverage', 'junit'], preprocessors: { - 'app/**/*.js': 'coverage' + 'app/*.js': 'coverage', + 'app/!(bower_components)/**/*.js': 'coverage' }, coverageReporter: { - dir: 'target/coverage/', - type: 'html' + dir: 'target/', + type: 'cobertura', + file: 'coverage.xml' + }, + + + junitReporter: { + outputFile: 'target/test-results.xml' }, // web server port @@ -46,18 +51,14 @@ module.exports = function (config) { // - Safari (only Mac) // - PhantomJS // - IE (only Windows) - browsers: [ - 'PhantomJS' - ], + browsers: ['PhantomJS'], // Which plugins to enable - plugins: [ - 'karma-phantomjs-launcher', 'karma-coverage', 'karma-jasmine', 'karma-spec-reporter' - ], + plugins: ['karma-phantomjs-launcher', 'karma-jasmine', 'karma-spec-reporter', 'karma-junit-reporter', 'karma-coverage'], // Continuous Integration mode // if true, it capture browsers, run tests and exit - singleRun: false, + singleRun: true, colors: true, @@ -67,7 +68,6 @@ module.exports = function (config) { //https://github.com/karma-runner/karma/issues/895 usePolling: true - // Uncomment the following lines if you are using grunt's server to run the tests // proxies: { // '/': 'http://localhost:9000/' diff --git a/test/spec/BlogPostCtrl.spec.js b/test/spec/BlogPostCtrl.spec.js deleted file mode 100644 index a5bdb4e..0000000 --- a/test/spec/BlogPostCtrl.spec.js +++ /dev/null @@ -1,81 +0,0 @@ -describe("BlogPostCtrl", function () -{ - 'use strict'; - beforeEach(module('exerciseApp')); - - var blogPostCtrl; - var posts; - var postList; - - beforeEach(inject(function ($controller) - { - postList = []; - posts = [ - { id: 1, - author: 'Jack', - title: 'Diving Deep with Dependency Injection' - }, - { id: 2, - author: 'Jill', - title: 'Practical End-to-End Testing with Protractor' - } - ]; - - blogPostCtrl = $controller('BlogPostCtrl', {}) - })); - - describe("posts array", function () - { - it("should exist", function () - { - expect(blogPostCtrl.posts).not.toBe(undefined); - }); - it("should be an array", function () - { - expect(blogPostCtrl.posts instanceof Array).toBe(true); - }); - - describe("posts.id", function () - { - beforeEach(function () - { - angular.forEach(blogPostCtrl.posts, function (value) - { - this.push(value.id); - }, postList); - }); - it("should set id", function () - { - expect(postList).toEqual([1, 2]) - }); - }); - describe("posts.author", function () - { - beforeEach(function () - { - angular.forEach(blogPostCtrl.posts, function (value) - { - this.push(value.author); - }, postList); - }); - it("should set author", function () - { - expect(postList).toEqual(['Jack', 'Jill']) - }); - }); - describe("posts.title", function () - { - beforeEach(function () - { - angular.forEach(blogPostCtrl.posts, function (value) - { - this.push(value.title); - }, postList); - }); - it("should set title", function () - { - expect(postList).toEqual(['Diving Deep with Dependency Injection', 'Practical End-to-End Testing with Protractor']) - }); - }); - }); -}); diff --git a/test/unit/BlogPostCtrl.spec.js b/test/unit/BlogPostCtrl.spec.js new file mode 100644 index 0000000..826faed --- /dev/null +++ b/test/unit/BlogPostCtrl.spec.js @@ -0,0 +1,43 @@ +describe('BlogPostCtrl', function () +{ + 'use strict'; + + var blogPostCtrl; + var posts; + + beforeEach(module('app')); + + beforeEach(inject(function ($controller) + { + posts = [ + { + id: 1, + author: 'Jack', + title: 'Diving Deep with Dependency Injection' + }, + { + id: 2, + author: 'Jill', + title: 'Practical End-to-End Testing with Protractor' + } + ]; + + blogPostCtrl = $controller('BlogPostCtrl', {}); + })); + + describe('posts array', function () + { + it('should exist', function () + { + expect(blogPostCtrl.posts).not.toBe(undefined); + }); + it('should be an array', function () + { + expect(blogPostCtrl.posts instanceof Array).toBe(true); + }); + it('should be set to data presented in README', function () + { + expect(blogPostCtrl.posts).toEqual(posts); + }); + }); +});