diff --git a/.gitignore b/.gitignore index dda084f0..f5a53f07 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ backend/*.js backend/*.js.map common/*/*.js common/*/*.js.map +test/coverage diff --git a/common/common-classes.d.ts b/common/common-classes.d.ts index d05bde7e..d23a4f42 100644 --- a/common/common-classes.d.ts +++ b/common/common-classes.d.ts @@ -1,10 +1,10 @@ -/// -/// -/// +/// +/// +/// -/// +/// -/// -/// -/// -/// +/// +/// +/// +/// diff --git a/common/tsconfig.json.back b/common/tsconfig.json similarity index 100% rename from common/tsconfig.json.back rename to common/tsconfig.json diff --git a/frontend/app/login/login.service.spec.ts b/frontend/app/login/login.service.spec.ts new file mode 100644 index 00000000..7f1c2713 --- /dev/null +++ b/frontend/app/login/login.service.spec.ts @@ -0,0 +1,42 @@ +/// + +import { + it, + inject, + injectAsync, + beforeEachProviders, + TestComponentBuilder +} from 'angular2/testing'; + +import {Component, provide} from 'angular2/core'; +import {BaseRequestOptions, Http} from 'angular2/http'; +import {MockBackend} from 'angular2/http/testing'; +import {LoginService} from "./login.service"; +import {NetworkService} from "../model/network.service"; + + + +describe('LoginService', () => { + beforeEachProviders(() => [ + provide(NetworkService, { + useFactory: function() { + return {login() {}}; + } + }), + + LoginService + ]); + + + it('should call Network service login', inject([ LoginService,NetworkService ], (loginService, networkService) => { + spyOn(networkService,"login"); + expect(networkService.login).not.toHaveBeenCalled(); + loginService.login(); + expect(networkService.login).toHaveBeenCalled(); + })); + + it('should be true', () => { + expect(true).toEqual(true) + }); + +}); diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 00000000..6fc2e491 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,71 @@ +// @AngularClass + +module.exports = function(config) { + var testWebpackConfig = require('./test/webpack.test.config.js'); + + config.set({ + + // base path that will be used to resolve all patterns (e.g. files, exclude) + basePath: './test', + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['jasmine'], + + // list of files to exclude + exclude: [ ], + + // list of files / patterns to load in the browser + // we are building the test environment in ./spec-bundle.js + files: [ { pattern: 'spec-bundle.js', watched: false } ], + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: {'spec-bundle.js': ['coverage', 'webpack', 'sourcemap']}, + + // Webpack Config at ./webpack.test.config.js + webpack: testWebpackConfig, + + coverageReporter: { + dir : 'coverage/', + reporters: [ + { type: 'text-summary' }, + { type: 'json' }, + { type: 'html' } + ] + }, + + // Webpack please don't spam the console when running in karma! + webpackServer: { noInfo: true }, + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: [ 'mocha', 'coverage' ], + + // web server port + port: 9876, + + // enable / disable colors in the output (reporters and logs) + colors: true, + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: [ + // 'Chrome', + 'PhantomJS' + ], + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: true + }); + +}; diff --git a/package.json b/package.json index ad6582f8..334f103f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,13 @@ "name": "PiGallery2", "version": "0.0.0", "private": true, + "description": "This is a photo gallery optimised for running low resource servers (especially on raspberry pi)", + "author": "Braun Patrik", + "homepage": "https://github.com/bpatrik/PiGallery2", + "license": "MIT", "scripts": { + "build": "webpack -p", + "test": "karma start ./karma.conf.js", "start": "node ./backend/server" }, "dependencies": { @@ -17,11 +23,49 @@ "socket.io": "^1.4.5", "socket.io-client": "^1.4.5", "ts-loader": "^0.8.1", - "webpack": "^1.12.14", - "zone.js": "^0.5.15" + "zone.js": "^0.5.15", + "es7-reflect-metadata": "^1.6.0" }, "devDependencies": { - "typescript": "^1.8.7", - "typings": "^0.7.8" + "awesome-typescript-loader": "^0.16.0-rc.0", + "compression-webpack-plugin": "^0.3.0", + "copy-webpack-plugin": "^1.1.1", + "css-loader": "^0.23.1", + "es6-promise-loader": "^1.0.1", + "exports-loader": "^0.6.3", + "expose-loader": "^0.7.1", + "file-loader": "^0.8.5", + "html-webpack-plugin": "^2.9.0", + "ie-shim": "^0.1.0", + "imports-loader": "^0.6.5", + "istanbul-instrumenter-loader": "^0.2.0", + "json-loader": "^0.5.4", + "karma": "^0.13.21", + "karma-chrome-launcher": "^0.2.2", + "karma-coverage": "^0.5.3", + "karma-jasmine": "^0.3.7", + "karma-mocha-reporter": "^2.0.0", + "karma-phantomjs-launcher": "^1.0.0", + "karma-sourcemap-loader": "^0.3.7", + "karma-webpack": "1.7.0", + "ng2lint": "0.0.10", + "parse5": "^1.3.2", + "phantomjs-polyfill": "0.0.2", + "phantomjs-prebuilt": "^2.1.4", + "protractor": "^3.1.1", + "raw-loader": "0.5.1", + "remap-istanbul": "^0.5.1", + "rimraf": "^2.5.2", + "source-map-loader": "^0.1.5", + "style-loader": "^0.13.0", + "ts-helper": "0.0.1", + "ts-node": "^0.5.5", + "tslint": "^3.5.0", + "tslint-loader": "^2.1.3", + "typedoc": "^0.3.12", + "typescript": "~1.8.7", + "typings": "^0.7.8", + "url-loader": "^0.5.7", + "webpack": "^1.12.14" } } diff --git a/test/spec-bundle.js b/test/spec-bundle.js new file mode 100644 index 00000000..33b6d5c6 --- /dev/null +++ b/test/spec-bundle.js @@ -0,0 +1,49 @@ +// @AngularClass +/* + * When testing with webpack and ES6, we have to do some extra + * things get testing to work right. Because we are gonna write test + * in ES6 to, we have to compile those as well. That's handled in + * karma.conf.js with the karma-webpack plugin. This is the entry + * file for webpack test. Just like webpack will create a bundle.js + * file for our client, when we run test, it well compile and bundle them + * all here! Crazy huh. So we need to do some setup + */ +Error.stackTraceLimit = Infinity; +require('phantomjs-polyfill'); +require('es6-promise'); +require('es6-shim'); +require('es7-reflect-metadata'); + +require('zone.js/dist/zone-microtask.js'); +require('zone.js/dist/long-stack-trace-zone.js'); +require('zone.js/dist/jasmine-patch.js'); + + +var testing = require('angular2/testing'); +var browser = require('angular2/platform/testing/browser'); + +testing.setBaseTestProviders( + browser.TEST_BROWSER_PLATFORM_PROVIDERS, + browser.TEST_BROWSER_APPLICATION_PROVIDERS); + +Object.assign(global, testing); +/* + Ok, this is kinda crazy. We can use the the context method on + require that webpack created in order to tell webpack + what files we actually want to require or import. + Below, context will be an function/object with file names as keys. + using that regex we are saying look in ./src/app and ./test then find + any file that ends with spec.js and get its path. By passing in true + we say do this recursively + */ +var testContext = require.context('./../frontend', true, /\.spec\.ts/); + +// get all the files, for each file, call the context function +// that will require the file and load it up here. Context will +// loop and require those spec files here +function requireAll(requireContext) { + return requireContext.keys().map(requireContext); +} + +var modules = requireAll(testContext); +// requires and returns all modules that match diff --git a/test/src-bundle.js b/test/src-bundle.js new file mode 100644 index 00000000..f34228bd --- /dev/null +++ b/test/src-bundle.js @@ -0,0 +1,49 @@ +// @AngularClass +/* + * When testing with webpack and ES6, we have to do some extra + * things get testing to work right. Because we are gonna write test + * in ES6 to, we have to compile those as well. That's handled in + * karma.conf.js with the karma-webpack plugin. This is the entry + * file for webpack test. Just like webpack will create a bundle.js + * file for our client, when we run test, it well compile and bundle them + * all here! Crazy huh. So we need to do some setup + */ +Error.stackTraceLimit = Infinity; +require('phantomjs-polyfill'); +require('es6-promise'); +require('es6-shim'); +require('es7-reflect-metadata'); + +require('zone.js/dist/zone-microtask.js'); +require('zone.js/dist/long-stack-trace-zone.js'); +require('zone.js/dist/jasmine-patch.js'); + + +var testing = require('angular2/testing'); +var browser = require('angular2/platform/testing/browser'); + +testing.setBaseTestProviders( + browser.TEST_BROWSER_PLATFORM_PROVIDERS, + browser.TEST_BROWSER_APPLICATION_PROVIDERS); + +Object.assign(global, testing); +/* + Ok, this is kinda crazy. We can use the the context method on + require that webpack created in order to tell webpack + what files we actually want to require or import. + Below, context will be an function/object with file names as keys. + using that regex we are saying look in ./src/app and ./test then find + any file that ends with spec.js and get its path. By passing in true + we say do this recursively + */ +var testContext = require.context('./../frontend', true, /\.ts/); + +// get all the files, for each file, call the context function +// that will require the file and load it up here. Context will +// loop and require those spec files here +function requireAll(requireContext) { + return requireContext.keys().map(requireContext); +} + +var modules = requireAll(testContext); +// requires and returns all modules that match diff --git a/test/tsconfig.json b/test/tsconfig.json new file mode 100644 index 00000000..9fcc3436 --- /dev/null +++ b/test/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "sourceMap": true, + "module": "commonjs", + "emitDecoratorMetadata": true, + "experimentalDecorators": true + }, + "exclude": [ + "node_modules", + "typings" + ] +} \ No newline at end of file diff --git a/test/tslint.json b/test/tslint.json new file mode 100644 index 00000000..163e10f1 --- /dev/null +++ b/test/tslint.json @@ -0,0 +1,71 @@ +{ + "rulesDirectory": [ + "node_modules/ng2lint/dist/src" + ], + "rules": { + "component-selector-name": [true, "kebab-case"], + "component-selector-type": [true, "element"], + "host-parameter-decorator": true, + "input-parameter-decorator": true, + "output-parameter-decorator": true, + "attribute-parameter-decorator": false, + "input-property-directive": true, + "output-property-directive": true, + + "class-name": true, + "curly": false, + "eofline": true, + "indent": [ + true, + "spaces" + ], + "max-line-length": [ + true, + 100 + ], + "member-ordering": [ + true, + "public-before-private", + "static-before-instance", + "variables-before-functions" + ], + "experimentalDecorators":true, + "no-arg": true, + "no-construct": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": false, + "no-eval": true, + "trailing-comma": true, + "no-trailing-whitespace": true, + "no-unused-expression": true, + "no-unused-variable": false, + "no-unreachable": true, + "no-use-before-declare": true, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": [ + true, + "single" + ], + "semicolon": true, + "triple-equals": [ + true, + "allow-null-check" + ], + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ] + } +} diff --git a/test/webpack.test.config.js b/test/webpack.test.config.js new file mode 100644 index 00000000..1df28830 --- /dev/null +++ b/test/webpack.test.config.js @@ -0,0 +1,87 @@ + + +var path = require('path'); +// Webpack Plugins +var ProvidePlugin = require('webpack/lib/ProvidePlugin'); +var DefinePlugin = require('webpack/lib/DefinePlugin'); +var ENV = process.env.ENV = process.env.NODE_ENV = 'test'; + +/* + * Config + */ +module.exports = { + devtool: 'inline-source-map', + resolve: { + extensions: ['', '.ts', '.js'] + }, + module: { + preLoaders: [ + { + test: /\.ts$/, + loader: 'tslint-loader', + exclude: [ + root('node_modules') + ] + }, + { + test: /\.js$/, + loader: "source-map-loader", + exclude: [ + root('node_modules/rxjs') + ] + } + ], + loaders: [ + { + test: /\.ts$/, + loader: 'awesome-typescript-loader', + query: { + "compilerOptions": { + "removeComments": true + } + }, + exclude: [ /\.e2e\.ts$/ ] + }, + { test: /\.json$/, loader: 'json-loader', exclude: [ root('frontend/index.html') ] }, + { test: /\.html$/, loader: 'raw-loader', exclude: [ root('frontend/index.html') ] }, + { test: /\.css$/, loader: 'raw-loader', exclude: [ root('frontend/index.html') ] } + ], + postLoaders: [ + // instrument only testing sources with Istanbul + { + test: /\.(js|ts)$/, + include: root('frontend'), + loader: 'istanbul-instrumenter-loader', + exclude: [ + /\.(e2e|spec)\.ts$/, + /node_modules/ + ] + } + ] + }, + plugins: [ + // Environment helpers + new DefinePlugin({ + 'ENV': JSON.stringify(ENV), + 'HMR': false + }) + ], + node: { + global: 'window', + progress: false, + crypto: 'empty', + module: false, + clearImmediate: false, + setImmediate: false + }, + tslint: { + emitErrors: false, + failOnHint: false, + resourcePath: 'src' + } +}; + +function root(args) { + args = Array.prototype.slice.call(arguments, 0); + return path.join.apply(path, [__dirname+"/../"].concat(args)); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..9fcc3436 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "es5", + "sourceMap": true, + "module": "commonjs", + "emitDecoratorMetadata": true, + "experimentalDecorators": true + }, + "exclude": [ + "node_modules", + "typings" + ] +} \ No newline at end of file diff --git a/tsd.json b/tsd.json index 2ac1d1a5..002bc4f4 100644 --- a/tsd.json +++ b/tsd.json @@ -25,6 +25,9 @@ }, "socket.io-client/socket.io-client.d.ts": { "commit": "d22516f9f089de107d7e7d5938566377370631f6" + }, + "jasmine/jasmine.d.ts": { + "commit": "d22516f9f089de107d7e7d5938566377370631f6" } } }