Files to support Grunt-based browser staff building.
* Fetching dependencies (angularjs, etc.)
* Runs unit tests with grunt-karma
* Concatenates and minifies files with grunt-uglify
* Moved unit tests into web directory
* Taught t_base_js.tt2 how to load the minified version of the file
TODO:
* minifiying non-core files and (possibly) copying them into the build
directory.
* Support for using non-minified files via browser option?
* Makefile options for building, testing, and copying the correct files
into the actual web directory (instead of cp -r web/*)
* Build docs
Signed-off-by: Bill Erickson <berick@esilibrary.com>
<!-- TODO: combine and minify JS -->
[%
- ANGULAR_VERSION = '1.2.16';
- ANGULAR_BOOTSTRAP_VERSION = '0.9.0';
+ EG_VERSION = '0.0.1'; # FIXME: build optoin
+ EXPAND_JS_IMPORTS = 1; # FIXME: env option?
%]
-<!-- hosted angular libs -->
-<script src="//ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular.min.js"></script>
-<script src="//ajax.googleapis.com/ajax/libs/angularjs/[% ANGULAR_VERSION %]/angular-route.min.js"></script>
-<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/[% ANGULAR_BOOTSTRAP_VERSION %]/ui-bootstrap-tpls.min.js"></script>
+<script src="/IDL2js"></script>
+
+[% IF EXPAND_JS_IMPORTS %]
+
+<!-- angular -->
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/build/angular.min.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/build/angular-route.min.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/build/ui-bootstrap.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/build/hotkeys.min.js"></script>
<!-- IDL / opensrf (network) -->
-<script src="/IDL2js"></script>
<script src="[% ctx.media_prefix %]/js/dojo/opensrf/JSON_v1.js"></script>
<script src="[% ctx.media_prefix %]/js/dojo/opensrf/opensrf.js"></script>
<script src="[% ctx.media_prefix %]/js/dojo/opensrf/opensrf_ws.js"></script>
-<script>
- // pending api_level thunking in C
- // OpenSRF.api_level = 2;
- OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS;
-</script>
-<!-- angular-driven shared services -->
+<!-- evergreen core services -->
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/core.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/strings.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/idl.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/startup.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/hatch.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/coresvc.js"></script>
-
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/navbar.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/statusbar.js"></script>
-
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/ui.js"></script>
-<script src="[% ctx.media_prefix %]/js/ui/default/staff/navbar.js"></script>
+[% ELSE %]
+
+<!-- concatenated, minified version of all of the above -->
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/build/evergreen-staff-client.[% EG_VERSION %].min.js"></script>
+
+[% END %]
+
+<script>
+ // Configure OpenSRF
+ // pending api_level thunking in C
+ // OpenSRF.api_level = 2;
+ OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_WS;
+</script>
+++ /dev/null
-The MIT License
-
-Copyright (c) 2010-2012 Google, Inc. http://angularjs.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
+++ /dev/null
-../../../web/js/ui/default/staff
\ No newline at end of file
+++ /dev/null
-module.exports = function(config){
- config.set({
- basePath : '../',
- //logLevel : config.LOG_DEBUG,
-
- files : [
- 'app/lib/angular/angular.js',
- 'app/lib/angular/angular-*.js',
- 'app/lib/angular-ui-bootstrap/angular-bootstrap-min.js',
- 'test/lib/angular/angular-mocks.js',
- 'app/lib/opensrf/JSON_v1.js',
- 'app/lib/opensrf/md5.js',
- 'app/lib/opensrf/opensrf.js',
- 'app/lib/opensrf/opensrf_xhr.js',
- 'app/js/services/core.js',
- 'app/js/services/idl.js',
- 'app/js/services/event.js',
- 'app/js/services/net.js',
- 'app/js/services/auth.js',
- 'app/js/services/pcrud.js',
- 'app/js/services/env.js',
- 'app/js/services/org.js',
- 'app/js/services/user.js',
- 'app/js/services/startup.js',
- 'app/js/services/ui.js',
- 'app/js/**/*.js',
- 'test/unit/**/*.js'
- ],
-
- exclude : [
- 'app/lib/angular/angular-loader.js',
- 'app/lib/angular/*.min.js',
- 'app/lib/angular/angular-scenario.js'
- ],
-
- autoWatch : true,
-
- frameworks: ['jasmine'],
-
- browsers : ['Chrome'],
-
- plugins : [
- 'karma-chrome-launcher',
- 'karma-firefox-launcher',
- 'karma-jasmine'
- ],
-
-})}
+++ /dev/null
-@echo off
-
-REM Windows script for running e2e tests
-REM You have to run server and capture some browser first
-REM
-REM Requirements:
-REM - NodeJS (http://nodejs.org/)
-REM - Karma (npm install -g karma)
-
-set BASE_DIR=%~dp0
-karma start "%BASE_DIR%\..\config\karma-e2e.conf.js" %*
+++ /dev/null
-#!/bin/bash
-
-BASE_DIR=`dirname $0`
-
-echo ""
-echo "Starting Karma Server (http://karma-runner.github.io)"
-echo $BASE_DIR
-echo "-------------------------------------------------------------------"
-
-$BASE_DIR/../node_modules/karma/bin/karma start $BASE_DIR/../config/karma-e2e.conf.js $*
+++ /dev/null
-@echo off\r
-\r
-REM Windows script for running unit tests\r
-REM You have to run server and capture some browser first\r
-REM\r
-REM Requirements:\r
-REM - NodeJS (http://nodejs.org/)\r
-REM - Karma (npm install -g karma)\r
-\r
-set BASE_DIR=%~dp0\r
-karma start "%BASE_DIR%\..\config\karma.conf.js" %*\r
+++ /dev/null
-#!/bin/bash
-
-BASE_DIR=`dirname $0`
-
-echo ""
-echo "Starting Karma Server (http://karma-runner.github.io)"
-echo "-------------------------------------------------------------------"
-
-#$BASE_DIR/../node_modules/karma/bin/karma start $BASE_DIR/../config/karma.conf.js $*
-karma start $BASE_DIR/../config/karma.conf.js $*
+++ /dev/null
-#!/usr/bin/env watchr
-
-# config file for watchr http://github.com/mynyml/watchr
-# install: gem install watchr
-# run: watch watchr.rb
-# note: make sure that you have jstd server running (server.sh) and a browser captured
-
-log_file = File.expand_path(File.dirname(__FILE__) + '/../logs/jstd.log')
-
-`cd ..`
-`touch #{log_file}`
-
-puts "String watchr... log file: #{log_file}"
-
-watch( '(app/js|test/unit)' ) do
- `echo "\n\ntest run started @ \`date\`" > #{log_file}`
- `scripts/test.sh &> #{log_file}`
-end
-
+++ /dev/null
-#!/usr/bin/env node
-
-var util = require('util'),
- http = require('http'),
- fs = require('fs'),
- url = require('url'),
- events = require('events');
-
-var DEFAULT_PORT = 8000;
-
-function main(argv) {
- new HttpServer({
- 'GET': createServlet(StaticServlet),
- 'HEAD': createServlet(StaticServlet)
- }).start(Number(argv[2]) || DEFAULT_PORT);
-}
-
-function escapeHtml(value) {
- return value.toString().
- replace('<', '<').
- replace('>', '>').
- replace('"', '"');
-}
-
-function createServlet(Class) {
- var servlet = new Class();
- return servlet.handleRequest.bind(servlet);
-}
-
-/**
- * An Http server implementation that uses a map of methods to decide
- * action routing.
- *
- * @param {Object} Map of method => Handler function
- */
-function HttpServer(handlers) {
- this.handlers = handlers;
- this.server = http.createServer(this.handleRequest_.bind(this));
-}
-
-HttpServer.prototype.start = function(port) {
- this.port = port;
- this.server.listen(port);
- util.puts('Http Server running at http://localhost:' + port + '/');
-};
-
-HttpServer.prototype.parseUrl_ = function(urlString) {
- var parsed = url.parse(urlString);
- parsed.pathname = url.resolve('/', parsed.pathname);
- return url.parse(url.format(parsed), true);
-};
-
-HttpServer.prototype.handleRequest_ = function(req, res) {
- var logEntry = req.method + ' ' + req.url;
- if (req.headers['user-agent']) {
- logEntry += ' ' + req.headers['user-agent'];
- }
- util.puts(logEntry);
- req.url = this.parseUrl_(req.url);
- var handler = this.handlers[req.method];
- if (!handler) {
- res.writeHead(501);
- res.end();
- } else {
- handler.call(this, req, res);
- }
-};
-
-/**
- * Handles static content.
- */
-function StaticServlet() {}
-
-StaticServlet.MimeMap = {
- 'txt': 'text/plain',
- 'html': 'text/html',
- 'css': 'text/css',
- 'xml': 'application/xml',
- 'json': 'application/json',
- 'js': 'application/javascript',
- 'jpg': 'image/jpeg',
- 'jpeg': 'image/jpeg',
- 'gif': 'image/gif',
- 'png': 'image/png',
- 'svg': 'image/svg+xml'
-};
-
-StaticServlet.prototype.handleRequest = function(req, res) {
- var self = this;
- var path = ('./' + req.url.pathname).replace('//','/').replace(/%(..)/g, function(match, hex){
- return String.fromCharCode(parseInt(hex, 16));
- });
- var parts = path.split('/');
- if (parts[parts.length-1].charAt(0) === '.')
- return self.sendForbidden_(req, res, path);
- fs.stat(path, function(err, stat) {
- if (err)
- return self.sendMissing_(req, res, path);
- if (stat.isDirectory())
- return self.sendDirectory_(req, res, path);
- return self.sendFile_(req, res, path);
- });
-}
-
-StaticServlet.prototype.sendError_ = function(req, res, error) {
- res.writeHead(500, {
- 'Content-Type': 'text/html'
- });
- res.write('<!doctype html>\n');
- res.write('<title>Internal Server Error</title>\n');
- res.write('<h1>Internal Server Error</h1>');
- res.write('<pre>' + escapeHtml(util.inspect(error)) + '</pre>');
- util.puts('500 Internal Server Error');
- util.puts(util.inspect(error));
-};
-
-StaticServlet.prototype.sendMissing_ = function(req, res, path) {
- path = path.substring(1);
- res.writeHead(404, {
- 'Content-Type': 'text/html'
- });
- res.write('<!doctype html>\n');
- res.write('<title>404 Not Found</title>\n');
- res.write('<h1>Not Found</h1>');
- res.write(
- '<p>The requested URL ' +
- escapeHtml(path) +
- ' was not found on this server.</p>'
- );
- res.end();
- util.puts('404 Not Found: ' + path);
-};
-
-StaticServlet.prototype.sendForbidden_ = function(req, res, path) {
- path = path.substring(1);
- res.writeHead(403, {
- 'Content-Type': 'text/html'
- });
- res.write('<!doctype html>\n');
- res.write('<title>403 Forbidden</title>\n');
- res.write('<h1>Forbidden</h1>');
- res.write(
- '<p>You do not have permission to access ' +
- escapeHtml(path) + ' on this server.</p>'
- );
- res.end();
- util.puts('403 Forbidden: ' + path);
-};
-
-StaticServlet.prototype.sendRedirect_ = function(req, res, redirectUrl) {
- res.writeHead(301, {
- 'Content-Type': 'text/html',
- 'Location': redirectUrl
- });
- res.write('<!doctype html>\n');
- res.write('<title>301 Moved Permanently</title>\n');
- res.write('<h1>Moved Permanently</h1>');
- res.write(
- '<p>The document has moved <a href="' +
- redirectUrl +
- '">here</a>.</p>'
- );
- res.end();
- util.puts('301 Moved Permanently: ' + redirectUrl);
-};
-
-StaticServlet.prototype.sendFile_ = function(req, res, path) {
- var self = this;
- var file = fs.createReadStream(path);
- res.writeHead(200, {
- 'Content-Type': StaticServlet.
- MimeMap[path.split('.').pop()] || 'text/plain'
- });
- if (req.method === 'HEAD') {
- res.end();
- } else {
- file.on('data', res.write.bind(res));
- file.on('close', function() {
- res.end();
- });
- file.on('error', function(error) {
- self.sendError_(req, res, error);
- });
- }
-};
-
-StaticServlet.prototype.sendDirectory_ = function(req, res, path) {
- var self = this;
- if (path.match(/[^\/]$/)) {
- req.url.pathname += '/';
- var redirectUrl = url.format(url.parse(url.format(req.url)));
- return self.sendRedirect_(req, res, redirectUrl);
- }
- fs.readdir(path, function(err, files) {
- if (err)
- return self.sendError_(req, res, error);
-
- if (!files.length)
- return self.writeDirectoryIndex_(req, res, path, []);
-
- var remaining = files.length;
- files.forEach(function(fileName, index) {
- fs.stat(path + '/' + fileName, function(err, stat) {
- if (err)
- return self.sendError_(req, res, err);
- if (stat.isDirectory()) {
- files[index] = fileName + '/';
- }
- if (!(--remaining))
- return self.writeDirectoryIndex_(req, res, path, files);
- });
- });
- });
-};
-
-StaticServlet.prototype.writeDirectoryIndex_ = function(req, res, path, files) {
- path = path.substring(1);
- res.writeHead(200, {
- 'Content-Type': 'text/html'
- });
- if (req.method === 'HEAD') {
- res.end();
- return;
- }
- res.write('<!doctype html>\n');
- res.write('<title>' + escapeHtml(path) + '</title>\n');
- res.write('<style>\n');
- res.write(' ol { list-style-type: none; font-size: 1.2em; }\n');
- res.write('</style>\n');
- res.write('<h1>Directory: ' + escapeHtml(path) + '</h1>');
- res.write('<ol>');
- files.forEach(function(fileName) {
- if (fileName.charAt(0) !== '.') {
- res.write('<li><a href="' +
- escapeHtml(fileName) + '">' +
- escapeHtml(fileName) + '</a></li>');
- }
- });
- res.write('</ol>');
- res.end();
-};
-
-// Must be last,
-main(process.argv);
+++ /dev/null
-'use strict';
-
-describe('egHomeControllers', function(){
- beforeEach(module('egHome'));
-
- /* ---- LoginCtrl ---------------------------------- */
-
- var loginCtrl, loginScope;
- beforeEach(inject(function ($rootScope, $controller, $location) {
- // pass the workstation name via (mock) URL param
- $location.search({ws : 'TestWorkstation'});
-
- loginScope = $rootScope.$new();
- loginCtrl = $controller('LoginCtrl', {$scope: loginScope});
- }));
-
- it('should focus the login controller', inject(function() {
- expect(loginScope.focusMe).toBe(true);
- }));
-
- it('should set the login workstation', inject(function() {
- expect(loginScope.args.workstation).toEqual('TestWorkstation');
- }));
-
-});
+++ /dev/null
-'use strict';
-
-describe('egPatronAppTest', function(){
- beforeEach(module('egPatronApp'));
-
- // basic controller sanity checks
-
- var patronCtrl, patronScope;
- beforeEach(inject(function ($rootScope, $controller, $location) {
- patronScope = $rootScope.$new();
- patronCtrl = $controller('PatronCtrl', {$scope: patronScope});
- }));
-
- /** patronSvc tests **/
- describe('patronSvcTests', function() {
-
- it('patronSvc should start with empty lists', inject(function(patronSvc) {
- expect(patronSvc.patrons.count()).toEqual(0);
- }));
-
- it('patronSvc reset should clear data', inject(function(patronSvc) {
- patronSvc.checkout_overrides.a = 1;
- expect(Object.keys(patronSvc.checkout_overrides).length).toBe(1);
- patronSvc.resetPatronLists();
- expect(Object.keys(patronSvc.checkout_overrides).length).toBe(0);
- expect(patronSvc.holds.items.length).toBe(0);
- }));
-
- });
-
-});
+++ /dev/null
-#! /bin/sh
-
-# --------------------------------------
-# modified added by berick / 2013-12-12
-# * create needed dirs
-# * udpate angular-ui-bootstrap code
-
-set -e;
-
-if [ -z "$1" ]; then
- echo "$0 <angular-version> <angular-bootstrap-version>"
- exit;
-fi;
-
-mkdir -p tmp
-mkdir -p app/lib;
-mkdir -p test/lib/angular
-mkdir -p test/lib/angular-ui-bootstrap
-
-curl https://raw.github.com/angular/code.angularjs.org/master/$1/angular-$1.zip -o tmp/angular.zip
-rm -fr app/lib/angular
-unzip tmp/angular.zip -d app/lib
-mv app/lib/angular-$1 app/lib/angular
-rm -fr app/lib/angular/docs
-mv app/lib/angular/angular-mocks.js test/lib/angular
-mv app/lib/angular/angular-scenario.js test/lib/angular
-cp app/lib/angular/version.txt test/lib/angular
-
-if [ -n "$2" ]; then
- mkdir -p app/lib/angular-ui-bootstrap/
- curl http://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/$2/ui-bootstrap-tpls.min.js \
- -o app/lib/angular-ui-bootstrap/angular-bootstrap-min.js
-fi;
-
--- /dev/null
+module.exports = function(grunt) {
+
+ // Project configuration.
+ var config = {
+ pkg: grunt.file.readJSON('package.json'),
+
+ // copy the JS files we care about from node-fetched dependencies
+ // into our build directory
+ copy: {
+ main: {
+ files: [{
+ dest: 'build/',
+ flatten: true,
+ filter: 'isFile',
+ expand : true,
+ src: [
+ 'node_modules/angular/lib/angular.min.js',
+ 'node_modules/angular-route/angular-route.min.js',
+ 'node_modules/angular-bootstrap/ui-bootstrap.js',
+ 'node_modules/angular-hotkeys/build/hotkeys.min.js'
+ ]
+ }]
+ }
+ },
+
+ // confiure minification
+ uglify: {
+ options: {
+ banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
+ },
+ build: {
+ src: [
+ // These are concatenated in order in the final build file.
+ // The order is important.
+ 'build/angular.min.js',
+ 'build/angular-route.min.js',
+ 'build/ui-bootstrap.js',
+ 'build/hotkeys.min.js',
+ // NOTE: OpenSRF must be installed
+ '/openils/lib/javascript/JSON_v1.js',
+ '/openils/lib/javascript/opensrf.js',
+ '/openils/lib/javascript/opensrf_ws.js',
+ 'services/core.js',
+ 'services/strings.js',
+ 'services/idl.js',
+ 'services/event.js',
+ 'services/net.js',
+ 'services/auth.js',
+ 'services/pcrud.js',
+ 'services/env.js',
+ 'services/org.js',
+ 'services/startup.js',
+ 'services/hatch.js',
+ 'services/coresvc.js',
+ 'services/statusbar.js',
+ 'services/ui.js',
+ 'navbar.js'
+ ],
+ dest: 'build/<%= pkg.name %>.<%= pkg.version %>.min.js'
+ }
+ },
+
+ // bare concat operation; useful for testing concat w/o minification
+ // to more easily detect when concat order is incorrect
+ concat: {
+ options: {
+ separator: ';',
+ }
+ },
+
+ // unit tests configuration
+ karma : {
+ unit: {
+ configFile: 'test/karma.conf.js',
+ //background: true // for now, visually babysit unit tests
+ }
+ }
+ };
+
+ // tell concat about our uglify build options (instead of repeating them)
+ config.concat.build = config.uglify.build;
+
+ // apply our configuration
+ grunt.initConfig(config);
+
+ // Load our modules
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+ grunt.loadNpmTasks('grunt-contrib-concat');
+ grunt.loadNpmTasks('grunt-contrib-copy');
+ grunt.loadNpmTasks('grunt-karma');
+
+ // note: "grunt concat" is not requried
+ grunt.registerTask('all', ['copy', 'karma:unit', 'uglify']);
+
+ // test only, no minification
+ grunt.registerTask('test', ['copy', 'karma:unit']);
+
+};
--- /dev/null
+{
+ "name": "evergreen-staff-client",
+ "description": "Evergreen ILS Browser Staff Client",
+ "version": "0.0.1",
+ "license": "GPL",
+ "homepage": "http://evergreen-ils.org/",
+ "devDependencies": {
+ "angular": "^1.2.16",
+ "angular-bootstrap": "0.0.4",
+ "angular-hotkeys": "^1.2.0",
+ "grunt": "~0.4.4",
+ "grunt-cli": "^0.1.13",
+ "grunt-contrib-concat": "^0.4.0",
+ "grunt-contrib-copy": "^0.5.0",
+ "grunt-contrib-jasmine": "^0.6.4",
+ "grunt-contrib-uglify": "^0.4.0",
+ "grunt-karma": "^0.8.3",
+ "karma": "^0.12.14",
+ "karma-jasmine": "^0.1.5",
+ "karma-phantomjs-launcher": "^0.1.4",
+ "karma-script-launcher": "~0.1.0",
+ "karma-story-reporter": "^0.2.2"
+ },
+ "napa": {
+ "angular-route": "angular/bower-angular-route",
+ "angular-mocks": "angular/bower-angular-mocks"
+ },
+ "scripts": {
+ "install": "napa",
+ "test": "grunt test"
+ }
+}
--- /dev/null
+module.exports = function(config){
+ config.set({
+ basePath : '../',
+
+ // config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ logLevel: config.LOG_DEBUG,
+
+ files : [
+ 'build/angular.min.js',
+ 'build/angular-route.min.js',
+ 'node_modules/angular-mocks/angular-mocks.js', // testing only
+ 'build/ui-bootstrap.js',
+ 'build/hotkeys.min.js',
+ /* OpenSRF must be installed first */
+ '/openils/lib/javascript/md5.js',
+ '/openils/lib/javascript/JSON_v1.js',
+ '/openils/lib/javascript/opensrf.js',
+ '/openils/lib/javascript/opensrf_ws.js',
+ // service/*.js have to be loaded in order
+ 'services/core.js',
+ 'services/idl.js',
+ 'services/strings.js',
+ 'services/event.js',
+ 'services/net.js',
+ 'services/auth.js',
+ 'services/pcrud.js',
+ 'services/env.js',
+ 'services/org.js',
+ 'services/hatch.js',
+ 'services/coresvc.js',
+ 'services/user.js',
+ 'services/startup.js',
+ 'services/ui.js',
+ 'services/statusbar.js',
+ 'services/grid.js',
+ // load app scripts
+ 'app.js',
+ 'navbar.js',
+ 'circ/**/*.js',
+ 'cat/**/*.js',
+ 'admin/**/*.js',
+ 'test/unit/**/*.js'
+ ],
+
+ // test results reporter to use
+ // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
+ reporters: ['progress', 'coverage'],
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch : false,
+
+ frameworks: ['jasmine'],
+
+ browsers: ['PhantomJS'],
+
+ // web server port
+ port: 9876,
+
+ /*
+ coverageReporter: {
+ type : 'html',
+ dir : 'coverage/',
+ },
+
+ preprocessors: {
+ '../src/*.js': ['coverage']
+ },
+ */
+
+ // If browser does not capture in given timeout [ms], kill it
+ captureTimeout: 60000,
+
+ // Continuous Integration mode
+ // if true, it capture browsers, run tests and exit
+ singleRun: true
+})}
--- /dev/null
+'use strict';
+
+describe('egHomeControllers', function(){
+ beforeEach(module('egHome'));
+
+ /* ---- LoginCtrl ---------------------------------- */
+
+ var loginCtrl, loginScope;
+ beforeEach(inject(function ($rootScope, $controller, $location) {
+ // pass the workstation name via (mock) URL param
+ $location.search({ws : 'TestWorkstation'});
+
+ loginScope = $rootScope.$new();
+ loginCtrl = $controller('LoginCtrl', {$scope: loginScope});
+ }));
+
+ it('should focus the login controller', inject(function() {
+ expect(loginScope.focusMe).toBe(true);
+ }));
+
+});
--- /dev/null
+'use strict';
+
+describe('egPatronAppTest', function(){
+ beforeEach(module('egPatronApp'));
+
+ // basic controller sanity checks
+
+ var patronCtrl, patronScope;
+ beforeEach(inject(function ($rootScope, $controller, $location) {
+ patronScope = $rootScope.$new();
+ patronCtrl = $controller('PatronCtrl', {$scope: patronScope});
+ }));
+
+ /** patronSvc tests **/
+ describe('patronSvcTests', function() {
+
+ it('patronSvc should start with empty lists', inject(function(patronSvc) {
+ expect(patronSvc.patrons.length).toEqual(0);
+ }));
+
+ it('patronSvc reset should clear data', inject(function(patronSvc) {
+ patronSvc.checkout_overrides.a = 1;
+ expect(Object.keys(patronSvc.checkout_overrides).length).toBe(1);
+ patronSvc.resetPatronLists();
+ expect(Object.keys(patronSvc.checkout_overrides).length).toBe(0);
+ expect(patronSvc.holds.length).toBe(0);
+ }));
+
+ });
+
+});