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"
}
}
}