GUI -- Jasmine Unit Tests for fn.js.

Change-Id: I8a187dd04413329e6ab2884319deddc25344e3a0
diff --git a/web/gui/src/main/webapp/tests/README.txt b/web/gui/src/main/webapp/tests/README.txt
new file mode 100644
index 0000000..6cd2255
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/README.txt
@@ -0,0 +1 @@
+# Unit and integration tests for code under the /app directory
diff --git a/web/gui/src/main/webapp/tests/e2e/README.txt b/web/gui/src/main/webapp/tests/e2e/README.txt
new file mode 100644
index 0000000..4a23fa1
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/e2e/README.txt
@@ -0,0 +1,2 @@
+# End-to-End Tests (i.e. Scenario Tests)
+
diff --git a/web/gui/src/main/webapp/tests/fw/lib/fnSpec.js b/web/gui/src/main/webapp/tests/fw/lib/fnSpec.js
new file mode 100644
index 0000000..4bd1b4a
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/fw/lib/fnSpec.js
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2014 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- General Purpose Functions - Unit Tests
+
+ @author Simon Hunt
+ */
+describe('factory: fw/lib/fn.js', function() {
+    var fs,
+        someFunction = function () {},
+        someArray = [1, 2, 3],
+        someObject = { foo: 'bar'},
+        someNumber = 42,
+        someString = 'xyyzy',
+        someDate = new Date();
+
+    beforeEach(module('onosApp'));
+
+    beforeEach(inject(function (FnService) {
+        fs = FnService;
+    }));
+
+    it('should have ONOS defined', function () {
+        expect(ONOS).toBeDefined();
+    });
+
+    it('should have FnService defined', function () {
+        expect(fs).toBeDefined();
+    });
+
+
+    // === Tests for isF()
+    it('isF(): null for undefined', function () {
+        expect(fs.isF(undefined)).toBeNull();
+    });
+    it('isF(): null for null', function () {
+        expect(fs.isF(null)).toBeNull();
+    });
+    it('isF(): the reference for function', function () {
+        expect(fs.isF(someFunction)).toBe(someFunction);
+    });
+    it('isF(): null for string', function () {
+        expect(fs.isF(someString)).toBeNull();
+    });
+    it('isF(): null for number', function () {
+        expect(fs.isF(someNumber)).toBeNull();
+    });
+    it('isF(): null for Date', function () {
+        expect(fs.isF(someDate)).toBeNull();
+    });
+    it('isF(): null for array', function () {
+        expect(fs.isF(someArray)).toBeNull();
+    });
+    it('isF(): null for object', function () {
+        expect(fs.isF(someObject)).toBeNull();
+    });
+
+
+    // === Tests for isA()
+    it('isA(): null for undefined', function () {
+        expect(fs.isA(undefined)).toBeNull();
+    });
+    it('isA(): null for null', function () {
+        expect(fs.isA(null)).toBeNull();
+    });
+    it('isA(): null for function', function () {
+        expect(fs.isA(someFunction)).toBeNull();
+    });
+    it('isA(): null for string', function () {
+        expect(fs.isA(someString)).toBeNull();
+    });
+    it('isA(): null for number', function () {
+        expect(fs.isA(someNumber)).toBeNull();
+    });
+    it('isA(): null for Date', function () {
+        expect(fs.isA(someDate)).toBeNull();
+    });
+    it('isA(): the reference for array', function () {
+        expect(fs.isA(someArray)).toBe(someArray);
+    });
+    it('isA(): null for object', function () {
+        expect(fs.isA(someObject)).toBeNull();
+    });
+
+
+    // === Tests for isS()
+    it('isS(): null for undefined', function () {
+        expect(fs.isS(undefined)).toBeNull();
+    });
+    it('isS(): null for null', function () {
+        expect(fs.isS(null)).toBeNull();
+    });
+    it('isS(): null for function', function () {
+        expect(fs.isS(someFunction)).toBeNull();
+    });
+    it('isS(): the reference for string', function () {
+        expect(fs.isS(someString)).toBe(someString);
+    });
+    it('isS(): null for number', function () {
+        expect(fs.isS(someNumber)).toBeNull();
+    });
+    it('isS(): null for Date', function () {
+        expect(fs.isS(someDate)).toBeNull();
+    });
+    it('isS(): null for array', function () {
+        expect(fs.isS(someArray)).toBeNull();
+    });
+    it('isS(): null for object', function () {
+        expect(fs.isS(someObject)).toBeNull();
+    });
+
+
+    // === Tests for isO()
+    it('isO(): null for undefined', function () {
+        expect(fs.isO(undefined)).toBeNull();
+    });
+    it('isO(): null for null', function () {
+        expect(fs.isO(null)).toBeNull();
+    });
+    it('isO(): null for function', function () {
+        expect(fs.isO(someFunction)).toBeNull();
+    });
+    it('isO(): null for string', function () {
+        expect(fs.isO(someString)).toBeNull();
+    });
+    it('isO(): null for number', function () {
+        expect(fs.isO(someNumber)).toBeNull();
+    });
+    it('isO(): null for Date', function () {
+        expect(fs.isO(someDate)).toBeNull();
+    });
+    it('isO(): null for array', function () {
+        expect(fs.isO(someArray)).toBeNull();
+    });
+    it('isO(): the reference for object', function () {
+        expect(fs.isO(someObject)).toBe(someObject);
+    });
+});
diff --git a/web/gui/src/main/webapp/tests/karma.conf.js b/web/gui/src/main/webapp/tests/karma.conf.js
new file mode 100644
index 0000000..5a25638
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/karma.conf.js
@@ -0,0 +1,77 @@
+// Karma configuration
+
+module.exports = function(config) {
+  config.set({
+
+    // base path that will be used to resolve all patterns (eg. files, exclude)
+    basePath: '',
+
+
+    // frameworks to use
+    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+    frameworks: ['jasmine'],
+
+
+    // list of files / patterns to load in the browser
+    files: [
+        // library code...
+        '../tp/angular.js',
+        '../tp/angular-mocks.js',
+        '../tp/d3.js',
+        '../tp/topojson.v1.min.js',
+        '../tp/jquery-2.1.1.min.js',
+
+        // production code...
+        '../app/onos.js',
+        '../app/fw/lib/*.js',
+        '../app/fw/mast/*.js',
+
+        // unit test code...
+        'fw/lib/*.js'
+    ],
+
+
+    // list of files to exclude
+    exclude: [
+    ],
+
+
+    // preprocess matching files before serving them to the browser
+    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+    preprocessors: {
+    },
+
+
+    // test results reporter to use
+    // possible values: 'dots', 'progress'
+    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
+    reporters: ['progress'],
+
+
+    // 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: true,
+
+
+    // start these browsers
+    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
+    browsers: ['Chrome'],
+
+
+    // Continuous Integration mode
+    // if true, Karma captures browsers, runs the tests and exits
+    singleRun: false
+  });
+};