From 2824b43b7332e847810f042c4183ce95ee90e852 Mon Sep 17 00:00:00 2001 From: Bernhard Posselt Date: Mon, 9 Sep 2013 15:57:10 +0200 Subject: use bower for managing deps --- .../modules/directives/animate/animate.js | 36 +++ .../modules/directives/animate/test/animateSpec.js | 71 +++++ .../modules/directives/calendar/calendar.js | 66 ++++ .../modules/directives/calendar/dependencies.json | 8 + .../directives/calendar/test/calendarSpec.js | 216 +++++++++++++ .../modules/directives/codemirror/codemirror.js | 77 +++++ .../directives/codemirror/dependencies.json | 8 + .../directives/codemirror/test/codemirrorSpec.js | 160 ++++++++++ .../modules/directives/currency/README.md | 46 +++ .../modules/directives/currency/currency.js | 45 +++ .../directives/currency/stylesheets/currency.less | 14 + .../directives/currency/test/currencySpec.js | 95 ++++++ .../angular-ui/modules/directives/date/README.md | 73 +++++ .../angular-ui/modules/directives/date/date.js | 111 +++++++ .../modules/directives/date/dependencies.json | 5 + .../modules/directives/date/test/dateSpec.js | 354 +++++++++++++++++++++ .../angular-ui/modules/directives/event/event.js | 27 ++ .../modules/directives/event/test/eventSpec.js | 79 +++++ js/vendor/angular-ui/modules/directives/if/if.js | 39 +++ .../modules/directives/if/test/ifSpec.js | 57 ++++ .../angular-ui/modules/directives/jq/README.md | 112 +++++++ js/vendor/angular-ui/modules/directives/jq/jq.js | 64 ++++ .../modules/directives/jq/test/jqSpec.js | 111 +++++++ .../modules/directives/keypress/keypress.js | 110 +++++++ .../directives/keypress/test/keydownSpec.js | 67 ++++ .../directives/keypress/test/keypressSpec.js | 67 ++++ .../modules/directives/keypress/test/keyupSpec.js | 67 ++++ js/vendor/angular-ui/modules/directives/map/map.js | 125 ++++++++ .../modules/directives/map/test/mapSpec.js | 102 ++++++ .../modules/directives/mask/dependencies.json | 5 + .../angular-ui/modules/directives/mask/mask.js | 38 +++ .../modules/directives/mask/test/maskSpec.js | 47 +++ .../angular-ui/modules/directives/reset/reset.js | 26 ++ .../directives/reset/stylesheets/reset.less | 18 ++ .../modules/directives/reset/test/resetSpec.js | 55 ++++ .../angular-ui/modules/directives/route/route.js | 68 ++++ .../modules/directives/route/test/routeSpec.js | 98 ++++++ .../modules/directives/scrollfix/scrollfix.js | 39 +++ .../directives/scrollfix/test/scrollfixSpec.js | 39 +++ .../modules/directives/select2/dependencies.json | 8 + .../modules/directives/select2/select2.js | 124 ++++++++ .../modules/directives/select2/test/select2Spec.js | 144 +++++++++ .../modules/directives/showhide/showhide.js | 60 ++++ .../directives/showhide/test/showhideSpec.js | 104 ++++++ .../modules/directives/sortable/REDME.md | 54 ++++ .../modules/directives/sortable/sortable.js | 112 +++++++ .../directives/sortable/test/sortableSpec.js | 40 +++ .../modules/directives/tinymce/dependencies.json | 8 + .../modules/directives/tinymce/test/tinymceSpec.js | 90 ++++++ .../modules/directives/tinymce/tinymce.js | 53 +++ .../directives/validate/test/validateSpec.js | 164 ++++++++++ .../modules/directives/validate/validate.js | 66 ++++ 52 files changed, 3872 insertions(+) create mode 100644 js/vendor/angular-ui/modules/directives/animate/animate.js create mode 100644 js/vendor/angular-ui/modules/directives/animate/test/animateSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/calendar/calendar.js create mode 100644 js/vendor/angular-ui/modules/directives/calendar/dependencies.json create mode 100644 js/vendor/angular-ui/modules/directives/calendar/test/calendarSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/codemirror/codemirror.js create mode 100644 js/vendor/angular-ui/modules/directives/codemirror/dependencies.json create mode 100644 js/vendor/angular-ui/modules/directives/codemirror/test/codemirrorSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/currency/README.md create mode 100644 js/vendor/angular-ui/modules/directives/currency/currency.js create mode 100644 js/vendor/angular-ui/modules/directives/currency/stylesheets/currency.less create mode 100644 js/vendor/angular-ui/modules/directives/currency/test/currencySpec.js create mode 100644 js/vendor/angular-ui/modules/directives/date/README.md create mode 100644 js/vendor/angular-ui/modules/directives/date/date.js create mode 100644 js/vendor/angular-ui/modules/directives/date/dependencies.json create mode 100644 js/vendor/angular-ui/modules/directives/date/test/dateSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/event/event.js create mode 100644 js/vendor/angular-ui/modules/directives/event/test/eventSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/if/if.js create mode 100644 js/vendor/angular-ui/modules/directives/if/test/ifSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/jq/README.md create mode 100644 js/vendor/angular-ui/modules/directives/jq/jq.js create mode 100644 js/vendor/angular-ui/modules/directives/jq/test/jqSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/keypress/keypress.js create mode 100644 js/vendor/angular-ui/modules/directives/keypress/test/keydownSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/keypress/test/keypressSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/keypress/test/keyupSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/map/map.js create mode 100644 js/vendor/angular-ui/modules/directives/map/test/mapSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/mask/dependencies.json create mode 100644 js/vendor/angular-ui/modules/directives/mask/mask.js create mode 100644 js/vendor/angular-ui/modules/directives/mask/test/maskSpec.js create mode 100755 js/vendor/angular-ui/modules/directives/reset/reset.js create mode 100644 js/vendor/angular-ui/modules/directives/reset/stylesheets/reset.less create mode 100755 js/vendor/angular-ui/modules/directives/reset/test/resetSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/route/route.js create mode 100644 js/vendor/angular-ui/modules/directives/route/test/routeSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/scrollfix/scrollfix.js create mode 100644 js/vendor/angular-ui/modules/directives/scrollfix/test/scrollfixSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/select2/dependencies.json create mode 100644 js/vendor/angular-ui/modules/directives/select2/select2.js create mode 100644 js/vendor/angular-ui/modules/directives/select2/test/select2Spec.js create mode 100644 js/vendor/angular-ui/modules/directives/showhide/showhide.js create mode 100644 js/vendor/angular-ui/modules/directives/showhide/test/showhideSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/sortable/REDME.md create mode 100644 js/vendor/angular-ui/modules/directives/sortable/sortable.js create mode 100644 js/vendor/angular-ui/modules/directives/sortable/test/sortableSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/tinymce/dependencies.json create mode 100644 js/vendor/angular-ui/modules/directives/tinymce/test/tinymceSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/tinymce/tinymce.js create mode 100644 js/vendor/angular-ui/modules/directives/validate/test/validateSpec.js create mode 100644 js/vendor/angular-ui/modules/directives/validate/validate.js (limited to 'js/vendor/angular-ui/modules/directives') diff --git a/js/vendor/angular-ui/modules/directives/animate/animate.js b/js/vendor/angular-ui/modules/directives/animate/animate.js new file mode 100644 index 000000000..430874bb0 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/animate/animate.js @@ -0,0 +1,36 @@ +/** + * Animates the injection of new DOM elements by simply creating the DOM with a class and then immediately removing it + * Animations must be done using CSS3 transitions, but provide excellent flexibility + * + * @todo Add proper support for animating out + * @param [options] {mixed} Can be an object with multiple options, or a string with the animation class + * class {string} the CSS class(es) to use. For example, 'ui-hide' might be an excellent alternative class. + * @example
  • {{item}}
  • + */ +angular.module('ui.directives').directive('uiAnimate', ['ui.config', '$timeout', function (uiConfig, $timeout) { + var options = {}; + if (angular.isString(uiConfig.animate)) { + options['class'] = uiConfig.animate; + } else if (uiConfig.animate) { + options = uiConfig.animate; + } + return { + restrict: 'A', // supports using directive as element, attribute and class + link: function ($scope, element, attrs) { + var opts = {}; + if (attrs.uiAnimate) { + opts = $scope.$eval(attrs.uiAnimate); + if (angular.isString(opts)) { + opts = {'class': opts}; + } + } + opts = angular.extend({'class': 'ui-animate'}, options, opts); + + element.addClass(opts['class']); + $timeout(function () { + element.removeClass(opts['class']); + }, 20, false); + } + }; +}]); + diff --git a/js/vendor/angular-ui/modules/directives/animate/test/animateSpec.js b/js/vendor/angular-ui/modules/directives/animate/test/animateSpec.js new file mode 100644 index 000000000..219f499a8 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/animate/test/animateSpec.js @@ -0,0 +1,71 @@ +/* + * sample unit testing for sample templates and implementations + */ +describe('uiAnimate', function () { + + // declare these up here to be global to all tests + var $rootScope, $compile, $timeout, uiConfig = angular.module('ui.config'); + + beforeEach(module('ui.directives')); + + // inject in angular constructs. Injector knows about leading/trailing underscores and does the right thing + // otherwise, you would need to inject these into each test + beforeEach(inject(function (_$rootScope_, _$compile_, _$timeout_) { + $rootScope = _$rootScope_; + $compile = _$compile_; + $timeout = _$timeout_; + })); + + afterEach(function () { + uiConfig.value('ui.config', {}); + }); + + describe('behavior', function () { + it('should add a ui-animate class when the dom is compiled', function () { + var element = $compile('
    ')($rootScope); + expect(element.hasClass('ui-animate')).toBeTruthy(); + }); + it('should remove the ui-animate class immediately after injection', function () { + var element = $compile('
    ')($rootScope); + $timeout.flush(); + expect(element.hasClass('ui-animate')).toBeFalsy(); + }); + + }); + + describe('options', function () { + describe('passed', function () { + + it('should use a string as the class', function () { + var element = $compile('
    ')($rootScope); + expect(element.hasClass('ui-hide')).toBeTruthy(); + }); + it('should use an object\'s class attribute as the class', function () { + var element = $compile('
    ')($rootScope); + expect(element.hasClass('ui-hide')).toBeTruthy(); + }); + + }); + describe('global', function () { + + var uiConfig; + beforeEach(inject(function ($injector) { + uiConfig = $injector.get('ui.config'); + })); + + it('should use a string as the class', function () { + uiConfig.animate = 'ui-hide-global'; + var element = $compile('
    ')($rootScope); + expect(element.hasClass('ui-hide-global')).toBeTruthy(); + }); + + it('should use an object\'s class attribute as the class', function () { + uiConfig.animate = { 'class': 'ui-hide-global' }; + var element = $compile('
    ')($rootScope); + expect(element.hasClass('ui-hide-global')).toBeTruthy(); + }); + + }); + }); + +}); diff --git a/js/vendor/angular-ui/modules/directives/calendar/calendar.js b/js/vendor/angular-ui/modules/directives/calendar/calendar.js new file mode 100644 index 000000000..9aca0b057 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/calendar/calendar.js @@ -0,0 +1,66 @@ +/* +* AngularJs Fullcalendar Wrapper for the JQuery FullCalendar +* API @ http://arshaw.com/fullcalendar/ +* +* Angular Calendar Directive that takes in the [eventSources] nested array object as the ng-model and watches (eventSources.length + eventSources[i].length) for changes. +* Can also take in multiple event urls as a source object(s) and feed the events per view. +* The calendar will watch any eventSource array and update itself when a delta is created +* An equalsTracker attrs has been added for use cases that would render the overall length tracker the same even though the events have changed to force updates. +* +*/ + +angular.module('ui.directives').directive('uiCalendar',['ui.config', '$parse', function (uiConfig,$parse) { + uiConfig.uiCalendar = uiConfig.uiCalendar || {}; + //returns calendar + return { + require: 'ngModel', + restrict: 'A', + link: function(scope, elm, attrs, $timeout) { + var sources = scope.$eval(attrs.ngModel); + var tracker = 0; + /* returns the length of all source arrays plus the length of eventSource itself */ + var getSources = function () { + var equalsTracker = scope.$eval(attrs.equalsTracker); + tracker = 0; + angular.forEach(sources,function(value,key){ + if(angular.isArray(value)){ + tracker += value.length; + } + }); + if(angular.isNumber(equalsTracker)){ + return tracker + sources.length + equalsTracker; + }else{ + return tracker + sources.length; + } + }; + /* update the calendar with the correct options */ + function update() { + //calendar object exposed on scope + scope.calendar = elm.html(''); + var view = scope.calendar.fullCalendar('getView'); + if(view){ + view = view.name; //setting the default view to be whatever the current view is. This can be overwritten. + } + /* If the calendar has options added then render them */ + var expression, + options = { + defaultView : view, + eventSources: sources + }; + if (attrs.uiCalendar) { + expression = scope.$eval(attrs.uiCalendar); + } else { + expression = {}; + } + angular.extend(options, uiConfig.uiCalendar, expression); + scope.calendar.fullCalendar(options); + } + update(); + /* watches all eventSources */ + scope.$watch(getSources, function( newVal, oldVal ) + { + update(); + }); + } + }; +}]); \ No newline at end of file diff --git a/js/vendor/angular-ui/modules/directives/calendar/dependencies.json b/js/vendor/angular-ui/modules/directives/calendar/dependencies.json new file mode 100644 index 000000000..c700ce2ce --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/calendar/dependencies.json @@ -0,0 +1,8 @@ +{ + "core": [ "jquery" ], + "internal": [], + "external": [ + "http://arshaw.com/js/fullcalendar-1.5.4/fullcalendar/fullcalendar.css", + "http://arshaw.com/js/fullcalendar-1.5.4/fullcalendar/fullcalendar.js" + ] +} \ No newline at end of file diff --git a/js/vendor/angular-ui/modules/directives/calendar/test/calendarSpec.js b/js/vendor/angular-ui/modules/directives/calendar/test/calendarSpec.js new file mode 100644 index 000000000..b3e9ac01b --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/calendar/test/calendarSpec.js @@ -0,0 +1,216 @@ +/*global beforeEach, afterEach, describe, it, inject, expect, module, spyOn, fullcalendar, angular, $*/ +describe('uiCalendar', function () { + 'use strict'; + + var scope, $compile; + + beforeEach(module('ui')); + beforeEach(inject(function (_$rootScope_, _$compile_) { + scope = _$rootScope_.$new(); + $compile = _$compile_; + + + //Date Objects needed for event + var date = new Date(); + var d = date.getDate(); + var m = date.getMonth(); + var y = date.getFullYear(); + + // create an array of events, to pass into the directive. + scope.events = [ + {title: 'All Day Event',start: new Date(y, m, 1),url: 'http://www.angularjs.org'}, + {title: 'Long Event',start: new Date(y, m, d - 5),end: new Date(y, m, d - 2)}, + {id: 999,title: 'Repeating Event',start: new Date(y, m, d - 3, 16, 0),allDay: false}, + {id: 999,title: 'Repeating Event',start: new Date(y, m, d + 4, 16, 0),allDay: true}]; + + // create an array of events, to pass into the directive. + scope.events2 = [ + {title: 'All Day Event 2',start: new Date(y, m, 1),url: 'http://www.atlantacarlocksmith.com'}, + {title: 'Long Event 2',start: new Date(y, m, d - 5),end: new Date(y, m, d - 2)}, + {id: 998,title: 'Repeating Event 2',start: new Date(y, m, d - 3, 16, 0),allDay: false}, + {id: 998,title: 'Repeating Event 2',start: new Date(y, m, d + 4, 16, 0),allDay: true}]; + //array to test equalsTracker with + scope.events3 = [ + {title: 'All Day Event 3',start: new Date(y, m, 1),url: 'http://www.atlantacarlocksmith.com'}, + {title: 'Long Event 3',start: new Date(y, m, d - 5),end: new Date(y, m, d - 2)}, + {id: 998,title: 'Repeating Event 3',start: new Date(y, m, d - 3, 16, 0),allDay: false}, + {id: 998,title: 'Repeating Event 3',start: new Date(y, m, d + 4, 16, 0),allDay: true}]; + + // create an array of events, to pass into the directive. + scope.events4 = [{title: 'All Day Event 3',start: new Date(y, m, 1),url: 'http://www.yoyoyo.com'}]; + + //equalsTracker to force the calendar to update on rare occasions + //ie... an event source is replacing another and has the same length as the prior eventSource + //or... replacing an eventSource that is an object with another eventSource + scope.equalsTracker = 0; + + //event Sources array + scope.eventSources = [scope.events,scope.events2]; //End of Events Array + + scope.addSource = function(source) { + scope.eventSources.push(source); + }; + + scope.addChild = function(array) { + array.push({ + title: 'Click for Google ' + scope.events.length, + start: new Date(y, m, 28), + end: new Date(y, m, 29), + url: 'http://google.com/' + }); + }; + + scope.remove = function(array,index) { + array.splice(index,1); + }; + + scope.uiConfig = { + calendar:{ + height: 200, + weekends: false, + defaultView: 'month' + } + }; + + })); + + afterEach(function() { + angular.module('ui.config').value('ui.config', {}); // cleanup + }); + + describe('compiling this directive and checking for events inside the calendar', function () { + + + /* test the calendar's events length */ + it('should excpect to load 4 events to scope', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length).toBe(4); + }); + /* test to check the title of the first event. */ + it('should excpect to be All Day Event', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].eventSources[0][0].title).toBe('All Day Event'); + }); + /* test to make sure the event has a url assigned to it. */ + it('should expect the url to = http://www.angularjs.org', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].eventSources[0][0].url).toBe('http://www.angularjs.org'); + expect($.fn.fullCalendar.mostRecentCall.args[0].eventSources[1][0].url).toBe('http://www.atlantacarlocksmith.com'); + }); + /* test the 3rd events' allDay field. */ + it('should expect the fourth Events all Day field to equal true', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].eventSources[0][3].allDay).toNotBe(false); + }); + /* Tests the height of the calendar. */ + it('should expect the calendar attribute height to be 200', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].height).toEqual(200); + }); + /* Tests the weekends boolean of the calendar. */ + it('should expect the calendar attribute weekends to be false', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].weekends).toEqual(false); + }); + /* Test to make sure that when an event is added to the calendar everything is updated with the new event. */ + it('should expect the scopes events to increase by 2', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length).toEqual(4); + scope.addChild(scope.events); + scope.addChild(scope.events); + expect($.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length).toEqual(6); + }); + /* Test to make sure the calendar is updating itself on changes to events length. */ + it('should expect the calendar to update itself with new events', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + var clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length; + expect(clientEventsLength).toEqual(4); + //remove an event from the scope. + scope.remove(scope.events,0); + //events should auto update inside the calendar. + clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length; + expect(clientEventsLength).toEqual(3); + }); + /* Test to make sure header options can be overwritten */ + it('should overwrite default header options', function () { + spyOn($.fn, 'fullCalendar'); + scope.uiConfig2 = { + calendar:{ + header: {center: 'title'} + } + }; + $compile('
    ')(scope); + expect($.fn.fullCalendar.mostRecentCall.args[0].hasOwnProperty('header')).toEqual(true); + var header = $.fn.fullCalendar.mostRecentCall.args[0].header; + expect(header).toEqual({center: 'title'}); + }); + /* Test to see if calendar is watching all eventSources for changes. */ + it('should update the calendar if any eventSource array contains a delta', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + var clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length; + var clientEventsLength2 = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[1].length; + expect(clientEventsLength).toEqual(4); + expect(clientEventsLength2).toEqual(4); + //remove an event from the scope. + scope.remove(scope.events2,0); + //events should auto update inside the calendar. + clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length; + clientEventsLength2 = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[1].length; + expect(clientEventsLength).toEqual(4); + expect(clientEventsLength2).toEqual(3); + scope.remove(scope.events,0); + clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length; + expect(clientEventsLength).toEqual(3); + }); + /* Test to see if calendar is updating when a new eventSource is added. */ + it('should update the calendar if an eventSource is Added', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + var clientEventSources = $.fn.fullCalendar.mostRecentCall.args[0].eventSources.length; + expect(clientEventSources).toEqual(2); + //add new source to calendar + scope.addSource(scope.events4); + //eventSources should auto update inside the calendar. + clientEventSources = $.fn.fullCalendar.mostRecentCall.args[0].eventSources.length; + expect(clientEventSources).toEqual(3); + //go ahead and add some more events to the array and check those too. + scope.addChild(scope.events4); + var clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[2].length; + expect(clientEventsLength).toEqual(2); + }); + /* Test to see if calendar is updating when an eventSource replaces another with an equal length. */ + it('should update the calendar if an eventSource has same length as prior eventSource', function () { + spyOn($.fn, 'fullCalendar'); + $compile('
    ')(scope); + var clientEventSources = $.fn.fullCalendar.mostRecentCall.args[0].eventSources; + var clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length; + expect(clientEventsLength).toEqual(4); + expect(clientEventSources.length).toEqual(2); + expect(clientEventSources[1][0].title).toEqual('All Day Event 2'); + //replace source with one that has the same length + scope.eventSources.splice(1,1,scope.events3); + //must update the equalsTracker as we would detect that the length is equal from controller + scope.equalsTracker++; + //eventSources should update inside the calendar since we incremented the equalsTracker + clientEventSources = $.fn.fullCalendar.mostRecentCall.args[0].eventSources; + expect(clientEventSources.length).toEqual(2); + expect(clientEventSources[1][0].title).toEqual('All Day Event 3'); + //remove an event to prove autobinding still works + scope.remove(scope.events,0); + clientEventsLength = $.fn.fullCalendar.mostRecentCall.args[0].eventSources[0].length; + expect(clientEventsLength).toEqual(3); + + }); + + }); + +}); diff --git a/js/vendor/angular-ui/modules/directives/codemirror/codemirror.js b/js/vendor/angular-ui/modules/directives/codemirror/codemirror.js new file mode 100644 index 000000000..403c1cc48 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/codemirror/codemirror.js @@ -0,0 +1,77 @@ +/*global angular, CodeMirror, Error*/ +/** + * Binds a CodeMirror widget to a ')(scope); + } + + expect(compile).not.toThrow(); + }); + + it('should throw an error when no ngModel attribute defined', function () { + function compile() { + $compile('')(scope); + } + + expect(compile).toThrow(); + }); + + it('should watch the uiCodemirror attribute', function () { + spyOn(scope, '$watch'); + $compile('')(scope); + $timeout.flush(); + expect(scope.$watch).toHaveBeenCalled(); + }); + + }); + + describe('while spying on the CodeMirror instance', function () { + + var codemirror; + + beforeEach(function () { + var fromTextArea = CodeMirror.fromTextArea; + spyOn(CodeMirror, 'fromTextArea').andCallFake(function () { + codemirror = fromTextArea.apply(this, arguments); + return codemirror; + }); + }); + + describe('verify the directive options', function () { + it('should include the passed options', function () { + $compile('')(scope); + $timeout.flush(); + expect(CodeMirror.fromTextArea.mostRecentCall.args[1].oof).toEqual("baar"); + }); + + it('should include the default options', function () { + $compile('')(scope); + $timeout.flush(); + expect(CodeMirror.fromTextArea.mostRecentCall.args[1].bar).toEqual('baz'); + }); + }); + + describe('when uiRefresh is added', function () { + it('should trigger the CodeMirror.refresh() method', function () { + $compile('')(scope); + $timeout.flush(); + spyOn(codemirror, 'refresh'); + scope.$apply('bar = true'); + $timeout.flush(); + expect(codemirror.refresh).toHaveBeenCalled(); + }); + }); + + + describe('when the IDE changes', function () { + it('should update the model', function () { + $compile('')(scope); + scope.$apply("foo = 'bar'"); + $timeout.flush(); + var value = 'baz'; + codemirror.setValue(value); + expect(scope.foo).toBe(value); + }); + }); + + describe('when the model changes', function () { + it('should update the IDE', function () { + var element = $compile('')(scope); + scope.foo = 'bar'; + scope.$apply(); + $timeout.flush(); + expect(codemirror.getValue()).toBe(scope.foo); + }); + }); + + describe('when the model is undefined/null', function () { + it('should update the IDE with an empty string', function () { + var element = $compile('')(scope); + scope.$apply(); + $timeout.flush(); + expect(scope.foo).toBe(undefined); + expect(codemirror.getValue()).toBe(''); + scope.$apply('foo = "bar"'); + expect(scope.foo).toBe('bar'); + expect(codemirror.getValue()).toBe('bar'); + scope.$apply('foo = null'); + expect(scope.foo).toBe(null); + expect(codemirror.getValue()).toBe(''); + }); + }); + }); + + describe('when the model is an object or an array', function () { + it('should throw an error', function () { + function compileWithObject() { + $compile('')(scope); + $timeout.flush(); + scope.foo = {}; + scope.$apply(); + } + + function compileWithArray() { + $compile('')(scope); + $timeout.flush(); + scope.foo = []; + scope.$apply(); + } + + expect(compileWithObject).toThrow(); + expect(compileWithArray).toThrow(); + }); + }); +}); \ No newline at end of file diff --git a/js/vendor/angular-ui/modules/directives/currency/README.md b/js/vendor/angular-ui/modules/directives/currency/README.md new file mode 100644 index 000000000..7959201a5 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/currency/README.md @@ -0,0 +1,46 @@ +# ui-currency directive + +This directive gives greater control over your currency elements by allowing you to set CSS styles based on the number's sign. +In angular, you are only able to specify what the currency symbol is (however, you might not want to change it for localization). + +## Usage + +Apply the directive to your html elements: + + myAppModule.controller('MyController', function($scope) { + $scope.SomeNumber = 123; + }); + + + +Default styles are in angular-ui.css and are pretty boring, you could just override these in your +stylesheet and make things most excellent (e.g. increasing size for negatives, doing a hover sorta thingy ) + + .ui-currency-pos { + color: green; + } + .ui-currency-neg { + color: red; + } + .ui-currency-zero { + color: blue; + } + .ui-currency-pos.ui-bignum, .ui-currency-neg.ui-smallnum { + font-size: 110%; + } + +### Options + +All the options can be controlled by ui.config (see Global Defaults) or passed in the ui-currency attribute on the declaration. +The symbol attribute defaults to null and is then controlled by the default locale settings. + + + +If the model is greater than or equal to 1000 add ui-bignum to css class, if less than or equal to -1000 add ui-small num. If attr is-total attribute +is set the bignum/smallnum is not applied. This is useful if the options are global and you don't want totals to necessarily have these classes. + +### Notes + +This directive wraps angular's currency filter. If that changes, you are on your own. + + \ No newline at end of file diff --git a/js/vendor/angular-ui/modules/directives/currency/currency.js b/js/vendor/angular-ui/modules/directives/currency/currency.js new file mode 100644 index 000000000..97ad384e6 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/currency/currency.js @@ -0,0 +1,45 @@ +/* + Gives the ability to style currency based on its sign. + */ +angular.module('ui.directives').directive('uiCurrency', ['ui.config', 'currencyFilter' , function (uiConfig, currencyFilter) { + var options = { + pos: 'ui-currency-pos', + neg: 'ui-currency-neg', + zero: 'ui-currency-zero' + }; + if (uiConfig.currency) { + angular.extend(options, uiConfig.currency); + } + return { + restrict: 'EAC', + require: 'ngModel', + link: function (scope, element, attrs, controller) { + var opts, // instance-specific options + renderview, + value; + + opts = angular.extend({}, options, scope.$eval(attrs.uiCurrency)); + + renderview = function (viewvalue) { + var num; + num = viewvalue * 1; + element.toggleClass(opts.pos, (num > 0) ); + element.toggleClass(opts.neg, (num < 0) ); + element.toggleClass(opts.zero, (num === 0) ); + if (viewvalue === '') { + element.text(''); + } else { + element.text(currencyFilter(num, opts.symbol)); + } + return true; + }; + + controller.$render = function () { + value = controller.$viewValue; + element.val(value); + renderview(value); + }; + + } + }; +}]); diff --git a/js/vendor/angular-ui/modules/directives/currency/stylesheets/currency.less b/js/vendor/angular-ui/modules/directives/currency/stylesheets/currency.less new file mode 100644 index 000000000..e1ab0afd2 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/currency/stylesheets/currency.less @@ -0,0 +1,14 @@ + +/* ui-currency */ +.ui-currency-pos { + color: green; +} +.ui-currency-neg { + color: red; +} +.ui-currency-zero { + color: blue; +} +.ui-currency-pos.ui-bignum, .ui-currency-neg.ui-smallnum { + font-size: 110%; +} diff --git a/js/vendor/angular-ui/modules/directives/currency/test/currencySpec.js b/js/vendor/angular-ui/modules/directives/currency/test/currencySpec.js new file mode 100644 index 000000000..bbbc71fd9 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/currency/test/currencySpec.js @@ -0,0 +1,95 @@ +describe('uiCurrency', function () { + var scope; + beforeEach(module('ui')); + beforeEach(inject(function ($rootScope) { + scope = $rootScope.$new(); + })); + describe('use on a div element with two-way binding', function () { + it('should have ui-currency-pos style non-zero positive model number ', function () { + inject(function ($compile) { + var element; + element = $compile("
    ")(scope); + scope.$apply(function () { + scope.aNum = 0.5123; + }); + expect(element.text()).toEqual('$0.51'); + expect(element.hasClass('ui-currency-pos')).toBeTruthy(); + expect(element.hasClass('ui-currency-neg')).toBeFalsy(); + expect(element.hasClass('ui-currency-zero')).toBeFalsy(); + }); + }); + it('should have ui-currency-neg style when negative model number', function () { + inject(function ($compile) { + var element; + element = $compile("
    ")(scope); + scope.$apply(function () { + scope.aNum = -123; + }); + expect(element.text()).toEqual('($123.00)'); + expect(element.hasClass('ui-currency-pos')).toBeFalsy(); + expect(element.hasClass('ui-currency-neg')).toBeTruthy(); + }); + }); + it('should have ui-currency-zero style when zero model number', function () { + inject(function ($compile) { + var element; + element = $compile("
    ")(scope); + scope.$apply(function () { + scope.aNum = 0; + }); + expect(element.text()).toEqual('$0.00'); + expect(element.hasClass('ui-currency-pos')).toBeFalsy(); + expect(element.hasClass('ui-currency-neg')).toBeFalsy(); + expect(element.hasClass('ui-currency-zero')).toBeTruthy(); + }); + }); + it('should not have any ui-currency styles or a value at all when missing scope model value', function () { + inject(function ($compile) { + var element; + element = $compile("
    ")(scope); + expect(element.text()).toEqual(''); + expect(element.hasClass('ui-currency-pos')).toBeFalsy(); + expect(element.hasClass('ui-currency-neg')).toBeFalsy(); + expect(element.hasClass('ui-currency-zero')).toBeFalsy(); + }); + }); + it('should not have any ui-currency styles or a value at all when provided a non-numeric model value', function () { + inject(function ($compile) { + var element; + element = $compile("
    ")(scope); + scope.$apply(function () { + scope.aBadNum = 'bad'; + }); + expect(element.text()).toEqual(''); + expect(element.hasClass('ui-currency-pos')).toBeFalsy(); + expect(element.hasClass('ui-currency-neg')).toBeFalsy(); + expect(element.hasClass('ui-currency-zero')).toBeFalsy(); + }); + }); + + it('should have user-defined positive style when provided in uiCurrency attr', function () { + inject(function ($compile) { + var element; + element = $compile("
    ")(scope); + scope.$apply(function () { + scope.aNum = 1; + }); + expect(element.hasClass('pstyle')).toBeTruthy(); + }); + }); + // Presumption is if above works then no need to test other cases, given the coverage in previous describe + }); + describe('use on a tag element', function () { + it('should have a defined element', function () { + inject(function ($compile) { + var element; + element = $compile("")(scope); + scope.$apply(function () { + scope.aNum = 1; + }); + expect(element).toBeDefined(); + expect(element.text()).toEqual('$1.00'); + }); + }); + }); +}); \ No newline at end of file diff --git a/js/vendor/angular-ui/modules/directives/date/README.md b/js/vendor/angular-ui/modules/directives/date/README.md new file mode 100644 index 000000000..71f15d933 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/date/README.md @@ -0,0 +1,73 @@ +# ui-date directive + +This directive allows you to add a date-picker to your form elements. + +# Requirements + +- JQuery +- JQueryUI +- [Date.toISOString()](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString) (requires [polyfill](https://github.com/kriskowal/es5-shim/) for ≤IE8) + +# Usage + +Load the script file in your application: + + + +Add the date module as a dependency to your application module: + + var myAppModule = angular.module('MyApp', ['ui.directives']) + +Apply the directive to your form elements: + + + +## Options + +All the jQueryUI DatePicker options can be passed through the directive. + + myAppModule.controller('MyController', function($scope) { + $scope.dateOptions = { + changeYear: true, + changeMonth: true, + yearRange: '1900:-0' + }; + }); + + + +## Static Inline Picker + +If you want a static picker then simply apply the directive to a div rather than an input element. + +
    + +# Working with ng-model + +The ui-date directive plays nicely with ng-model and validation directives such as ng-required. + +If you add the ng-model directive to same the element as ui-date then the picked date is automatically synchronized with the model value. + +_The ui-date directive stores and expects the model value to be a standard javascript Date object._ + +## ui-date-format directive +The ui-date directive only works with Date objects. +If you want to pass date strings to and from the date directive via ng-model then you must use the ui-date-format directive. +This directive specifies the format of the date string that will be expected in the ng-model. +The format string syntax is that defined by the JQueryUI Date picker. For example + + + +Now you can set myDate in the controller. + + $scope.myDate = "Thursday, 11 October, 2012"; + +## ng-required directive + +If you apply the required directive to element then the form element is invalid until a date is picked. + +Note: Remember that the ng-required directive must be explictly set, i.e. to "true". This is especially true on divs: + +
    + + diff --git a/js/vendor/angular-ui/modules/directives/date/date.js b/js/vendor/angular-ui/modules/directives/date/date.js new file mode 100644 index 000000000..238ac7ff8 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/date/date.js @@ -0,0 +1,111 @@ +/*global angular */ +/* + jQuery UI Datepicker plugin wrapper + + @note If ≤ IE8 make sure you have a polyfill for Date.toISOString() + @param [ui-date] {object} Options to pass to $.fn.datepicker() merged onto ui.config + */ + +angular.module('ui.directives') + +.directive('uiDate', ['ui.config', function (uiConfig) { + 'use strict'; + var options; + options = {}; + if (angular.isObject(uiConfig.date)) { + angular.extend(options, uiConfig.date); + } + return { + require:'?ngModel', + link:function (scope, element, attrs, controller) { + var getOptions = function () { + return angular.extend({}, uiConfig.date, scope.$eval(attrs.uiDate)); + }; + var initDateWidget = function () { + var opts = getOptions(); + + // If we have a controller (i.e. ngModelController) then wire it up + if (controller) { + var updateModel = function () { + scope.$apply(function () { + var date = element.datepicker("getDate"); + element.datepicker("setDate", element.val()); + controller.$setViewValue(date); + element.blur(); + }); + }; + if (opts.onSelect) { + // Caller has specified onSelect, so call this as well as updating the model + var userHandler = opts.onSelect; + opts.onSelect = function (value, picker) { + updateModel(); + scope.$apply(function() { + userHandler(value, picker); + }); + }; + } else { + // No onSelect already specified so just update the model + opts.onSelect = updateModel; + } + // In case the user changes the text directly in the input box + element.bind('change', updateModel); + + // Update the date picker when the model changes + controller.$render = function () { + var date = controller.$viewValue; + if ( angular.isDefined(date) && date !== null && !angular.isDate(date) ) { + throw new Error('ng-Model value must be a Date object - currently it is a ' + typeof date + ' - use ui-date-format to convert it from a string'); + } + element.datepicker("setDate", date); + }; + } + // If we don't destroy the old one it doesn't update properly when the config changes + element.datepicker('destroy'); + // Create the new datepicker widget + element.datepicker(opts); + if ( controller ) { + // Force a render to override whatever is in the input text box + controller.$render(); + } + }; + // Watch for changes to the directives options + scope.$watch(getOptions, initDateWidget, true); + } + }; +} +]) + +.directive('uiDateFormat', ['ui.config', function(uiConfig) { + var directive = { + require:'ngModel', + link: function(scope, element, attrs, modelCtrl) { + var dateFormat = attrs.uiDateFormat || uiConfig.dateFormat; + if ( dateFormat ) { + // Use the datepicker with the attribute value as the dateFormat string to convert to and from a string + modelCtrl.$formatters.push(function(value) { + if (angular.isString(value) ) { + return $.datepicker.parseDate(dateFormat, value); + } + }); + modelCtrl.$parsers.push(function(value){ + if (value) { + return $.datepicker.formatDate(dateFormat, value); + } + }); + } else { + // Default to ISO formatting + modelCtrl.$formatters.push(function(value) { + if (angular.isString(value) ) { + return new Date(value); + } + }); + modelCtrl.$parsers.push(function(value){ + if (value) { + return value.toISOString(); + } + }); + } + } + }; + return directive; +}]); diff --git a/js/vendor/angular-ui/modules/directives/date/dependencies.json b/js/vendor/angular-ui/modules/directives/date/dependencies.json new file mode 100644 index 000000000..9b9d050fa --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/date/dependencies.json @@ -0,0 +1,5 @@ +{ + "core": [ "jquery", "jquery-ui" ], + "internal": [], + "external": [] +} \ No newline at end of file diff --git a/js/vendor/angular-ui/modules/directives/date/test/dateSpec.js b/js/vendor/angular-ui/modules/directives/date/test/dateSpec.js new file mode 100644 index 000000000..fc0c4db78 --- /dev/null +++ b/js/vendor/angular-ui/modules/directives/date/test/dateSpec.js @@ -0,0 +1,354 @@ +/*global describe, beforeEach, it, inject, expect, module, $*/ +describe('uiDate', function() { + 'use strict'; + var selectDate; + selectDate = function(element, date) { + element.datepicker('setDate', date); + $.datepicker._selectDate(element); + }; + beforeEach(module('ui.directives')); + describe('simple use on input element', function() { + it('should have a date picker attached', function() { + inject(function($compile, $rootScope) { + var element; + element = $compile("")($rootScope); + expect(element.datepicker()).toBeDefined(); + }); + }); + it('should be able to get the date from the model', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("")($rootScope); + $rootScope.$apply(function() { + $rootScope.x = aDate; + }); + expect(element.datepicker('getDate')).toEqual(aDate); + }); + }); + it('should put the date in the model', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("")($rootScope); + $rootScope.$apply(); + selectDate(element, aDate); + expect($rootScope.x).toEqual(aDate); + }); + }); + it('should blur the input element after selecting a date', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("")($rootScope); + $rootScope.$apply(); + $(document.body).append(element); // Need to add it to the document so that it can get focus + element.focus(); + expect(document.activeElement).toEqual(element[0]); + selectDate(element, aDate); + expect(document.activeElement).not.toEqual(element[0]); + element.remove(); // And then remove it again! + }); + }); + }); + describe('when model is not a Date', function() { + var element; + var scope; + beforeEach(inject(function($compile, $rootScope) { + element = $compile('')($rootScope); + scope = $rootScope; + })); + it('should not freak out when the model is null', function() { + scope.$apply(function() { + scope.x = null; + }); + expect(element.datepicker('getDate')).toBe(null); + }); + it('should not freak out when the model is undefined', function() { + scope.$apply(function() { + scope.x = undefined; + }); + expect(element.datepicker('getDate')).toBe(null); + }); + it('should throw an error if you try to pass in a boolean when the model is false', function() { + expect(function() { + scope.$apply(function() { + scope.x = false; + }); + }).toThrow(); + }); + }); + + it('should update the input field correctly on a manual update', function() { + inject(function($compile, $rootScope) { + var dateString = '2012-08-17'; + var dateObj = $.datepicker.parseDate('yy-mm-dd', dateString); + var element = $compile('')($rootScope); + $rootScope.$apply(function() { + $rootScope.x = dateObj; + }); + // Now change the data in the input box + dateString = '2012-8-01'; + dateObj = $.datepicker.parseDate('yy-mm-dd', dateString); + element.val(dateString); + element.trigger("change"); + expect(element.datepicker('getDate')).toEqual(dateObj); + expect(element.val()).toEqual('2012-08-01'); + $rootScope.$digest(); + expect($rootScope.x).toEqual(dateObj); + }); + }); + + describe("use with user events", function() { + it('should call the user onSelect event within a scope.$apply context', function() { + inject(function($compile, $rootScope) { + var watched = false; + $rootScope.myDateSelected = function() { + $rootScope.watchMe = true; + } + $rootScope.$watch("watchMe", function(watchMe) { + if (watchMe) { + watched = true; + } + }); + var aDate = new Date(2012,9,11); + var element = $compile('')($rootScope); + $rootScope.$apply(); + selectDate(element, aDate); + expect(watched).toBeTruthy(); + }); + }); + }); + + describe('use with ng-required directive', function() { + it('should be invalid initially', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("")($rootScope); + $rootScope.$apply(); + expect(element.hasClass('ng-invalid')).toBeTruthy(); + }); + }); + it('should be valid if model has been specified', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("")($rootScope); + $rootScope.$apply(function() { + $rootScope.x = aDate; + }); + expect(element.hasClass('ng-valid')).toBeTruthy(); + }); + }); + it('should be valid after the date has been picked', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("")($rootScope); + $rootScope.$apply(); + selectDate(element, aDate); + expect(element.hasClass('ng-valid')).toBeTruthy(); + }); + }); + }); + describe('simple use on a div element', function() { + it('should have a date picker attached', function() { + inject(function($compile, $rootScope) { + var element; + element = $compile("
    ")($rootScope); + expect(element.datepicker()).toBeDefined(); + }); + }); + it('should be able to get the date from the model', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("
    ")($rootScope); + $rootScope.$apply(function() { + $rootScope.x = aDate; + }); + expect(element.datepicker('getDate')).toEqual(aDate); + }); + }); + it('should put the date in the model', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("
    ")($rootScope); + $rootScope.$apply(); + selectDate(element, aDate); + expect($rootScope.x).toEqual(aDate); + }); + }); + }); + describe('use with ng-required directive', function() { + it('should be invalid initially', function() { + inject(function($compile, $rootScope) { + var element = $compile("
    ")($rootScope); + $rootScope.$apply(); + expect(element.hasClass('ng-invalid')).toBeTruthy(); + }); + }); + it('should be valid if model has been specified', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("
    ")($rootScope); + $rootScope.$apply(function() { + $rootScope.x = aDate; + }); + expect(element.hasClass('ng-valid')).toBeTruthy(); + }); + }); + it('should be valid after the date has been picked', function() { + inject(function($compile, $rootScope) { + var aDate, element; + aDate = new Date(2010, 12, 1); + element = $compile("
    ")($rootScope); + $rootScope.$apply(); + selectDate(element, aDate); + expect(element.hasClass('ng-valid')).toBeTruthy(); + }); + }); + }); + describe('when attribute options change', function() { + it('should watch attribute and update date widget accordingly', function() { + inject(function($compile, $rootScope) { + var element; + $rootScope.config = { + minDate: 5 + }; + element = $compile("")($rootScope); + $rootScope.$apply(); + expect(element.datepicker("option", "minDate")).toBe(5); + $rootScope.$apply(function() { + $rootScope.config.minDate = 10; + }); + expect(element.datepicker("option", "minDate")).toBe(10); + }); + }); + }); +}); + +describe('uiDateFormat', function() { + beforeEach(module('ui.directives')); + + describe('$formatting', function() { + it('should parse the date correctly from an ISO string', function() { + inject(function($compile, $rootScope) { + var aDate, aDateString, element; + aDate = new Date(2012,8,17); + aDateString = (aDate).toISOString(); + + element = $compile('')($rootScope); + $rootScope.x = aDateString; + $rootScope.$digest(); + + // Check that the model has not been altered + expect($rootScope.x).toEqual(aDateString); + // Check that the viewValue has been parsed correctly + expect(element.controller('ngModel').$viewValue).toEqual(aDate); + }); + }); + it('should parse the date correctly from a custom string', function() { + inject(function($compile, $rootScope) { + var aDate = new Date(2012, 9, 11); + var aDateString = "Thursday, 11 October, 2012"; + + var element = $compile('')($rootScope); + $rootScope.x = aDateString; + $rootScope.$digest(); + + // Check that the model has not been altered + expect($rootScope.x).toEqual(aDateString); + // Check that the viewValue has been parsed correctly + expect(element.controller('ngModel').$viewValue).toEqual(aDate); + }); + }); + it('should handle unusual model values', function() { + inject(function($compile, $rootScope) { + var element = $compile('')($rootScope); + + $rootScope.x = false; + $rootScope.$digest(); + // Check that the model has not been altered + expect($rootScope.x).toEqual(false); + // Check that the viewValue has been parsed correctly + expect(element.controller('ngModel').$viewValue).toEqual(null); + + $rootScope.x = undefined; + $rootScope.$digest(); + // Check that the model has not been altered + expect($rootScope.x).toBeUndefined(); + // Check that the viewValue has been parsed correctly + expect(element.controller('ngModel').$viewValue).toEqual(null); + + $rootScope.x = null; + $rootScope.$digest(); + // Check that the model has not be