From 1bfc21270b80c6cd70d44b9c1af643003c4846db Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 28 Nov 2014 15:33:40 -0800 Subject: [PATCH] [Forms] Fill in specs Fill in specs for scripts which support the mct-form and mct-control directives. WTD-530. --- platform/forms/src/MCTForm.js | 8 +- .../src/controllers/DateTimeController.js | 3 +- platform/forms/test/MCTControlSpec.js | 48 ++++++++++++ platform/forms/test/MCTFormSpec.js | 78 +++++++++++++++++++ .../controllers/DateTimeControllerSpec.js | 29 +++++++ 5 files changed, 161 insertions(+), 5 deletions(-) diff --git a/platform/forms/src/MCTForm.js b/platform/forms/src/MCTForm.js index 986c4d2ddc..8414938171 100644 --- a/platform/forms/src/MCTForm.js +++ b/platform/forms/src/MCTForm.js @@ -8,7 +8,8 @@ define( function () { "use strict"; - var MATCH_ALL = /^.*$/; + // Default ng-pattern; any non whitespace + var NON_WHITESPACE = /\S/; /** * The mct-form directive allows generation of displayable @@ -37,8 +38,7 @@ define( ].join("/"); function controller($scope) { - var regexps = [], - matchAll = /.*/; + var regexps = []; // ng-pattern seems to want a RegExp, and not a // string (despite what documentation says) but @@ -47,7 +47,7 @@ define( function getRegExp(pattern) { // If undefined, don't apply a pattern if (!pattern) { - return MATCH_ALL; + return NON_WHITESPACE; } // Just echo if it's already a regexp diff --git a/platform/forms/src/controllers/DateTimeController.js b/platform/forms/src/controllers/DateTimeController.js index d5a08859f1..c1387318d8 100644 --- a/platform/forms/src/controllers/DateTimeController.js +++ b/platform/forms/src/controllers/DateTimeController.js @@ -1,8 +1,9 @@ -/*global define*/ +/*global define,moment*/ define( ["../../lib/moment.min"], function () { + "use strict"; var DATE_FORMAT = "YYYY-DDD"; diff --git a/platform/forms/test/MCTControlSpec.js b/platform/forms/test/MCTControlSpec.js index 39813afed6..448892758a 100644 --- a/platform/forms/test/MCTControlSpec.js +++ b/platform/forms/test/MCTControlSpec.js @@ -6,6 +6,54 @@ define( "use strict"; describe("The mct-control directive", function () { + var testControls, + mockScope, + mctControl; + + beforeEach(function () { + testControls = [ + { + key: "abc", + bundle: { path: "a", resources: "b" }, + templateUrl: "c/template.html" + }, + { + key: "xyz", + bundle: { path: "x", resources: "y" }, + templateUrl: "z/template.html" + } + ]; + + mockScope = jasmine.createSpyObj("$scope", [ "$watch" ]); + + mctControl = new MCTControl(testControls); + }); + + it("is restricted to the element level", function () { + expect(mctControl.restrict).toEqual("E"); + }); + + it("watches its passed key to choose a template", function () { + mctControl.controller(mockScope); + + expect(mockScope.$watch).toHaveBeenCalledWith( + "key", + jasmine.any(Function) + ); + }); + + it("changes its template dynamically", function () { + mctControl.controller(mockScope); + + mockScope.key = "xyz"; + mockScope.$watch.mostRecentCall.args[1]("xyz"); + + // Should have communicated the template path to + // ng-include via the "inclusion" field in scope + expect(mockScope.inclusion).toEqual( + "x/y/z/template.html" + ); + }); }); } diff --git a/platform/forms/test/MCTFormSpec.js b/platform/forms/test/MCTFormSpec.js index 2d64065c29..df30dbf4cc 100644 --- a/platform/forms/test/MCTFormSpec.js +++ b/platform/forms/test/MCTFormSpec.js @@ -6,6 +6,84 @@ define( "use strict"; describe("The mct-form directive", function () { + var mockScope, + mctForm; + + beforeEach(function () { + mockScope = jasmine.createSpyObj("$scope", [ "$watch" ]); + mockScope.$parent = {}; + mctForm = new MCTForm(); + }); + + it("is restricted to elements", function () { + expect(mctForm.restrict).toEqual("E"); + }); + + it("watches for changes in form by name", function () { + // mct-form needs to watch for the form by name + // in order to convey changes in $valid, $dirty, etc + // up to the parent scope. + mctForm.controller(mockScope); + + expect(mockScope.$watch).toHaveBeenCalledWith( + "mctForm", + jasmine.any(Function) + ); + }); + + it("conveys form status to parent scope", function () { + var someState = { someKey: "some value" }; + mockScope.name = "someName"; + + mctForm.controller(mockScope); + + mockScope.$watch.mostRecentCall.args[1](someState); + + expect(mockScope.$parent.someName).toBe(someState); + }); + + it("allows strings to be converted to RegExps", function () { + // This is needed to support ng-pattern in the template + mctForm.controller(mockScope); + + // Should have added getRegExp to the scope, + // to convert strings to regular expressions + expect(mockScope.getRegExp("^\\d+$")).toEqual(/^\d+$/); + }); + + it("returns the same regexp instance for the same string", function () { + // Don't want new instances each digest cycle, for performance + var strRegExp = "^[a-z]\\d+$", + regExp; + + // Add getRegExp to scope + mctForm.controller(mockScope); + regExp = mockScope.getRegExp(strRegExp); + + // Same object instance each time... + expect(mockScope.getRegExp(strRegExp)).toBe(regExp); + expect(mockScope.getRegExp(strRegExp)).toBe(regExp); + }); + + it("passes RegExp objects through untouched", function () { + // Permit using forms to simply provide their own RegExp object + var regExp = /^\d+[a-d]$/; + + // Add getRegExp to scope + mctForm.controller(mockScope); + + // Should have added getRegExp to the scope, + // to convert strings to regular expressions + expect(mockScope.getRegExp(regExp)).toBe(regExp); + }); + + it("passes a non-whitespace regexp when no pattern is defined", function () { + // If no pattern is supplied, ng-pattern should match anything + mctForm.controller(mockScope); + expect(mockScope.getRegExp()).toEqual(/\S/); + expect(mockScope.getRegExp(undefined)).toEqual(/\S/); + }); + }); } diff --git a/platform/forms/test/controllers/DateTimeControllerSpec.js b/platform/forms/test/controllers/DateTimeControllerSpec.js index 96039710d0..3b47068f15 100644 --- a/platform/forms/test/controllers/DateTimeControllerSpec.js +++ b/platform/forms/test/controllers/DateTimeControllerSpec.js @@ -6,6 +6,35 @@ define( "use strict"; describe("The date-time directive", function () { + var mockScope, + controller; + + beforeEach(function () { + mockScope = jasmine.createSpyObj("$scope", [ "$watch" ]); + controller = new DateTimeController(mockScope); + }); + + it("watches for changes in fields", function () { + ["date", "hour", "min", "sec"].forEach(function (fieldName) { + expect(mockScope.$watch).toHaveBeenCalledWith( + "datetime." + fieldName, + jasmine.any(Function) + ); + }); + }); + + it("converts date-time input into a timestamp", function () { + mockScope.ngModel = {}; + mockScope.field = "test"; + mockScope.datetime.date = "2014-332"; + mockScope.datetime.hour = 22; + mockScope.datetime.min = 55; + mockScope.datetime.sec = 13; + + mockScope.$watch.mostRecentCall.args[1](); + + expect(mockScope.ngModel.test).toEqual(1417215313000); + }); }); }