├── .bowerrc ├── .gitignore ├── .jscsrc ├── .jshintrc ├── .nvmrc ├── .scss-lint.yml ├── Gemfile ├── Gruntfile.js ├── LICENSE.md ├── README.md ├── app ├── index.html ├── scripts │ ├── app.ts │ └── components │ │ ├── name-formatter.ts │ │ ├── name-input.ts │ │ ├── name-list.ts │ │ └── names-app.ts ├── test │ ├── .jshintrc │ ├── lib │ │ └── turnerjs-driver.ts │ └── spec │ │ ├── components │ │ ├── es5-name-formatter.js │ │ ├── name-formatter.spec.ts │ │ ├── name-input.spec.ts │ │ ├── name-list.spec.ts │ │ └── names-app.spec.ts │ │ └── test-kit │ │ └── turnerjs-driver.spec.ts ├── tsconfig.json └── typings │ ├── angularjs │ ├── angular-mocks.d.ts │ └── angular.d.ts │ ├── jasmine │ └── jasmine.d.ts │ ├── jquery │ └── jquery.d.ts │ └── node │ └── node.d.ts ├── bower.json ├── karma.conf.js ├── module └── generated │ ├── turnerjs-driver.d.ts │ └── turnerjs-driver.js ├── package.json ├── pom.xml ├── tsd.json └── tslint.json /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | .sass-cache 5 | app/bower_components 6 | *.iml 7 | *.sublime-workspace 8 | npm-debug.log 9 | sauce_connect.log* 10 | .DS_Store 11 | .bundle 12 | .idea 13 | .sauce-connect 14 | vendor 15 | Gemfile.lock 16 | coverage 17 | target 18 | replace.private.conf.js 19 | Gruntfile.private.js 20 | .baseDir.ts 21 | .tscache 22 | npm-debug.log* 23 | index.d.ts 24 | turnerjs-module.d.ts 25 | module 26 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "crockford", 3 | "validateIndentation": 2, 4 | "disallowMultipleVarDecl": null, 5 | "requireMultipleVarDecl": null, 6 | "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", 7 | "disallowDanglingUnderscores": null, 8 | "requireSpaceBeforeObjectValues": true, 9 | "requireSpacesInAnonymousFunctionExpression": null, 10 | "requireVarDeclFirst": null 11 | } 12 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "camelcase": true, 4 | "curly": true, 5 | "eqeqeq": true, 6 | "immed": true, 7 | "indent": 2, 8 | "latedef": true, 9 | "newcap": true, 10 | "noarg": true, 11 | "quotmark": "single", 12 | "undef": true, 13 | "unused": true, 14 | "strict": true, 15 | "globalstrict": true, 16 | "trailing": true, 17 | "smarttabs": true, 18 | "white": true, 19 | "globals": { 20 | "_": false, 21 | "angular": false, 22 | "require": false, 23 | "process": false, 24 | "module": false 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /.scss-lint.yml: -------------------------------------------------------------------------------- 1 | linters: 2 | BorderZero: 3 | enabled: true 4 | 5 | CapitalizationInSelector: 6 | enabled: true 7 | 8 | ColorKeyword: 9 | enabled: true 10 | 11 | Comment: 12 | enabled: true 13 | 14 | DebugStatement: 15 | enabled: true 16 | 17 | DeclarationOrder: 18 | enabled: true 19 | 20 | DuplicateProperty: 21 | enabled: true 22 | 23 | ElsePlacement: 24 | enabled: true 25 | style: same_line 26 | 27 | EmptyLineBetweenBlocks: 28 | enabled: true 29 | ignore_single_line_blocks: true 30 | 31 | EmptyRule: 32 | enabled: true 33 | 34 | FinalNewline: 35 | enabled: true 36 | present: true 37 | 38 | HexLength: 39 | enabled: true 40 | style: long 41 | 42 | HexNotation: 43 | enabled: true 44 | style: lowercase 45 | 46 | HexValidation: 47 | enabled: true 48 | 49 | IdWithExtraneousSelector: 50 | enabled: true 51 | 52 | Indentation: 53 | enabled: true 54 | character: space 55 | width: 2 56 | 57 | LeadingZero: 58 | enabled: true 59 | style: exclude_zero 60 | 61 | MergeableSelector: 62 | enabled: true 63 | force_nesting: true 64 | 65 | NameFormat: 66 | enabled: true 67 | convention: hyphenated_lowercase 68 | 69 | PlaceholderInExtend: 70 | enabled: true 71 | 72 | PropertySortOrder: 73 | enabled: false 74 | order: concentric 75 | ignore_unspecified: true 76 | 77 | PropertySpelling: 78 | enabled: true 79 | extra_properties: [] 80 | 81 | SelectorDepth: 82 | enabled: true 83 | max_depth: 4 84 | 85 | Shorthand: 86 | enabled: true 87 | 88 | SingleLinePerProperty: 89 | enabled: true 90 | allow_single_line_rule_sets: true 91 | 92 | SingleLinePerSelector: 93 | enabled: true 94 | 95 | SpaceAfterComma: 96 | enabled: true 97 | 98 | SpaceAfterPropertyColon: 99 | enabled: true 100 | style: one_space 101 | 102 | SpaceAfterPropertyName: 103 | enabled: true 104 | 105 | SpaceBeforeBrace: 106 | enabled: true 107 | allow_single_line_padding: true 108 | 109 | SpaceBetweenParens: 110 | enabled: true 111 | spaces: 0 112 | 113 | StringQuotes: 114 | enabled: true 115 | style: single_quotes 116 | 117 | TrailingSemicolon: 118 | enabled: true 119 | 120 | UnnecessaryMantissa: 121 | enabled: true 122 | 123 | UnnecessaryParentReference: 124 | enabled: true 125 | 126 | UrlFormat: 127 | enabled: true 128 | 129 | UrlQuotes: 130 | enabled: true 131 | 132 | ZeroUnit: 133 | enabled: true 134 | 135 | Compass::*: 136 | enabled: false 137 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rake' 4 | 5 | 6 | gem 'compass' 7 | gem 'haml' 8 | gem 'scss-lint' 9 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | // Generated on 2016-04-14 using generator-wix-angular 1.0.88 2 | 'use strict'; 3 | 4 | module.exports = function (grunt) { 5 | var turnerModuleNames = ['index.d.ts', 'module/index.d.ts']; 6 | 7 | require('wix-gruntfile')(grunt, { 8 | version: '1.0.88', 9 | karmaConf: require('./karma.conf.js'), 10 | protractor: false, 11 | bowerComponent: true 12 | }); 13 | var copy = grunt.config('copy'); 14 | copy.dist.files.push({ 15 | expand: true, 16 | cwd: '.tmp/test/lib/', 17 | src: ['*.d.ts', '*.js'], 18 | dest: 'module/generated' 19 | }); 20 | copy.dist.files.push({ 21 | expand: true, 22 | cwd: '.tmp/test/lib/', 23 | src: 'turnerjs-driver.js', 24 | rename: function () { 25 | return 'module/index.js'; 26 | } 27 | }); 28 | copy.dist.files = copy.dist.files.concat(turnerModuleNames.map(function (name) { 29 | return { 30 | expand: true, 31 | cwd: '.tmp/test/lib/', 32 | src: ['*.d.ts'], 33 | rename: function () { 34 | return name; 35 | } 36 | }; 37 | })); 38 | grunt.config('copy', copy); 39 | 40 | var replace = grunt.config('replace'); 41 | replace.dtsAsModule = { 42 | src: turnerModuleNames, 43 | overwrite: true, 44 | replacements: [{ 45 | from: /declare /g, 46 | to: 'export ' 47 | }] 48 | }; 49 | grunt.config('replace', replace); 50 | grunt.hookTask('package').push('replace:dtsAsModule'); 51 | }; 52 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Wix.com 3 | 4 | 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: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | 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. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular Components Test Kit 2 | 3 | ## Post 4 | A detailed post with examples and explanations can be found in the following Medium article: 5 | 6 | [Testing angular components — you don’t know what you’re missing](https://goo.gl/pk6EoA) 7 | 8 | ## Overview 9 | Component tests allows testing the UI (provided that it is build as components/directives of course) in order to get instant feedback and minimize the use of protractor. 10 | 11 | The test kit provides a base driver utility class - **TurnerComponentDriver**, which allows writing tests using typescript in order to test components in a more readable, maintainable and quicker manner, 12 | It provides basic methods to allow rendering a template, accessing underlying elements and ability to maintain drivers' hierarchy, in order to be able to reuse drivers in parent components. 13 | 14 | The best practice implemented by TurnerJS in regards to elements' selectors is by using a 'data-hook' attribute in order to mark elements which are accessed by your code. 15 | It implements the approach demonstrates in [this](http://html5doctor.com/html5-custom-data-attributes/) article, but it is not mandated by the framework, one can use any other data selectors approach. 16 | 17 | ## Installation - Bower 18 | 1. install using bower 19 | `bower install --save turnerjs` 20 | 2. Include the following reference in your Karma configuration file 21 | `'/bower_components/turnerjs/dist/test/lib/turnerjs-driver.js'` 22 | 3. *Optional* - if you are using TypeScript (recommended) add reference to the d.ts file in your tsconfig file: 23 | `"bower_components/turnerjs/dist/test/lib/turnerjs-driver.d.ts"` 24 | 25 | ## Installation - NPM 26 | 1. install using node package manager 27 | `npm install -S turnerjs` 28 | 2. Include the following reference in your Karma configuration file 29 | `'node_modules/turnerjs/module/generated/turnerjs-driver.js'` 30 | or 31 | `require(turnerjs)` (when window is supported) 32 | 3. *Optional* - if you are using TypeScript (recommended) add reference to the d.ts file in your tsconfig file: 33 | `"../node_modules/turnerjs/module/generated/turnerjs-driver.d.ts"` 34 | 35 | ## Usage 36 | * Create a driver that extends the base driver and implement the methods that are required for your tests, for example (in the spec file or elsewhere): 37 | 38 | ```javascript 39 | class ExampleComponentDriver extends TurnerComponentDriver { 40 | 41 | constructor() { 42 | super(); 43 | } 44 | 45 | render(param1, param2) { 46 | //renders the template and adds the input parameters as scope params (second argument to renderFromTemplate method) 47 | //passing a selector is needed when the element containing the directive is not the first element in the template or when there is more than one driver 48 | this.renderFromTemplate('
{{param1}}
', {param1, param2}, 'example-component'); 49 | } 50 | 51 | isInnerElementValid(): boolean { 52 | return this.findByDataHook('inner-element').text() === 'valid'; 53 | } 54 | } 55 | ``` 56 | 57 | * Write tests that utilizes the driver 58 | 59 | ```javascript 60 | let driver: ExampleComponentDriver; 61 | beforeEach(() => { 62 | driver = new ExampleComponentDriver(); 63 | driver.render('valid', 'yada yada'); 64 | driver.connectToBody(); 65 | }); 66 | 67 | afterEach(() => { 68 | driver.disconnectFromBody(); 69 | }); 70 | 71 | it('should contain a valid element value', () => { 72 | expect(driver.isInnerElementValid()).toBeTruthy(); 73 | }); 74 | ``` 75 | 76 | ## Global Methods added by the test kit 77 | |Param|Type|Arguments|Details| 78 | |---|---|---|---| 79 | |byDataHook|global method|dataHook: string|Create a data-hook selector it is useful for methods that uses selectors such as ***TurnerComponentDriver.defineChild***| 80 | 81 | ## Base Driver Methods/ Members 82 | |Param|Type|Arguments|Details| 83 | |---|---|---|---| 84 | |constructor|Constructor|N/A|Creates the driver| 85 | |renderFromTemplate|protected method|**template**: string, **args**?: Object, **selector**?: string, appendToBody?: boolean|Allows rendering the component/directive, the args is a key value pairs object that will be added to the scope of the element, initializes the root of the driver according to the selector | 86 | |findByDataHook|protected method|**dataHook**: string|a utility method that should be used by drivers that inherits from the base driver in order to select an element (first if there are several) by **data-hook** attribute. It will throws an error if called before ***renderFromTemplate*** was called| 87 | |findAllByDataHook|protected method|**dataHook**: string|similar to ***findByDataHook*** but allows selecting several elements with the same **data-hook**| 88 | |defineChild|protected method|**childDriver**: Instance of T such that T extends **TurnerComponentDriver**, **selector**: string representing a CSS selector (preferably called with ***byDataHook(dataHook)***)|Declare a child driver of the current driver, allows components hierarchy, which is also returned by the method. This method should be called before ***renderFromTemplate*** was called| 89 | |defineChildren|protected method|**factory**: function that returns an instance of T such that T extends **TurnerComponentDriver**, **selector**: string representing a CSS selector (which is expected to return more than one result)|returns an array of child drivers (instances of T), it is useful when there is more than one child driver for parent driver (e.g. ng-repeat), the returned array will change when there is a change in the number of elements in the dom. This method should be called before ***renderFromTemplate*** was called| 90 | |applyChanges|public method|N/A|invokes $rootScope.$digest(), mainly aimed to 'hide' *AngularJS* related implementation| 91 | |connectToBody|public method|N/A|Connects the template to the karma's browser body - allows height/width related tests. ***disconnectFromBody*** has to be called at the end of the test. It will thorw an error if called before ***renderFromTemplate*** was called| 92 | |disconnectFromBody|public method|N/A|Clears the the body of the karma's browser, used in order to reset the browser to the original state prior to starting the next test| 93 | |afterRender|protected method|N/A|You can override this method if you need extra setup after render| 94 | |element|ng.IAugmentedJQuery|N/A|Reference to the element that represents the root of the driver (by selector if provided or template root)| 95 | |scope|ng.IScope|N/A|Reference to the scope of ***element*** member| 96 | |isRendered|boolean|N/A|defines whether the driver is rendered - whether its template was rendered and its scope is valid (defined and part of the dom)| 97 | |appendedToBody|boolean|N/A|defines whether the driver's element is appended to body (e.g. a driver for bootstrap tooltip)| 98 | |$rootScope|ng.IRootScopeService|N/A|Reference to the **$rootScope** service (removes the need to inject it in tests)| 99 | 100 | ## Nested drivers 101 | In order to allow reuse of drivers, the base driver supports initializing any child element (member) that extends **TurnerComponentDriver** 102 | For example, assuming 3 components are defined: 103 | ```javascript 104 | angular.module('myModule', []); 105 | class ItemComponentCtrl { 106 | public item: {value: number}; 107 | 108 | isValid(): boolean { 109 | return this.item.value > 1; 110 | } 111 | } 112 | 113 | angular 114 | .module('myModule') 115 | .component('itemComponent', { 116 | template: `
`, 117 | controller: ItemComponentCtrl, 118 | bindings: { 119 | item: '=' 120 | } 121 | }); 122 | 123 | class IndividualComponentCtrl { 124 | public item: {value: number}; 125 | 126 | getText(): string { 127 | return this.item.value > 1 ? 'valid' : 'invalid'; 128 | } 129 | } 130 | 131 | angular 132 | .module('myModule') 133 | .component('individualComponent', { 134 | template: `
{{$ctrl.getText()}}
`, 135 | controller: IndividualComponentCtrl, 136 | bindings: { 137 | item: '=' 138 | } 139 | }); 140 | 141 | class ParentComponentCtrl { 142 | public items: {value: number}[]; 143 | 144 | constructor() { 145 | this.items = []; 146 | for (let i = 0; i < 5; i++) { 147 | //push either 1 or 2 148 | this.items.push({ 149 | value: Math.floor((Math.random() * 2) + 1) 150 | }); 151 | } 152 | } 153 | } 154 | 155 | angular 156 | .module('myModule') 157 | .component('parentComponent', { 158 | template: `
159 | 160 | 161 |
`, 162 | controller: ParentComponentCtrl 163 | }); 164 | 165 | ``` 166 | 167 | 3 Drivers that corresponds to each are defined: 168 | (When there is a list of child drivers - e.g. when using ng-repeat, **defineChildren** method should be used in order to declare an array of child drivers) 169 | ```javascript 170 | 171 | class IndividualComponentDriver extends TurnerComponentDriver { 172 | 173 | constructor() { 174 | super(); 175 | } 176 | 177 | render(item) { 178 | this.renderFromTemplate('', {item}); 179 | } 180 | 181 | isValid(): boolean { 182 | return this.findByDataHook('inner-element').text() === 'valid'; 183 | } 184 | } 185 | 186 | class ItemComponentDriver extends TurnerComponentDriver { 187 | 188 | constructor() { 189 | super(); 190 | } 191 | 192 | render(item) { 193 | this.renderFromTemplate('', {item}, 'item-component'); 194 | } 195 | 196 | isValid(): boolean { 197 | return this.findByDataHook('item-element').hasClass('valid'); 198 | } 199 | } 200 | 201 | class ParentComponentDriver extends TurnerComponentDriver { 202 | public innerComponent: IndividualComponentDriver; 203 | public itemComponents: ItemComponentDriver[]; 204 | 205 | constructor() { 206 | super(); 207 | this.innerComponent = this.defineChild(new IndividualComponentDriver(), 'individual-component'); 208 | this.itemComponents = this.defineChildren(() => new ItemComponentDriver(), 'item-component'); 209 | } 210 | 211 | render() { 212 | this.renderFromTemplate(``); 213 | } 214 | 215 | isIndividualValid(): boolean { 216 | return this.innerComponent.isValid(); 217 | } 218 | 219 | isItemsValid(): boolean { 220 | let result = true; 221 | this.itemComponents.forEach(itemDriver => { 222 | result = result && itemDriver.isValid(); 223 | }); 224 | return result; 225 | } 226 | } 227 | ``` 228 | **TurnerComponentDriver** will initialize the member's scope & element automatically as soon as the renderFromTemplate method is invoked. 229 | The above drivers will allow testing each component separately and also testing the parent component that wraps the two: 230 | ```javascript 231 | describe('Usage Examples when there are repeatable drivers', () => { 232 | let parentComponentDriver: ParentComponentDriver; 233 | beforeEach(() => { 234 | module('myModule'); 235 | parentComponentDriver = new ParentComponentDriver(); 236 | }); 237 | 238 | it('should be valid when the random values are above 1', () => { 239 | spyOn(Math, 'random').and.returnValue(0.9); 240 | parentComponentDriver.render(); 241 | expect(parentComponentDriver.isIndividualValid()).toBe(true); 242 | expect(parentComponentDriver.isItemsValid()).toBe(true); 243 | }); 244 | }); 245 | ``` 246 | ## Non TypeScript usage 247 | Though the recommendation is to use TypeScript with turnerjs, if you are not using it, you can create the driver using prototypical inheritance. 248 | There are various ways to implement it, but the test kits includes a test spec for ES5 usage (see ***app/test/spec/components/es5-name-formatter.js***) 249 | The below provides the basic implementation of such driver: 250 | ```javascript 251 | /* globals TurnerComponentDriver */ //for jshint 252 | function ES5Driver() { 253 | TurnerComponentDriver.call(arguments); 254 | } 255 | 256 | ES5Driver.prototype = new TurnerComponentDriver(); 257 | ES5Driver.constructor = ES5Driver; 258 | 259 | ES5Driver.prototype.render = function () { 260 | this.renderFromTemplate(''); 261 | }; 262 | //other driver methods 263 | 264 | describe('your tests are here', function () { 265 | var es5driver; 266 | 267 | beforeEach(function () { 268 | angular.mock.module('turnerjsAppInternal'); 269 | driver = new ES5Driver(); 270 | }); 271 | 272 | it('...', function () { 273 | driver.render(); 274 | //test e 275 | }); 276 | }); 277 | ``` 278 | #### Contribution 279 | Via pull requests, 280 | 281 | After cloning the repository please run `npm install` and `bower install` in order to fetch dependencies 282 | 283 | Running/Building the project is done by using ***grunt***: 284 | `grunt serve:clean` - will start the server, there is no real UI for it, but it will run the unit tests on each save 285 | `grunt build` - build the project to make sure that changes are valid and meeting all code style definitions 286 | 287 | #### Credits 288 | Alon Yehezkel 289 | Shahar Talmi 290 | Boris Litvinski 291 | Amit Shvil 292 | 293 | ## License 294 | 295 | The MIT License. 296 | 297 | See [LICENSE](LICENSE.md) 298 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | componentTestKit 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |

Names App

16 |

This is not a real app, the only purpose of the components is to present the component testing kit, so look into the test folder

17 |
18 | 19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/scripts/app.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //add services, directives, controllers, filters, etc. in this module 4 | //avoid adding module dependencies for this module 5 | angular 6 | .module('turnerjsAppInternal', []); 7 | 8 | //add module dependencies & config and run blocks in this module 9 | //load only the internal module in tests and mock any module dependency 10 | //the only exception to load this module in tests in to test the config & run blocks 11 | angular 12 | .module('turnerjsApp', ['turnerjsAppInternal']) 13 | .config(() => { 14 | return; 15 | }); 16 | -------------------------------------------------------------------------------- /app/scripts/components/name-formatter.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NameFormatter { 4 | name: string; 5 | } 6 | 7 | angular 8 | .module('turnerjsAppInternal') 9 | .component('nameFormatter', { 10 | template: `Name: {{$ctrl.name}}`, 11 | controller: NameFormatter, 12 | bindings: { 13 | name: '=' 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /app/scripts/components/name-input.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NameInput { 4 | currentName: string; 5 | onNameAdded: Function; 6 | 7 | onAddName() { 8 | this.onNameAdded({name: this.currentName}); 9 | this.currentName = ''; 10 | } 11 | } 12 | 13 | angular 14 | .module('turnerjsAppInternal') 15 | .component('nameInput', { 16 | template: `
17 | Name to add: 18 | 19 |
`, 20 | bindings: { 21 | onNameAdded: '&' 22 | }, 23 | controller: NameInput 24 | }); 25 | -------------------------------------------------------------------------------- /app/scripts/components/name-list.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NameList { 4 | names: string[]; 5 | } 6 | 7 | angular 8 | .module('turnerjsAppInternal') 9 | .component('nameList', { 10 | 11 | template: `
12 |
    13 |
  • 14 |
15 |
`, 16 | controller: NameList, 17 | bindings: { 18 | names: '=' 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /app/scripts/components/names-app.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NamesApp { 4 | names: Array; 5 | showNames: boolean; 6 | 7 | constructor() { 8 | this.names = []; 9 | this.showNames = true; 10 | } 11 | 12 | onNameAdded(name) { 13 | this.names.push(name); 14 | } 15 | } 16 | 17 | angular 18 | .module('turnerjsAppInternal') 19 | .component('namesApp', { 20 | 21 | template: `
22 | 23 |
24 | Hide names: 25 | 26 |
27 |
`, 28 | 29 | controller: NamesApp 30 | }); 31 | -------------------------------------------------------------------------------- /app/test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": true, 3 | "camelcase": true, 4 | "curly": true, 5 | "eqeqeq": true, 6 | "immed": true, 7 | "indent": 2, 8 | "latedef": true, 9 | "newcap": true, 10 | "noarg": true, 11 | "quotmark": "single", 12 | "undef": true, 13 | "unused": true, 14 | "strict": true, 15 | "globalstrict": true, 16 | "trailing": true, 17 | "smarttabs": true, 18 | "white": true, 19 | "node": true, 20 | "esnext": true, 21 | "globals": { 22 | "_": false, 23 | "$": false, 24 | "$$": false, 25 | "angular": false, 26 | "jasmine": false, 27 | "module": false, 28 | "inject": false, 29 | 30 | "describe": false, 31 | "it": false, 32 | "beforeEach": false, 33 | "afterEach": false, 34 | "expect": false, 35 | "spyOn": false, 36 | "runs": false, 37 | "waitsFor": false, 38 | 39 | "browser": false, 40 | "protractor": false, 41 | "by": false, 42 | "element": false, 43 | "input": false, 44 | "select": false, 45 | "binding": false, 46 | "repeater": false, 47 | "using": false, 48 | "pause": false, 49 | "resume": false, 50 | "sleep": false 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/test/lib/turnerjs-driver.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const enum TurnerChildDriverType { 4 | CHILD_REGULAR, 5 | CHILD_ARRAY 6 | } 7 | 8 | interface TurnerChildDriver { 9 | selector?: string; 10 | selectorIndex?: number; 11 | type: TurnerChildDriverType; 12 | factory?: (item?, index?) => T; 13 | drivers?: Array; 14 | fullDriversArr?: Array; 15 | } 16 | 17 | class TurnerComponentDriver { 18 | 19 | public $rootScope: ng.IRootScopeService; 20 | public $compile: ng.ICompileService; 21 | public body: ng.IAugmentedJQuery; 22 | 23 | public appendedToBody: boolean; 24 | 25 | private _element: ng.IAugmentedJQuery; 26 | private _scope: ng.IScope; 27 | private parent: TurnerComponentDriver; 28 | private templateRoot: ng.IAugmentedJQuery; 29 | private childDrivers: Array = []; 30 | 31 | constructor() { 32 | this.body = angular.element(document.body); 33 | } 34 | 35 | static byDataHook(dataHook): string { 36 | return `[data-hook='${dataHook}']`; 37 | } 38 | 39 | public get element() { 40 | this.verifyRendered(); 41 | return this._element; 42 | } 43 | 44 | public get scope() { 45 | this.verifyRendered(); 46 | return this._scope; 47 | } 48 | 49 | public get isRendered() { 50 | return !!this._scope; 51 | } 52 | 53 | public connectToBody() { 54 | this.verifyRendered(); 55 | this.appendTemplateToBody(); 56 | } 57 | 58 | public disconnectFromBody() { 59 | if (this.templateRoot) { 60 | this.templateRoot.remove(); 61 | } 62 | if (this.appendedToBody) { 63 | this._element.remove(); 64 | } 65 | } 66 | 67 | public applyChanges() { 68 | this.$rootScope.$digest(); 69 | } 70 | 71 | protected findByDataHook(dataHook: string): ng.IAugmentedJQuery { 72 | return angular.element(this.element[0].querySelector(TurnerComponentDriver.byDataHook(dataHook))); 73 | } 74 | 75 | protected findAllByDataHook(dataHook: string): ng.IAugmentedJQuery { 76 | return angular.element(this.element[0].querySelectorAll(TurnerComponentDriver.byDataHook(dataHook))); 77 | } 78 | 79 | protected renderFromTemplate(template: string, args: Object = {}, selector?, appendToBody = false) { 80 | angular.mock.inject(($rootScope: ng.IRootScopeService, $compile: ng.ICompileService) => { 81 | this.$rootScope = $rootScope; 82 | this.$compile = $compile; 83 | }); 84 | let scope = this.$rootScope.$new(); 85 | scope = angular.extend(scope, args); 86 | 87 | this.templateRoot = angular.element(template); 88 | this.$compile(this.templateRoot)(scope); 89 | if (appendToBody) { 90 | this.appendTemplateToBody(); 91 | } 92 | this.$rootScope.$digest(); 93 | 94 | this.initializeDriver(this.templateRoot, selector); 95 | this.$rootScope.$watch(() => this.initChildDrivers()); 96 | } 97 | 98 | protected initChildDrivers() { 99 | this.childDrivers.forEach(child => { 100 | if (child.type === TurnerChildDriverType.CHILD_REGULAR) { 101 | this.initRegularChild(child); 102 | } else if (child.type === TurnerChildDriverType.CHILD_ARRAY) { 103 | this.initArrayChild(child); 104 | } 105 | }); 106 | } 107 | 108 | protected defineChild(childDriver: T, selector?: string): T { 109 | return this.defineIndexedChild(childDriver, selector, 0); 110 | } 111 | 112 | protected defineChildren(factory: (item?, index?) => T, selector: string): Array { 113 | let children = []; 114 | this.childDrivers.push({ 115 | type: TurnerChildDriverType.CHILD_ARRAY, 116 | selector, 117 | factory, 118 | drivers: children, 119 | fullDriversArr: [] 120 | }); 121 | return children; 122 | } 123 | 124 | private appendTemplateToBody() { 125 | this.body.append(this.templateRoot); 126 | } 127 | 128 | private defineIndexedChild(childDriver: T, selector?: string, selectorIndex: number = 0): T { 129 | this.childDrivers.push({ 130 | selector, 131 | selectorIndex, 132 | type: TurnerChildDriverType.CHILD_REGULAR, 133 | drivers: [childDriver] 134 | }); 135 | childDriver.parent = this; 136 | return childDriver; 137 | } 138 | 139 | private initializeDriver(containingElement: ng.IAugmentedJQuery, selector?: string, selectorIndex: number = 0): void { 140 | let searchElement = this.appendedToBody ? this.body : containingElement; 141 | this._element = selector ? angular.element(searchElement[0].querySelectorAll(selector)[selectorIndex]) : containingElement; 142 | this._scope = this._element.isolateScope() || this._element.scope(); 143 | if (this.isRendered) { 144 | this.initChildDrivers(); 145 | } 146 | } 147 | 148 | private initArrayChild(child) { 149 | child.drivers.splice(0, child.drivers.length); 150 | [].forEach.call(this._element[0].querySelectorAll(child.selector), (item, index) => { 151 | if (child.fullDriversArr.length <= index) { 152 | child.fullDriversArr.push(this.defineIndexedChild(child.factory(item, index), child.selector, index)); 153 | } 154 | child.drivers.push(child.fullDriversArr[index]); 155 | }); 156 | } 157 | 158 | private initRegularChild(child) { 159 | let childDriver = child.drivers[0]; 160 | childDriver.initializeDriver(this._element, child.selector, child.selectorIndex); 161 | childDriver.$compile = this.$compile; 162 | childDriver.$rootScope = this.$rootScope; 163 | } 164 | 165 | verifyRendered() { 166 | if (this.parent) { 167 | this.parent.verifyRendered(); 168 | } else { 169 | this.initChildDrivers(); 170 | } 171 | if (!this.isRendered) { 172 | throw 'cannot interact with driver before element is rendered'; 173 | } 174 | } 175 | } 176 | 177 | if (window) { 178 | window['byDataHook'] = window['byDataHook'] || TurnerComponentDriver.byDataHook; 179 | } 180 | 181 | declare function byDataHook(dataHook: string): string; 182 | 183 | if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { 184 | module.exports = { 185 | TurnerComponentDriver, 186 | byDataHook: TurnerComponentDriver.byDataHook 187 | }; 188 | } 189 | -------------------------------------------------------------------------------- /app/test/spec/components/es5-name-formatter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* globals TurnerComponentDriver */ 4 | function ES5NameFormatterDriver() { 5 | TurnerComponentDriver.call(arguments); 6 | } 7 | 8 | ES5NameFormatterDriver.prototype = new TurnerComponentDriver(); 9 | ES5NameFormatterDriver.constructor = ES5NameFormatterDriver; 10 | 11 | ES5NameFormatterDriver.prototype.render = function (name) { 12 | name = name || ''; 13 | this.renderFromTemplate('', {name: name}); 14 | }; 15 | 16 | ES5NameFormatterDriver.prototype.getFormattedName = function () { 17 | return this.findByDataHook('name-container').text(); 18 | }; 19 | 20 | describe('Component: nameFormatter', function () { 21 | var driver; 22 | beforeEach(function () { 23 | angular.mock.module('turnerjsAppInternal'); 24 | driver = new ES5NameFormatterDriver(); 25 | }); 26 | afterEach(function () { 27 | driver.disconnectFromBody(); 28 | }); 29 | it('should display name', function () { 30 | driver.render('Carmel Cohen'); 31 | expect(driver.getFormattedName()).toEqual('Name: Carmel Cohen'); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /app/test/spec/components/name-formatter.spec.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NameFormatterDriver extends TurnerComponentDriver { 4 | 5 | render(name = '') { 6 | this.renderFromTemplate(``, {name}); 7 | } 8 | 9 | getFormattedName() { 10 | return this.findByDataHook('name-container').text(); 11 | } 12 | 13 | getOriginalName() { 14 | return this.getFormattedName().split('Name: ')[1]; 15 | } 16 | } 17 | 18 | describe('Component: nameFormatter', () => { 19 | let driver: NameFormatterDriver; 20 | 21 | beforeEach(() => { 22 | angular.mock.module('turnerjsAppInternal'); 23 | driver = new NameFormatterDriver(); 24 | }); 25 | 26 | afterEach(() => { 27 | driver.disconnectFromBody(); 28 | }); 29 | 30 | it('should display name', () => { 31 | driver.render('Carmel Cohen'); 32 | expect(driver.getFormattedName()).toEqual('Name: Carmel Cohen'); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /app/test/spec/components/name-input.spec.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NameInputDriver extends TurnerComponentDriver { 4 | list: NameListDriver; 5 | 6 | constructor() { 7 | super(); 8 | this.list = this.defineChild(new NameListDriver(), 'name-list'); 9 | } 10 | 11 | render(onNameAdded = name => null) { 12 | this.renderFromTemplate(``, {onNameAdded}); 13 | } 14 | 15 | addName(name: string) { 16 | this.name = name; 17 | this.findByDataHook('add-name-button').triggerHandler('click'); 18 | this.applyChanges(); 19 | } 20 | 21 | get name(): string { 22 | return this.findByDataHook('name-input').val(); 23 | } 24 | 25 | set name(name: string) { 26 | this.findByDataHook('name-input').val(name); 27 | this.findByDataHook('name-input').triggerHandler('change'); 28 | this.applyChanges(); 29 | } 30 | } 31 | 32 | describe('Component: namesApp', () => { 33 | let driver: NameInputDriver; 34 | 35 | beforeEach(() => { 36 | angular.mock.module('turnerjsAppInternal'); 37 | driver = new NameInputDriver(); 38 | }); 39 | 40 | afterEach(() => { 41 | driver.disconnectFromBody(); 42 | }); 43 | 44 | it('Should initialize the name input as empty', () => { 45 | driver.render(); 46 | expect(driver.name).toEqual(''); 47 | }); 48 | 49 | it('Should be able to add names', () => { 50 | const addNameSpy = jasmine.createSpy('addNameSpy'); 51 | const nameToInput = 'Name 1'; 52 | driver.render(addNameSpy); 53 | driver.addName(nameToInput); 54 | expect(addNameSpy).toHaveBeenCalledWith(nameToInput); 55 | }); 56 | 57 | it('Should reflect new typed name', () => { 58 | const nameToInput = 'Name 1'; 59 | driver.render(); 60 | driver.name = nameToInput; 61 | expect(driver.name).toEqual(nameToInput); 62 | }); 63 | 64 | it('Should clear name after name is added', () => { 65 | driver.render(); 66 | driver.addName('some name'); 67 | expect(driver.name).toEqual(''); 68 | }); 69 | }); 70 | -------------------------------------------------------------------------------- /app/test/spec/components/name-list.spec.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NameListDriver extends TurnerComponentDriver { 4 | nameDrivers: NameFormatterDriver[]; 5 | 6 | constructor() { 7 | super(); 8 | this.nameDrivers = this.defineChildren(() => new NameFormatterDriver(), 'name-formatter'); 9 | } 10 | 11 | render(names: Array) { 12 | this.renderFromTemplate(``, {names}); 13 | } 14 | } 15 | 16 | describe('Component: nameList', () => { 17 | let driver: NameListDriver; 18 | 19 | beforeEach(() => { 20 | angular.mock.module('turnerjsAppInternal'); 21 | driver = new NameListDriver(); 22 | }); 23 | 24 | afterEach(() => { 25 | driver.disconnectFromBody(); 26 | }); 27 | 28 | it('should list all names', () => { 29 | driver.render(['Elyaniv Barda', 'Maor Melikson']); 30 | expect(driver.nameDrivers.length).toBe(2); 31 | }); 32 | 33 | it('should format the names', () => { 34 | driver.render(['Elyaniv Barda', 'Maor Melikson']); 35 | expect(driver.nameDrivers[0].getOriginalName()).toEqual('Elyaniv Barda'); 36 | }); 37 | 38 | it('should respond to changes in the names array', () => { 39 | var names = ['Elyaniv Barda', 'Maor Melikson']; 40 | driver.render(names); 41 | names.push('Maor Buzaglo'); 42 | driver.applyChanges(); 43 | expect(driver.nameDrivers.length).toBe(3); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /app/test/spec/components/names-app.spec.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class NamesAppDriver extends TurnerComponentDriver { 4 | list: NameListDriver; 5 | input: NameInputDriver; 6 | 7 | constructor() { 8 | super(); 9 | this.list = this.defineChild(new NameListDriver(), 'name-list'); 10 | this.input = this.defineChild(new NameInputDriver(), 'name-input'); 11 | } 12 | 13 | render() { 14 | this.renderFromTemplate(``); 15 | } 16 | 17 | renderToBody() { 18 | this.renderFromTemplate(``, {}, null, true); 19 | } 20 | 21 | addName(name: string) { 22 | this.input.addName(name); 23 | } 24 | 25 | toggleVisibility() { 26 | var controller = this.scope['$ctrl']; 27 | controller.showNames = !controller.showNames; 28 | this.applyChanges(); 29 | } 30 | 31 | isNamesPresented(): boolean { 32 | return !!this.findByDataHook('name-list').length; 33 | } 34 | } 35 | 36 | describe('Component: namesApp', () => { 37 | let driver: NamesAppDriver; 38 | 39 | beforeEach(() => { 40 | angular.mock.module('turnerjsAppInternal'); 41 | driver = new NamesAppDriver(); 42 | }); 43 | 44 | afterEach(() => { 45 | driver.disconnectFromBody(); 46 | }); 47 | 48 | it('should be appended to body', () => { 49 | driver.renderToBody(); 50 | 51 | expect(angular.element(document.body).find('names-app').length).toBe(1); 52 | }); 53 | 54 | it('Should initialize the names list as an empty list', () => { 55 | driver.render(); 56 | expect(driver.list.nameDrivers.length).toBe(0); 57 | }); 58 | 59 | it('Should be able to add names', () => { 60 | driver.render(); 61 | driver.addName('Name 1'); 62 | expect(driver.list.nameDrivers.length).toBe(1); 63 | }); 64 | 65 | it('Should show the names by default', () => { 66 | driver.render(); 67 | expect(driver.isNamesPresented()).toBe(true); 68 | }); 69 | 70 | it('Should be able to hide the names list', () => { 71 | driver.render(); 72 | driver.toggleVisibility(); 73 | expect(driver.isNamesPresented()).toBe(false); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /app/test/spec/test-kit/turnerjs-driver.spec.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | class InnerDriverExample extends TurnerComponentDriver { 3 | public child: InnerDriverExample; 4 | 5 | constructor(public item?, public index?) { 6 | super(); 7 | } 8 | 9 | getContent(): string { 10 | return this.findByDataHook('inner-driver-example-content').text(); 11 | } 12 | 13 | initChild() { 14 | this.child = this.defineChild(new InnerDriverExample(), '.inner-driver-example'); 15 | } 16 | } 17 | 18 | class AppendedToBodyDriver extends InnerDriverExample { 19 | constructor() { 20 | super(); 21 | this.appendedToBody = true; 22 | } 23 | } 24 | 25 | class ParentWithChildAppendedToBodyDriver extends TurnerComponentDriver { 26 | public childAppendedToBody: AppendedToBodyDriver; 27 | 28 | render() { 29 | this.renderFromTemplate( 30 | `
31 |
32 |
33 |
`, {}, '.driver-part'); 34 | this.childAppendedToBody = this.defineChild(new AppendedToBodyDriver(), byDataHook('child-driver')); 35 | let childElement = angular.element(`
Appended to body
`); 36 | this.$compile(childElement)(this.scope); 37 | this.body.append(childElement); 38 | this.applyChanges(); 39 | } 40 | 41 | isChildFoundInDom(): boolean { 42 | return !!this.body[0].querySelectorAll(byDataHook('child-driver')).length; 43 | } 44 | } 45 | 46 | describe('Directive: turnerjs test base driver', () => { 47 | let driver: TurnerComponentDriver; 48 | beforeEach(() => { 49 | angular.mock.module('turnerjsAppInternal'); 50 | }); 51 | 52 | afterEach(() => { 53 | driver.disconnectFromBody(); 54 | }); 55 | 56 | describe('Turner Driver: errors', () => { 57 | let simpleSelectorsDriver: NameFormatterDriver; 58 | 59 | beforeEach(() => { 60 | simpleSelectorsDriver = driver = new NameFormatterDriver(); 61 | }); 62 | 63 | it('should throw an error when trying to connect to body before render is called', () => { 64 | expect(() => simpleSelectorsDriver.connectToBody()).toThrow(); 65 | }); 66 | 67 | it('should throw an error when trying to query an element before render is called', () => { 68 | expect(() => simpleSelectorsDriver.getFormattedName()).toThrow(); 69 | }); 70 | 71 | it('should throw when accessing element/scope before render', () => { 72 | expect(() => simpleSelectorsDriver.element).toThrow(); 73 | expect(() => simpleSelectorsDriver.scope).toThrow(); 74 | }); 75 | }); 76 | 77 | describe('Turner Driver: initialization of child drivers', () => { 78 | let listDriver: NameListDriver; 79 | 80 | beforeEach(() => { 81 | listDriver = driver = new NameListDriver(); 82 | }); 83 | 84 | it('should initialize the root element for child drivers and allow searching in it', () => { 85 | listDriver.render(['a', 'b']); 86 | expect(listDriver.nameDrivers[0].getFormattedName()).toContain('a'); 87 | }); 88 | 89 | it('should be able to call apply changes from child and parent driver', () => { 90 | listDriver.render(['a', 'b']); 91 | expect(() => listDriver.applyChanges()).not.toThrow(); 92 | expect(() => listDriver.nameDrivers[0].applyChanges()).not.toThrow(); 93 | }); 94 | 95 | it('should initialize the scope for each driver member', () => { 96 | listDriver.render(['a', 'b']); 97 | listDriver.connectToBody(); 98 | expect(angular.element(listDriver.element[0].querySelector('#name-number-0')).scope()).toEqual(listDriver.nameDrivers[0].scope.$parent); 99 | }); 100 | 101 | it('should reinitialize a child driver when its element is re-added to the dom', () => { 102 | let names = ['a', 'b']; 103 | listDriver.render(names); 104 | let secondChildDriver = listDriver.nameDrivers[1]; 105 | names.pop(); 106 | driver.applyChanges(); 107 | expect(() => secondChildDriver.scope).toThrow(); 108 | names.push('c'); 109 | driver.applyChanges(); 110 | expect(() => secondChildDriver.scope).not.toThrow(); 111 | }); 112 | }); 113 | 114 | describe('Usage Examples when there are drivers with nested drivers in multiple hierarchies', () => { 115 | let multiLevelsDriver: NamesAppDriver; 116 | 117 | beforeEach(() => { 118 | multiLevelsDriver = driver = new NamesAppDriver(); 119 | }); 120 | 121 | it('should support nested drivers', () => { 122 | multiLevelsDriver.render(); 123 | multiLevelsDriver.addName('Test Name'); 124 | expect(multiLevelsDriver.list.nameDrivers[0].getFormattedName()).toContain('Test Name'); 125 | }); 126 | 127 | it('should support nested drivers reinitialization', () => { 128 | multiLevelsDriver.render(); 129 | multiLevelsDriver.toggleVisibility(); 130 | multiLevelsDriver.addName('Test Name'); 131 | expect(() => multiLevelsDriver.list.scope).toThrow(); 132 | multiLevelsDriver.toggleVisibility(); 133 | expect(multiLevelsDriver.list.nameDrivers[0].getFormattedName()).toContain('Test Name'); 134 | }); 135 | }); 136 | 137 | describe('Usage Example when child is appended to body', () => { 138 | let parentWithAppendedToBodyDriver: ParentWithChildAppendedToBodyDriver; 139 | 140 | beforeEach(() => { 141 | parentWithAppendedToBodyDriver = driver = new ParentWithChildAppendedToBodyDriver(); 142 | }); 143 | 144 | afterEach(() => { 145 | parentWithAppendedToBodyDriver.childAppendedToBody.disconnectFromBody(); 146 | }); 147 | 148 | it('should be able to select a child which is appended to body', () => { 149 | parentWithAppendedToBodyDriver.render(); 150 | expect(parentWithAppendedToBodyDriver.childAppendedToBody.getContent()).toBe('Appended to body'); 151 | }); 152 | 153 | it('should be able to remove from body when child is appended to body', () => { 154 | parentWithAppendedToBodyDriver.render(); 155 | expect(parentWithAppendedToBodyDriver.isChildFoundInDom()).toBe(true); 156 | parentWithAppendedToBodyDriver.childAppendedToBody.disconnectFromBody(); 157 | expect(parentWithAppendedToBodyDriver.isChildFoundInDom()).toBe(false); 158 | }); 159 | }); 160 | 161 | describe('by data hook global', () => { 162 | it('should support global by data hook method', () => { 163 | let element = document.createElement('div'); 164 | element.setAttribute('data-hook', 'check'); 165 | element.innerHTML = 'aa'; 166 | document.body.appendChild(element); 167 | 168 | expect(angular.element(document.body.querySelector(byDataHook('check'))).text()).toBe('aa'); 169 | }); 170 | }); 171 | }); 172 | -------------------------------------------------------------------------------- /app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "../.tmp" 4 | }, 5 | "filesGlob": [ 6 | "scripts/**/*.ts", 7 | "test/**/*.ts", 8 | "typings/**/*.d.ts" 9 | ], 10 | "files": [ 11 | "scripts/app.ts", 12 | "scripts/components/name-formatter.ts", 13 | "scripts/components/name-input.ts", 14 | "scripts/components/name-list.ts", 15 | "scripts/components/names-app.ts", 16 | "test/lib/turnerjs-driver.ts", 17 | "test/spec/components/name-formatter.spec.ts", 18 | "test/spec/components/name-input.spec.ts", 19 | "test/spec/components/name-list.spec.ts", 20 | "test/spec/components/names-app.spec.ts", 21 | "test/spec/test-kit/turnerjs-driver.spec.ts", 22 | "typings/angularjs/angular-mocks.d.ts", 23 | "typings/angularjs/angular.d.ts", 24 | "typings/jasmine/jasmine.d.ts", 25 | "typings/jquery/jquery.d.ts", 26 | "typings/node/node.d.ts" 27 | ] 28 | } -------------------------------------------------------------------------------- /app/typings/angularjs/angular-mocks.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Angular JS 1.3 (ngMock, ngMockE2E module) 2 | // Project: http://angularjs.org 3 | // Definitions by: Diego Vilar , Tony Curtis 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | /// 7 | 8 | declare module "angular-mocks/ngMock" { 9 | var _: string; 10 | export = _; 11 | } 12 | 13 | declare module "angular-mocks/ngMockE2E" { 14 | var _: string; 15 | export = _; 16 | } 17 | 18 | declare module "angular-mocks/ngAnimateMock" { 19 | var _: string; 20 | export = _; 21 | } 22 | 23 | /////////////////////////////////////////////////////////////////////////////// 24 | // ngMock module (angular-mocks.js) 25 | /////////////////////////////////////////////////////////////////////////////// 26 | declare namespace angular { 27 | 28 | /////////////////////////////////////////////////////////////////////////// 29 | // AngularStatic 30 | // We reopen it to add the MockStatic definition 31 | /////////////////////////////////////////////////////////////////////////// 32 | interface IAngularStatic { 33 | mock: IMockStatic; 34 | } 35 | 36 | // see https://docs.angularjs.org/api/ngMock/function/angular.mock.inject 37 | interface IInjectStatic { 38 | (...fns: Function[]): any; 39 | (...inlineAnnotatedConstructor: any[]): any; // this overload is undocumented, but works 40 | strictDi(val?: boolean): void; 41 | } 42 | 43 | interface IMockStatic { 44 | // see https://docs.angularjs.org/api/ngMock/function/angular.mock.dump 45 | dump(obj: any): string; 46 | 47 | inject: IInjectStatic 48 | 49 | // see https://docs.angularjs.org/api/ngMock/function/angular.mock.module 50 | module: { 51 | (...modules: any[]): any; 52 | sharedInjector(): void; 53 | } 54 | 55 | // see https://docs.angularjs.org/api/ngMock/type/angular.mock.TzDate 56 | TzDate(offset: number, timestamp: number): Date; 57 | TzDate(offset: number, timestamp: string): Date; 58 | } 59 | 60 | /////////////////////////////////////////////////////////////////////////// 61 | // ExceptionHandlerService 62 | // see https://docs.angularjs.org/api/ngMock/service/$exceptionHandler 63 | // see https://docs.angularjs.org/api/ngMock/provider/$exceptionHandlerProvider 64 | /////////////////////////////////////////////////////////////////////////// 65 | interface IExceptionHandlerProvider extends IServiceProvider { 66 | mode(mode: string): void; 67 | } 68 | 69 | /////////////////////////////////////////////////////////////////////////// 70 | // TimeoutService 71 | // see https://docs.angularjs.org/api/ngMock/service/$timeout 72 | // Augments the original service 73 | /////////////////////////////////////////////////////////////////////////// 74 | interface ITimeoutService { 75 | flush(delay?: number): void; 76 | flushNext(expectedDelay?: number): void; 77 | verifyNoPendingTasks(): void; 78 | } 79 | 80 | /////////////////////////////////////////////////////////////////////////// 81 | // IntervalService 82 | // see https://docs.angularjs.org/api/ngMock/service/$interval 83 | // Augments the original service 84 | /////////////////////////////////////////////////////////////////////////// 85 | interface IIntervalService { 86 | flush(millis?: number): number; 87 | } 88 | 89 | /////////////////////////////////////////////////////////////////////////// 90 | // LogService 91 | // see https://docs.angularjs.org/api/ngMock/service/$log 92 | // Augments the original service 93 | /////////////////////////////////////////////////////////////////////////// 94 | interface ILogService { 95 | assertEmpty(): void; 96 | reset(): void; 97 | } 98 | 99 | interface ILogCall { 100 | logs: string[]; 101 | } 102 | 103 | /////////////////////////////////////////////////////////////////////////// 104 | // ControllerService mock 105 | // see https://docs.angularjs.org/api/ngMock/service/$controller 106 | // This interface extends http://docs.angularjs.org/api/ng.$controller 107 | /////////////////////////////////////////////////////////////////////////// 108 | interface IControllerService { 109 | // Although the documentation doesn't state this, locals are optional 110 | (controllerConstructor: new (...args: any[]) => T, locals?: any, bindings?: any): T; 111 | (controllerConstructor: Function, locals?: any, bindings?: any): T; 112 | (controllerName: string, locals?: any, bindings?: any): T; 113 | } 114 | 115 | /////////////////////////////////////////////////////////////////////////// 116 | // ComponentControllerService 117 | // see https://docs.angularjs.org/api/ngMock/service/$componentController 118 | /////////////////////////////////////////////////////////////////////////// 119 | interface IComponentControllerService { 120 | // TBinding is an interface exposed by a component as per John Papa's style guide 121 | // https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#accessible-members-up-top 122 | (componentName: string, locals: { $scope: IScope, [key: string]: any }, bindings?: TBinding, ident?: string): T; 123 | } 124 | 125 | 126 | /////////////////////////////////////////////////////////////////////////// 127 | // HttpBackendService 128 | // see https://docs.angularjs.org/api/ngMock/service/$httpBackend 129 | /////////////////////////////////////////////////////////////////////////// 130 | interface IHttpBackendService { 131 | /** 132 | * Flushes all pending requests using the trained responses. 133 | * @param count Number of responses to flush (in the order they arrived). If undefined, all pending requests will be flushed. 134 | */ 135 | flush(count?: number): void; 136 | 137 | /** 138 | * Resets all request expectations, but preserves all backend definitions. 139 | */ 140 | resetExpectations(): void; 141 | 142 | /** 143 | * Verifies that all of the requests defined via the expect api were made. If any of the requests were not made, verifyNoOutstandingExpectation throws an exception. 144 | */ 145 | verifyNoOutstandingExpectation(): void; 146 | 147 | /** 148 | * Verifies that there are no outstanding requests that need to be flushed. 149 | */ 150 | verifyNoOutstandingRequest(): void; 151 | 152 | /** 153 | * Creates a new request expectation. 154 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. 155 | * Returns an object with respond method that controls how a matched request is handled. 156 | * @param method HTTP method. 157 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 158 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 159 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 160 | */ 161 | expect(method: string, url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)) :mock.IRequestHandler; 162 | 163 | /** 164 | * Creates a new request expectation for DELETE requests. 165 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. 166 | * Returns an object with respond method that controls how a matched request is handled. 167 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url is as expected. 168 | * @param headers HTTP headers object to be compared with the HTTP headers in the request. 169 | */ 170 | expectDELETE(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; 171 | 172 | /** 173 | * Creates a new request expectation for GET requests. 174 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. 175 | * Returns an object with respond method that controls how a matched request is handled. 176 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 177 | * @param headers HTTP headers object to be compared with the HTTP headers in the request. 178 | */ 179 | expectGET(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; 180 | 181 | /** 182 | * Creates a new request expectation for HEAD requests. 183 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. 184 | * Returns an object with respond method that controls how a matched request is handled. 185 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 186 | * @param headers HTTP headers object to be compared with the HTTP headers in the request. 187 | */ 188 | expectHEAD(url: string | RegExp | ((url: string) => boolean), headers?: Object): mock.IRequestHandler; 189 | 190 | /** 191 | * Creates a new request expectation for JSONP requests. 192 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, or if function returns false. 193 | * Returns an object with respond method that controls how a matched request is handled. 194 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 195 | */ 196 | expectJSONP(url: string | RegExp | ((url: string) => boolean)): mock.IRequestHandler; 197 | 198 | /** 199 | * Creates a new request expectation for PATCH requests. 200 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. 201 | * Returns an object with respond method that controls how a matched request is handled. 202 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 203 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 204 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 205 | */ 206 | expectPATCH(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; 207 | 208 | /** 209 | * Creates a new request expectation for POST requests. 210 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. 211 | * Returns an object with respond method that controls how a matched request is handled. 212 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 213 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 214 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 215 | */ 216 | expectPOST(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; 217 | 218 | /** 219 | * Creates a new request expectation for PUT requests. 220 | * Throws a preformatted error if expectation(s) don't match supplied string, regular expression, object, or if function returns false. 221 | * Returns an object with respond method that controls how a matched request is handled. 222 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 223 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 224 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 225 | */ 226 | expectPUT(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object): mock.IRequestHandler; 227 | 228 | /** 229 | * Creates a new backend definition. 230 | * Returns an object with respond method that controls how a matched request is handled. 231 | * @param method HTTP method. 232 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 233 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 234 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 235 | */ 236 | when(method: string, url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; 237 | 238 | /** 239 | * Creates a new backend definition for DELETE requests. 240 | * Returns an object with respond method that controls how a matched request is handled. 241 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 242 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 243 | */ 244 | whenDELETE(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; 245 | 246 | /** 247 | * Creates a new backend definition for GET requests. 248 | * Returns an object with respond method that controls how a matched request is handled. 249 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 250 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 251 | */ 252 | whenGET(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; 253 | 254 | /** 255 | * Creates a new backend definition for HEAD requests. 256 | * Returns an object with respond method that controls how a matched request is handled. 257 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 258 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 259 | */ 260 | whenHEAD(url: string | RegExp | ((url: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; 261 | 262 | /** 263 | * Creates a new backend definition for JSONP requests. 264 | * Returns an object with respond method that controls how a matched request is handled. 265 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 266 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 267 | */ 268 | whenJSONP(url: string | RegExp | ((url: string) => boolean)): mock.IRequestHandler; 269 | 270 | /** 271 | * Creates a new backend definition for PATCH requests. 272 | * Returns an object with respond method that controls how a matched request is handled. 273 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 274 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 275 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 276 | */ 277 | whenPATCH(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; 278 | 279 | /** 280 | * Creates a new backend definition for POST requests. 281 | * Returns an object with respond method that controls how a matched request is handled. 282 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 283 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 284 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 285 | */ 286 | whenPOST(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; 287 | 288 | /** 289 | * Creates a new backend definition for PUT requests. 290 | * Returns an object with respond method that controls how a matched request is handled. 291 | * @param url HTTP url string, regular expression or function that receives a url and returns true if the url matches the current expctation. 292 | * @param data HTTP request body string, json object, regular expression or function that receives the data and returns true if the data matches the current expectation. 293 | * @param headers HTTP headers object or function that receives the headers and returns true if the headers match the current expectation. 294 | */ 295 | whenPUT(url: string | RegExp | ((url: string) => boolean), data?: string | RegExp | Object | ((data: string) => boolean), headers?: Object | ((object: Object) => boolean)): mock.IRequestHandler; 296 | } 297 | 298 | export module mock { 299 | // returned interface by the the mocked HttpBackendService expect/when methods 300 | interface IRequestHandler { 301 | 302 | /** 303 | * Controls the response for a matched request using a function to construct the response. 304 | * Returns the RequestHandler object for possible overrides. 305 | * @param func Function that receives the request HTTP method, url, data, and headers and returns an array containing response status (number), data, headers, and status text. 306 | */ 307 | respond(func: ((method: string, url: string, data: string | Object, headers: Object) => [number, string | Object, Object, string])): IRequestHandler; 308 | 309 | /** 310 | * Controls the response for a matched request using supplied static data to construct the response. 311 | * Returns the RequestHandler object for possible overrides. 312 | * @param status HTTP status code to add to the response. 313 | * @param data Data to add to the response. 314 | * @param headers Headers object to add to the response. 315 | * @param responseText Response text to add to the response. 316 | */ 317 | respond(status: number, data: string | Object, headers?: Object, responseText?: string): IRequestHandler; 318 | 319 | /** 320 | * Controls the response for a matched request using the HTTP status code 200 and supplied static data to construct the response. 321 | * Returns the RequestHandler object for possible overrides. 322 | * @param data Data to add to the response. 323 | * @param headers Headers object to add to the response. 324 | * @param responseText Response text to add to the response. 325 | */ 326 | respond(data: string | Object, headers?: Object, responseText?: string): IRequestHandler; 327 | 328 | // Available when ngMockE2E is loaded 329 | /** 330 | * Any request matching a backend definition or expectation with passThrough handler will be passed through to the real backend (an XHR request will be made to the server.) 331 | */ 332 | passThrough(): IRequestHandler; 333 | } 334 | 335 | } 336 | 337 | } 338 | 339 | /////////////////////////////////////////////////////////////////////////////// 340 | // functions attached to global object (window) 341 | /////////////////////////////////////////////////////////////////////////////// 342 | //Use `angular.mock.module` instead of `module`, as `module` conflicts with commonjs. 343 | //declare var module: (...modules: any[]) => any; 344 | declare var inject: angular.IInjectStatic; 345 | -------------------------------------------------------------------------------- /app/typings/angularjs/angular.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Angular JS 1.5 2 | // Project: http://angularjs.org 3 | // Definitions by: Diego Vilar 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | 7 | /// 8 | 9 | declare var angular: angular.IAngularStatic; 10 | 11 | // Support for painless dependency injection 12 | interface Function { 13 | $inject?: string[]; 14 | } 15 | 16 | // Collapse angular into ng 17 | import ng = angular; 18 | // Support AMD require 19 | declare module 'angular' { 20 | export = angular; 21 | } 22 | 23 | /////////////////////////////////////////////////////////////////////////////// 24 | // ng module (angular.js) 25 | /////////////////////////////////////////////////////////////////////////////// 26 | declare namespace angular { 27 | 28 | // not directly implemented, but ensures that constructed class implements $get 29 | interface IServiceProviderClass { 30 | new (...args: any[]): IServiceProvider; 31 | } 32 | 33 | interface IServiceProviderFactory { 34 | (...args: any[]): IServiceProvider; 35 | } 36 | 37 | // All service providers extend this interface 38 | interface IServiceProvider { 39 | $get: any; 40 | } 41 | 42 | interface IAngularBootstrapConfig { 43 | strictDi?: boolean; 44 | debugInfoEnabled?: boolean; 45 | } 46 | 47 | /////////////////////////////////////////////////////////////////////////// 48 | // AngularStatic 49 | // see http://docs.angularjs.org/api 50 | /////////////////////////////////////////////////////////////////////////// 51 | interface IAngularStatic { 52 | bind(context: any, fn: Function, ...args: any[]): Function; 53 | 54 | /** 55 | * Use this function to manually start up angular application. 56 | * 57 | * @param element DOM element which is the root of angular application. 58 | * @param modules An array of modules to load into the application. 59 | * Each item in the array should be the name of a predefined module or a (DI annotated) 60 | * function that will be invoked by the injector as a config block. 61 | * @param config an object for defining configuration options for the application. The following keys are supported: 62 | * - `strictDi`: disable automatic function annotation for the application. This is meant to assist in finding bugs which break minified code. 63 | */ 64 | bootstrap(element: string|Element|JQuery|Document, modules?: (string|Function|any[])[], config?: IAngularBootstrapConfig): auto.IInjectorService; 65 | 66 | /** 67 | * Creates a deep copy of source, which should be an object or an array. 68 | * 69 | * - If no destination is supplied, a copy of the object or array is created. 70 | * - If a destination is provided, all of its elements (for array) or properties (for objects) are deleted and then all elements/properties from the source are copied to it. 71 | * - If source is not an object or array (inc. null and undefined), source is returned. 72 | * - If source is identical to 'destination' an exception will be thrown. 73 | * 74 | * @param source The source that will be used to make a copy. Can be any type, including primitives, null, and undefined. 75 | * @param destination Destination into which the source is copied. If provided, must be of the same type as source. 76 | */ 77 | copy(source: T, destination?: T): T; 78 | 79 | /** 80 | * Wraps a raw DOM element or HTML string as a jQuery element. 81 | * 82 | * If jQuery is available, angular.element is an alias for the jQuery function. If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite." 83 | */ 84 | element: IAugmentedJQueryStatic; 85 | equals(value1: any, value2: any): boolean; 86 | extend(destination: any, ...sources: any[]): any; 87 | 88 | /** 89 | * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. 90 | * 91 | * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. 92 | * 93 | * @param obj Object to iterate over. 94 | * @param iterator Iterator function. 95 | * @param context Object to become context (this) for the iterator function. 96 | */ 97 | forEach(obj: T[], iterator: (value: T, key: number) => any, context?: any): any; 98 | /** 99 | * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. 100 | * 101 | * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. 102 | * 103 | * @param obj Object to iterate over. 104 | * @param iterator Iterator function. 105 | * @param context Object to become context (this) for the iterator function. 106 | */ 107 | forEach(obj: { [index: string]: T; }, iterator: (value: T, key: string) => any, context?: any): any; 108 | /** 109 | * Invokes the iterator function once for each item in obj collection, which can be either an object or an array. The iterator function is invoked with iterator(value, key), where value is the value of an object property or an array element and key is the object property key or array element index. Specifying a context for the function is optional. 110 | * 111 | * It is worth noting that .forEach does not iterate over inherited properties because it filters using the hasOwnProperty method. 112 | * 113 | * @param obj Object to iterate over. 114 | * @param iterator Iterator function. 115 | * @param context Object to become context (this) for the iterator function. 116 | */ 117 | forEach(obj: any, iterator: (value: any, key: any) => any, context?: any): any; 118 | 119 | fromJson(json: string): any; 120 | identity(arg?: T): T; 121 | injector(modules?: any[], strictDi?: boolean): auto.IInjectorService; 122 | isArray(value: any): boolean; 123 | isDate(value: any): boolean; 124 | isDefined(value: any): boolean; 125 | isElement(value: any): boolean; 126 | isFunction(value: any): boolean; 127 | isNumber(value: any): boolean; 128 | isObject(value: any): boolean; 129 | isString(value: any): boolean; 130 | isUndefined(value: any): boolean; 131 | lowercase(str: string): string; 132 | 133 | /** 134 | * Deeply extends the destination object dst by copying own enumerable properties from the src object(s) to dst. You can specify multiple src objects. If you want to preserve original objects, you can do so by passing an empty object as the target: var object = angular.merge({}, object1, object2). 135 | * 136 | * Unlike extend(), merge() recursively descends into object properties of source objects, performing a deep copy. 137 | * 138 | * @param dst Destination object. 139 | * @param src Source object(s). 140 | */ 141 | merge(dst: any, ...src: any[]): any; 142 | 143 | /** 144 | * The angular.module is a global place for creating, registering and retrieving Angular modules. All modules (angular core or 3rd party) that should be available to an application must be registered using this mechanism. 145 | * 146 | * When passed two or more arguments, a new module is created. If passed only one argument, an existing module (the name passed as the first argument to module) is retrieved. 147 | * 148 | * @param name The name of the module to create or retrieve. 149 | * @param requires The names of modules this module depends on. If specified then new module is being created. If unspecified then the module is being retrieved for further configuration. 150 | * @param configFn Optional configuration function for the module. 151 | */ 152 | module( 153 | name: string, 154 | requires?: string[], 155 | configFn?: Function): IModule; 156 | 157 | noop(...args: any[]): void; 158 | reloadWithDebugInfo(): void; 159 | toJson(obj: any, pretty?: boolean): string; 160 | uppercase(str: string): string; 161 | version: { 162 | full: string; 163 | major: number; 164 | minor: number; 165 | dot: number; 166 | codeName: string; 167 | }; 168 | 169 | /** 170 | * If window.name contains prefix NG_DEFER_BOOTSTRAP! when angular.bootstrap is called, the bootstrap process will be paused until angular.resumeBootstrap() is called. 171 | * @param extraModules An optional array of modules that should be added to the original list of modules that the app was about to be bootstrapped with. 172 | */ 173 | resumeBootstrap?(extraModules?: string[]): ng.auto.IInjectorService; 174 | } 175 | 176 | /////////////////////////////////////////////////////////////////////////// 177 | // Module 178 | // see http://docs.angularjs.org/api/angular.Module 179 | /////////////////////////////////////////////////////////////////////////// 180 | interface IModule { 181 | /** 182 | * Use this method to register a component. 183 | * 184 | * @param name The name of the component. 185 | * @param options A definition object passed into the component. 186 | */ 187 | component(name: string, options: IComponentOptions): IModule; 188 | /** 189 | * Use this method to register work which needs to be performed on module loading. 190 | * 191 | * @param configFn Execute this function on module load. Useful for service configuration. 192 | */ 193 | config(configFn: Function): IModule; 194 | /** 195 | * Use this method to register work which needs to be performed on module loading. 196 | * 197 | * @param inlineAnnotatedFunction Execute this function on module load. Useful for service configuration. 198 | */ 199 | config(inlineAnnotatedFunction: any[]): IModule; 200 | config(object: Object): IModule; 201 | /** 202 | * Register a constant service, such as a string, a number, an array, an object or a function, with the $injector. Unlike value it can be injected into a module configuration function (see config) and it cannot be overridden by an Angular decorator. 203 | * 204 | * @param name The name of the constant. 205 | * @param value The constant value. 206 | */ 207 | constant(name: string, value: T): IModule; 208 | constant(object: Object): IModule; 209 | /** 210 | * The $controller service is used by Angular to create new controllers. 211 | * 212 | * This provider allows controller registration via the register method. 213 | * 214 | * @param name Controller name, or an object map of controllers where the keys are the names and the values are the constructors. 215 | * @param controllerConstructor Controller constructor fn (optionally decorated with DI annotations in the array notation). 216 | */ 217 | controller(name: string, controllerConstructor: Function): IModule; 218 | /** 219 | * The $controller service is used by Angular to create new controllers. 220 | * 221 | * This provider allows controller registration via the register method. 222 | * 223 | * @param name Controller name, or an object map of controllers where the keys are the names and the values are the constructors. 224 | * @param controllerConstructor Controller constructor fn (optionally decorated with DI annotations in the array notation). 225 | */ 226 | controller(name: string, inlineAnnotatedConstructor: any[]): IModule; 227 | controller(object: Object): IModule; 228 | /** 229 | * Register a new directive with the compiler. 230 | * 231 | * @param name Name of the directive in camel-case (i.e. ngBind which will match as ng-bind) 232 | * @param directiveFactory An injectable directive factory function. 233 | */ 234 | directive(name: string, directiveFactory: IDirectiveFactory): IModule; 235 | /** 236 | * Register a new directive with the compiler. 237 | * 238 | * @param name Name of the directive in camel-case (i.e. ngBind which will match as ng-bind) 239 | * @param directiveFactory An injectable directive factory function. 240 | */ 241 | directive(name: string, inlineAnnotatedFunction: any[]): IModule; 242 | directive(object: Object): IModule; 243 | /** 244 | * Register a service factory, which will be called to return the service instance. This is short for registering a service where its provider consists of only a $get property, which is the given service factory function. You should use $provide.factory(getFn) if you do not need to configure your service in a provider. 245 | * 246 | * @param name The name of the instance. 247 | * @param $getFn The $getFn for the instance creation. Internally this is a short hand for $provide.provider(name, {$get: $getFn}). 248 | */ 249 | factory(name: string, $getFn: Function): IModule; 250 | /** 251 | * Register a service factory, which will be called to return the service instance. This is short for registering a service where its provider consists of only a $get property, which is the given service factory function. You should use $provide.factory(getFn) if you do not need to configure your service in a provider. 252 | * 253 | * @param name The name of the instance. 254 | * @param inlineAnnotatedFunction The $getFn for the instance creation. Internally this is a short hand for $provide.provider(name, {$get: $getFn}). 255 | */ 256 | factory(name: string, inlineAnnotatedFunction: any[]): IModule; 257 | factory(object: Object): IModule; 258 | filter(name: string, filterFactoryFunction: Function): IModule; 259 | filter(name: string, inlineAnnotatedFunction: any[]): IModule; 260 | filter(object: Object): IModule; 261 | provider(name: string, serviceProviderFactory: IServiceProviderFactory): IModule; 262 | provider(name: string, serviceProviderConstructor: IServiceProviderClass): IModule; 263 | provider(name: string, inlineAnnotatedConstructor: any[]): IModule; 264 | provider(name: string, providerObject: IServiceProvider): IModule; 265 | provider(object: Object): IModule; 266 | /** 267 | * Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests. 268 | */ 269 | run(initializationFunction: Function): IModule; 270 | /** 271 | * Run blocks are the closest thing in Angular to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the service have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests. 272 | */ 273 | run(inlineAnnotatedFunction: any[]): IModule; 274 | /** 275 | * Register a service constructor, which will be invoked with new to create the service instance. This is short for registering a service where its provider's $get property is a factory function that returns an instance instantiated by the injector from the service constructor function. 276 | * 277 | * @param name The name of the instance. 278 | * @param serviceConstructor An injectable class (constructor function) that will be instantiated. 279 | */ 280 | service(name: string, serviceConstructor: Function): IModule; 281 | /** 282 | * Register a service constructor, which will be invoked with new to create the service instance. This is short for registering a service where its provider's $get property is a factory function that returns an instance instantiated by the injector from the service constructor function. 283 | * 284 | * @param name The name of the instance. 285 | * @param inlineAnnotatedConstructor An injectable class (constructor function) that will be instantiated. 286 | */ 287 | service(name: string, inlineAnnotatedConstructor: any[]): IModule; 288 | service(object: Object): IModule; 289 | /** 290 | * Register a value service with the $injector, such as a string, a number, an array, an object or a function. This is short for registering a service where its provider's $get property is a factory function that takes no arguments and returns the value service. 291 | 292 | Value services are similar to constant services, except that they cannot be injected into a module configuration function (see config) but they can be overridden by an Angular decorator. 293 | * 294 | * @param name The name of the instance. 295 | * @param value The value. 296 | */ 297 | value(name: string, value: T): IModule; 298 | value(object: Object): IModule; 299 | 300 | /** 301 | * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. 302 | * @param name The name of the service to decorate 303 | * @param decorator This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. 304 | */ 305 | decorator(name:string, decoratorConstructor: Function): IModule; 306 | decorator(name:string, inlineAnnotatedConstructor: any[]): IModule; 307 | 308 | // Properties 309 | name: string; 310 | requires: string[]; 311 | } 312 | 313 | /////////////////////////////////////////////////////////////////////////// 314 | // Attributes 315 | // see http://docs.angularjs.org/api/ng.$compile.directive.Attributes 316 | /////////////////////////////////////////////////////////////////////////// 317 | interface IAttributes { 318 | /** 319 | * this is necessary to be able to access the scoped attributes. it's not very elegant 320 | * because you have to use attrs['foo'] instead of attrs.foo but I don't know of a better way 321 | * this should really be limited to return string but it creates this problem: http://stackoverflow.com/q/17201854/165656 322 | */ 323 | [name: string]: any; 324 | 325 | /** 326 | * Converts an attribute name (e.g. dash/colon/underscore-delimited string, optionally prefixed with x- or data-) to its normalized, camelCase form. 327 | * 328 | * Also there is special case for Moz prefix starting with upper case letter. 329 | * 330 | * For further information check out the guide on @see https://docs.angularjs.org/guide/directive#matching-directives 331 | */ 332 | $normalize(name: string): string; 333 | 334 | /** 335 | * Adds the CSS class value specified by the classVal parameter to the 336 | * element. If animations are enabled then an animation will be triggered 337 | * for the class addition. 338 | */ 339 | $addClass(classVal: string): void; 340 | 341 | /** 342 | * Removes the CSS class value specified by the classVal parameter from the 343 | * element. If animations are enabled then an animation will be triggered for 344 | * the class removal. 345 | */ 346 | $removeClass(classVal: string): void; 347 | 348 | /** 349 | * Adds and removes the appropriate CSS class values to the element based on the difference between 350 | * the new and old CSS class values (specified as newClasses and oldClasses). 351 | */ 352 | $updateClass(newClasses: string, oldClasses: string): void; 353 | 354 | /** 355 | * Set DOM element attribute value. 356 | */ 357 | $set(key: string, value: any): void; 358 | 359 | /** 360 | * Observes an interpolated attribute. 361 | * The observer function will be invoked once during the next $digest 362 | * following compilation. The observer is then invoked whenever the 363 | * interpolated value changes. 364 | */ 365 | $observe(name: string, fn: (value?: T) => any): Function; 366 | 367 | /** 368 | * A map of DOM element attribute names to the normalized name. This is needed 369 | * to do reverse lookup from normalized name back to actual name. 370 | */ 371 | $attr: Object; 372 | } 373 | 374 | /** 375 | * form.FormController - type in module ng 376 | * see https://docs.angularjs.org/api/ng/type/form.FormController 377 | */ 378 | interface IFormController { 379 | 380 | /** 381 | * Indexer which should return ng.INgModelController for most properties but cannot because of "All named properties must be assignable to string indexer type" constraint - see https://github.com/Microsoft/TypeScript/issues/272 382 | */ 383 | [name: string]: any; 384 | 385 | $pristine: boolean; 386 | $dirty: boolean; 387 | $valid: boolean; 388 | $invalid: boolean; 389 | $submitted: boolean; 390 | $error: any; 391 | $pending: any; 392 | $addControl(control: INgModelController): void; 393 | $removeControl(control: INgModelController): void; 394 | $setValidity(validationErrorKey: string, isValid: boolean, control: INgModelController): void; 395 | $setDirty(): void; 396 | $setPristine(): void; 397 | $commitViewValue(): void; 398 | $rollbackViewValue(): void; 399 | $setSubmitted(): void; 400 | $setUntouched(): void; 401 | } 402 | 403 | /////////////////////////////////////////////////////////////////////////// 404 | // NgModelController 405 | // see http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController 406 | /////////////////////////////////////////////////////////////////////////// 407 | interface INgModelController { 408 | $render(): void; 409 | $setValidity(validationErrorKey: string, isValid: boolean): void; 410 | // Documentation states viewValue and modelValue to be a string but other 411 | // types do work and it's common to use them. 412 | $setViewValue(value: any, trigger?: string): void; 413 | $setPristine(): void; 414 | $setDirty(): void; 415 | $validate(): void; 416 | $setTouched(): void; 417 | $setUntouched(): void; 418 | $rollbackViewValue(): void; 419 | $commitViewValue(): void; 420 | $isEmpty(value: any): boolean; 421 | 422 | $viewValue: any; 423 | 424 | $modelValue: any; 425 | 426 | $parsers: IModelParser[]; 427 | $formatters: IModelFormatter[]; 428 | $viewChangeListeners: IModelViewChangeListener[]; 429 | $error: any; 430 | $name: string; 431 | 432 | $touched: boolean; 433 | $untouched: boolean; 434 | 435 | $validators: IModelValidators; 436 | $asyncValidators: IAsyncModelValidators; 437 | 438 | $pending: any; 439 | $pristine: boolean; 440 | $dirty: boolean; 441 | $valid: boolean; 442 | $invalid: boolean; 443 | } 444 | 445 | //Allows tuning how model updates are done. 446 | //https://docs.angularjs.org/api/ng/directive/ngModelOptions 447 | interface INgModelOptions { 448 | updateOn?: string; 449 | debounce?: any; 450 | allowInvalid?: boolean; 451 | getterSetter?: boolean; 452 | timezone?: string; 453 | } 454 | 455 | interface IModelValidators { 456 | /** 457 | * viewValue is any because it can be an object that is called in the view like $viewValue.name:$viewValue.subName 458 | */ 459 | [index: string]: (modelValue: any, viewValue: any) => boolean; 460 | } 461 | 462 | interface IAsyncModelValidators { 463 | [index: string]: (modelValue: any, viewValue: any) => IPromise; 464 | } 465 | 466 | interface IModelParser { 467 | (value: any): any; 468 | } 469 | 470 | interface IModelFormatter { 471 | (value: any): any; 472 | } 473 | 474 | interface IModelViewChangeListener { 475 | (): void; 476 | } 477 | 478 | /** 479 | * $rootScope - $rootScopeProvider - service in module ng 480 | * see https://docs.angularjs.org/api/ng/type/$rootScope.Scope and https://docs.angularjs.org/api/ng/service/$rootScope 481 | */ 482 | interface IRootScopeService { 483 | [index: string]: any; 484 | 485 | $apply(): any; 486 | $apply(exp: string): any; 487 | $apply(exp: (scope: IScope) => any): any; 488 | 489 | $applyAsync(): any; 490 | $applyAsync(exp: string): any; 491 | $applyAsync(exp: (scope: IScope) => any): any; 492 | 493 | /** 494 | * Dispatches an event name downwards to all child scopes (and their children) notifying the registered $rootScope.Scope listeners. 495 | * 496 | * The event life cycle starts at the scope on which $broadcast was called. All listeners listening for name event on this scope get notified. Afterwards, the event propagates to all direct and indirect scopes of the current scope and calls all registered listeners along the way. The event cannot be canceled. 497 | * 498 | * Any exception emitted from the listeners will be passed onto the $exceptionHandler service. 499 | * 500 | * @param name Event name to broadcast. 501 | * @param args Optional one or more arguments which will be passed onto the event listeners. 502 | */ 503 | $broadcast(name: string, ...args: any[]): IAngularEvent; 504 | $destroy(): void; 505 | $digest(): void; 506 | /** 507 | * Dispatches an event name upwards through the scope hierarchy notifying the registered $rootScope.Scope listeners. 508 | * 509 | * The event life cycle starts at the scope on which $emit was called. All listeners listening for name event on this scope get notified. Afterwards, the event traverses upwards toward the root scope and calls all registered listeners along the way. The event will stop propagating if one of the listeners cancels it. 510 | * 511 | * Any exception emitted from the listeners will be passed onto the $exceptionHandler service. 512 | * 513 | * @param name Event name to emit. 514 | * @param args Optional one or more arguments which will be passed onto the event listeners. 515 | */ 516 | $emit(name: string, ...args: any[]): IAngularEvent; 517 | 518 | $eval(): any; 519 | $eval(expression: string, locals?: Object): any; 520 | $eval(expression: (scope: IScope) => any, locals?: Object): any; 521 | 522 | $evalAsync(): void; 523 | $evalAsync(expression: string): void; 524 | $evalAsync(expression: (scope: IScope) => any): void; 525 | 526 | // Defaults to false by the implementation checking strategy 527 | $new(isolate?: boolean, parent?: IScope): IScope; 528 | 529 | /** 530 | * Listens on events of a given type. See $emit for discussion of event life cycle. 531 | * 532 | * The event listener function format is: function(event, args...). 533 | * 534 | * @param name Event name to listen on. 535 | * @param listener Function to call when the event is emitted. 536 | */ 537 | $on(name: string, listener: (event: IAngularEvent, ...args: any[]) => any): () => void; 538 | 539 | $watch(watchExpression: string, listener?: string, objectEquality?: boolean): () => void; 540 | $watch(watchExpression: string, listener?: (newValue: T, oldValue: T, scope: IScope) => any, objectEquality?: boolean): () => void; 541 | $watch(watchExpression: (scope: IScope) => any, listener?: string, objectEquality?: boolean): () => void; 542 | $watch(watchExpression: (scope: IScope) => T, listener?: (newValue: T, oldValue: T, scope: IScope) => any, objectEquality?: boolean): () => void; 543 | 544 | $watchCollection(watchExpression: string, listener: (newValue: T, oldValue: T, scope: IScope) => any): () => void; 545 | $watchCollection(watchExpression: (scope: IScope) => T, listener: (newValue: T, oldValue: T, scope: IScope) => any): () => void; 546 | 547 | $watchGroup(watchExpressions: any[], listener: (newValue: any, oldValue: any, scope: IScope) => any): () => void; 548 | $watchGroup(watchExpressions: { (scope: IScope): any }[], listener: (newValue: any, oldValue: any, scope: IScope) => any): () => void; 549 | 550 | $parent: IScope; 551 | $root: IRootScopeService; 552 | $id: number; 553 | 554 | // Hidden members 555 | $$isolateBindings: any; 556 | $$phase: any; 557 | } 558 | 559 | interface IScope extends IRootScopeService { } 560 | 561 | /** 562 | * $scope for ngRepeat directive. 563 | * see https://docs.angularjs.org/api/ng/directive/ngRepeat 564 | */ 565 | interface IRepeatScope extends IScope { 566 | 567 | /** 568 | * iterator offset of the repeated element (0..length-1). 569 | */ 570 | $index: number; 571 | 572 | /** 573 | * true if the repeated element is first in the iterator. 574 | */ 575 | $first: boolean; 576 | 577 | /** 578 | * true if the repeated element is between the first and last in the iterator. 579 | */ 580 | $middle: boolean; 581 | 582 | /** 583 | * true if the repeated element is last in the iterator. 584 | */ 585 | $last: boolean; 586 | 587 | /** 588 | * true if the iterator position $index is even (otherwise false). 589 | */ 590 | $even: boolean; 591 | 592 | /** 593 | * true if the iterator position $index is odd (otherwise false). 594 | */ 595 | $odd: boolean; 596 | 597 | } 598 | 599 | interface IAngularEvent { 600 | /** 601 | * the scope on which the event was $emit-ed or $broadcast-ed. 602 | */ 603 | targetScope: IScope; 604 | /** 605 | * the scope that is currently handling the event. Once the event propagates through the scope hierarchy, this property is set to null. 606 | */ 607 | currentScope: IScope; 608 | /** 609 | * name of the event. 610 | */ 611 | name: string; 612 | /** 613 | * calling stopPropagation function will cancel further event propagation (available only for events that were $emit-ed). 614 | */ 615 | stopPropagation?: Function; 616 | /** 617 | * calling preventDefault sets defaultPrevented flag to true. 618 | */ 619 | preventDefault: Function; 620 | /** 621 | * true if preventDefault was called. 622 | */ 623 | defaultPrevented: boolean; 624 | } 625 | 626 | /////////////////////////////////////////////////////////////////////////// 627 | // WindowService 628 | // see http://docs.angularjs.org/api/ng.$window 629 | /////////////////////////////////////////////////////////////////////////// 630 | interface IWindowService extends Window { 631 | [key: string]: any; 632 | } 633 | 634 | /////////////////////////////////////////////////////////////////////////// 635 | // TimeoutService 636 | // see http://docs.angularjs.org/api/ng.$timeout 637 | /////////////////////////////////////////////////////////////////////////// 638 | interface ITimeoutService { 639 | (delay?: number, invokeApply?: boolean): IPromise; 640 | (fn: (...args: any[]) => T, delay?: number, invokeApply?: boolean, ...args: any[]): IPromise; 641 | cancel(promise?: IPromise): boolean; 642 | } 643 | 644 | /////////////////////////////////////////////////////////////////////////// 645 | // IntervalService 646 | // see http://docs.angularjs.org/api/ng.$interval 647 | /////////////////////////////////////////////////////////////////////////// 648 | interface IIntervalService { 649 | (func: Function, delay: number, count?: number, invokeApply?: boolean, ...args: any[]): IPromise; 650 | cancel(promise: IPromise): boolean; 651 | } 652 | 653 | /** 654 | * $filter - $filterProvider - service in module ng 655 | * 656 | * Filters are used for formatting data displayed to the user. 657 | * 658 | * see https://docs.angularjs.org/api/ng/service/$filter 659 | */ 660 | interface IFilterService { 661 | (name: 'filter'): IFilterFilter; 662 | (name: 'currency'): IFilterCurrency; 663 | (name: 'number'): IFilterNumber; 664 | (name: 'date'): IFilterDate; 665 | (name: 'json'): IFilterJson; 666 | (name: 'lowercase'): IFilterLowercase; 667 | (name: 'uppercase'): IFilterUppercase; 668 | (name: 'limitTo'): IFilterLimitTo; 669 | (name: 'orderBy'): IFilterOrderBy; 670 | /** 671 | * Usage: 672 | * $filter(name); 673 | * 674 | * @param name Name of the filter function to retrieve 675 | */ 676 | (name: string): T; 677 | } 678 | 679 | interface IFilterFilter { 680 | (array: T[], expression: string | IFilterFilterPatternObject | IFilterFilterPredicateFunc, comparator?: IFilterFilterComparatorFunc|boolean): T[]; 681 | } 682 | 683 | interface IFilterFilterPatternObject { 684 | [name: string]: any; 685 | } 686 | 687 | interface IFilterFilterPredicateFunc { 688 | (value: T, index: number, array: T[]): boolean; 689 | } 690 | 691 | interface IFilterFilterComparatorFunc { 692 | (actual: T, expected: T): boolean; 693 | } 694 | 695 | interface IFilterCurrency { 696 | /** 697 | * Formats a number as a currency (ie $1,234.56). When no currency symbol is provided, default symbol for current locale is used. 698 | * @param amount Input to filter. 699 | * @param symbol Currency symbol or identifier to be displayed. 700 | * @param fractionSize Number of decimal places to round the amount to, defaults to default max fraction size for current locale 701 | * @return Formatted number 702 | */ 703 | (amount: number, symbol?: string, fractionSize?: number): string; 704 | } 705 | 706 | interface IFilterNumber { 707 | /** 708 | * Formats a number as text. 709 | * @param number Number to format. 710 | * @param fractionSize Number of decimal places to round the number to. If this is not provided then the fraction size is computed from the current locale's number formatting pattern. In the case of the default locale, it will be 3. 711 | * @return Number rounded to decimalPlaces and places a “,” after each third digit. 712 | */ 713 | (value: number|string, fractionSize?: number|string): string; 714 | } 715 | 716 | interface IFilterDate { 717 | /** 718 | * Formats date to a string based on the requested format. 719 | * 720 | * @param date Date to format either as Date object, milliseconds (string or number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is specified in the string input, the time is considered to be in the local timezone. 721 | * @param format Formatting rules (see Description). If not specified, mediumDate is used. 722 | * @param timezone Timezone to be used for formatting. It understands UTC/GMT and the continental US time zone abbreviations, but for general use, use a time zone offset, for example, '+0430' (4 hours, 30 minutes east of the Greenwich meridian) If not specified, the timezone of the browser will be used. 723 | * @return Formatted string or the input if input is not recognized as date/millis. 724 | */ 725 | (date: Date | number | string, format?: string, timezone?: string): string; 726 | } 727 | 728 | interface IFilterJson { 729 | /** 730 | * Allows you to convert a JavaScript object into JSON string. 731 | * @param object Any JavaScript object (including arrays and primitive types) to filter. 732 | * @param spacing The number of spaces to use per indentation, defaults to 2. 733 | * @return JSON string. 734 | */ 735 | (object: any, spacing?: number): string; 736 | } 737 | 738 | interface IFilterLowercase { 739 | /** 740 | * Converts string to lowercase. 741 | */ 742 | (value: string): string; 743 | } 744 | 745 | interface IFilterUppercase { 746 | /** 747 | * Converts string to uppercase. 748 | */ 749 | (value: string): string; 750 | } 751 | 752 | interface IFilterLimitTo { 753 | /** 754 | * Creates a new array containing only a specified number of elements. The elements are taken from either the beginning or the end of the source array, string or number, as specified by the value and sign (positive or negative) of limit. 755 | * @param input Source array to be limited. 756 | * @param limit The length of the returned array. If the limit number is positive, limit number of items from the beginning of the source array/string are copied. If the number is negative, limit number of items from the end of the source array are copied. The limit will be trimmed if it exceeds array.length. If limit is undefined, the input will be returned unchanged. 757 | * @param begin Index at which to begin limitation. As a negative index, begin indicates an offset from the end of input. Defaults to 0. 758 | * @return A new sub-array of length limit or less if input array had less than limit elements. 759 | */ 760 | (input: T[], limit: string|number, begin?: string|number): T[]; 761 | /** 762 | * Creates a new string containing only a specified number of elements. The elements are taken from either the beginning or the end of the source string or number, as specified by the value and sign (positive or negative) of limit. If a number is used as input, it is converted to a string. 763 | * @param input Source string or number to be limited. 764 | * @param limit The length of the returned string. If the limit number is positive, limit number of items from the beginning of the source string are copied. If the number is negative, limit number of items from the end of the source string are copied. The limit will be trimmed if it exceeds input.length. If limit is undefined, the input will be returned unchanged. 765 | * @param begin Index at which to begin limitation. As a negative index, begin indicates an offset from the end of input. Defaults to 0. 766 | * @return A new substring of length limit or less if input had less than limit elements. 767 | */ 768 | (input: string|number, limit: string|number, begin?: string|number): string; 769 | } 770 | 771 | interface IFilterOrderBy { 772 | /** 773 | * Orders a specified array by the expression predicate. It is ordered alphabetically for strings and numerically for numbers. Note: if you notice numbers are not being sorted as expected, make sure they are actually being saved as numbers and not strings. 774 | * @param array The array to sort. 775 | * @param expression A predicate to be used by the comparator to determine the order of elements. 776 | * @param reverse Reverse the order of the array. 777 | * @return Reverse the order of the array. 778 | */ 779 | (array: T[], expression: string|((value: T) => any)|(((value: T) => any)|string)[], reverse?: boolean): T[]; 780 | } 781 | 782 | /** 783 | * $filterProvider - $filter - provider in module ng 784 | * 785 | * Filters are just functions which transform input to an output. However filters need to be Dependency Injected. To achieve this a filter definition consists of a factory function which is annotated with dependencies and is responsible for creating a filter function. 786 | * 787 | * see https://docs.angularjs.org/api/ng/provider/$filterProvider 788 | */ 789 | interface IFilterProvider extends IServiceProvider { 790 | /** 791 | * register(name); 792 | * 793 | * @param name Name of the filter function, or an object map of filters where the keys are the filter names and the values are the filter factories. Note: Filter names must be valid angular Expressions identifiers, such as uppercase or orderBy. Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace your filters, then you can use capitalization (myappSubsectionFilterx) or underscores (myapp_subsection_filterx). 794 | */ 795 | register(name: string | {}): IServiceProvider; 796 | } 797 | 798 | /////////////////////////////////////////////////////////////////////////// 799 | // LocaleService 800 | // see http://docs.angularjs.org/api/ng.$locale 801 | /////////////////////////////////////////////////////////////////////////// 802 | interface ILocaleService { 803 | id: string; 804 | 805 | // These are not documented 806 | // Check angular's i18n files for exemples 807 | NUMBER_FORMATS: ILocaleNumberFormatDescriptor; 808 | DATETIME_FORMATS: ILocaleDateTimeFormatDescriptor; 809 | pluralCat: (num: any) => string; 810 | } 811 | 812 | interface ILocaleNumberFormatDescriptor { 813 | DECIMAL_SEP: string; 814 | GROUP_SEP: string; 815 | PATTERNS: ILocaleNumberPatternDescriptor[]; 816 | CURRENCY_SYM: string; 817 | } 818 | 819 | interface ILocaleNumberPatternDescriptor { 820 | minInt: number; 821 | minFrac: number; 822 | maxFrac: number; 823 | posPre: string; 824 | posSuf: string; 825 | negPre: string; 826 | negSuf: string; 827 | gSize: number; 828 | lgSize: number; 829 | } 830 | 831 | interface ILocaleDateTimeFormatDescriptor { 832 | MONTH: string[]; 833 | SHORTMONTH: string[]; 834 | DAY: string[]; 835 | SHORTDAY: string[]; 836 | AMPMS: string[]; 837 | medium: string; 838 | short: string; 839 | fullDate: string; 840 | longDate: string; 841 | mediumDate: string; 842 | shortDate: string; 843 | mediumTime: string; 844 | shortTime: string; 845 | } 846 | 847 | /////////////////////////////////////////////////////////////////////////// 848 | // LogService 849 | // see http://docs.angularjs.org/api/ng.$log 850 | // see http://docs.angularjs.org/api/ng.$logProvider 851 | /////////////////////////////////////////////////////////////////////////// 852 | interface ILogService { 853 | debug: ILogCall; 854 | error: ILogCall; 855 | info: ILogCall; 856 | log: ILogCall; 857 | warn: ILogCall; 858 | } 859 | 860 | interface ILogProvider extends IServiceProvider { 861 | debugEnabled(): boolean; 862 | debugEnabled(enabled: boolean): ILogProvider; 863 | } 864 | 865 | // We define this as separate interface so we can reopen it later for 866 | // the ngMock module. 867 | interface ILogCall { 868 | (...args: any[]): void; 869 | } 870 | 871 | /////////////////////////////////////////////////////////////////////////// 872 | // ParseService 873 | // see http://docs.angularjs.org/api/ng.$parse 874 | // see http://docs.angularjs.org/api/ng.$parseProvider 875 | /////////////////////////////////////////////////////////////////////////// 876 | interface IParseService { 877 | (expression: string): ICompiledExpression; 878 | } 879 | 880 | interface IParseProvider { 881 | logPromiseWarnings(): boolean; 882 | logPromiseWarnings(value: boolean): IParseProvider; 883 | 884 | unwrapPromises(): boolean; 885 | unwrapPromises(value: boolean): IParseProvider; 886 | } 887 | 888 | interface ICompiledExpression { 889 | (context: any, locals?: any): any; 890 | 891 | literal: boolean; 892 | constant: boolean; 893 | 894 | // If value is not provided, undefined is gonna be used since the implementation 895 | // does not check the parameter. Let's force a value for consistency. If consumer 896 | // whants to undefine it, pass the undefined value explicitly. 897 | assign(context: any, value: any): any; 898 | } 899 | 900 | /** 901 | * $location - $locationProvider - service in module ng 902 | * see https://docs.angularjs.org/api/ng/service/$location 903 | */ 904 | interface ILocationService { 905 | absUrl(): string; 906 | hash(): string; 907 | hash(newHash: string): ILocationService; 908 | host(): string; 909 | 910 | /** 911 | * Return path of current url 912 | */ 913 | path(): string; 914 | 915 | /** 916 | * Change path when called with parameter and return $location. 917 | * Note: Path should always begin with forward slash (/), this method will add the forward slash if it is missing. 918 | * 919 | * @param path New path 920 | */ 921 | path(path: string): ILocationService; 922 | 923 | port(): number; 924 | protocol(): string; 925 | replace(): ILocationService; 926 | 927 | /** 928 | * Return search part (as object) of current url 929 | */ 930 | search(): any; 931 | 932 | /** 933 | * Change search part when called with parameter and return $location. 934 | * 935 | * @param search When called with a single argument the method acts as a setter, setting the search component of $location to the specified value. 936 | * 937 | * If the argument is a hash object containing an array of values, these values will be encoded as duplicate search parameters in the url. 938 | */ 939 | search(search: any): ILocationService; 940 | 941 | /** 942 | * Change search part when called with parameter and return $location. 943 | * 944 | * @param search New search params 945 | * @param paramValue If search is a string or a Number, then paramValue will override only a single search property. If paramValue is null, the property specified via the first argument will be deleted. If paramValue is an array, it will override the property of the search component of $location specified via the first argument. If paramValue is true, the property specified via the first argument will be added with no value nor trailing equal sign. 946 | */ 947 | search(search: string, paramValue: string|number|string[]|boolean): ILocationService; 948 | 949 | state(): any; 950 | state(state: any): ILocationService; 951 | url(): string; 952 | url(url: string): ILocationService; 953 | } 954 | 955 | interface ILocationProvider extends IServiceProvider { 956 | hashPrefix(): string; 957 | hashPrefix(prefix: string): ILocationProvider; 958 | html5Mode(): boolean; 959 | 960 | // Documentation states that parameter is string, but 961 | // implementation tests it as boolean, which makes more sense 962 | // since this is a toggler 963 | html5Mode(active: boolean): ILocationProvider; 964 | html5Mode(mode: { enabled?: boolean; requireBase?: boolean; rewriteLinks?: boolean; }): ILocationProvider; 965 | } 966 | 967 | /////////////////////////////////////////////////////////////////////////// 968 | // DocumentService 969 | // see http://docs.angularjs.org/api/ng.$document 970 | /////////////////////////////////////////////////////////////////////////// 971 | interface IDocumentService extends IAugmentedJQuery {} 972 | 973 | /////////////////////////////////////////////////////////////////////////// 974 | // ExceptionHandlerService 975 | // see http://docs.angularjs.org/api/ng.$exceptionHandler 976 | /////////////////////////////////////////////////////////////////////////// 977 | interface IExceptionHandlerService { 978 | (exception: Error, cause?: string): void; 979 | } 980 | 981 | /////////////////////////////////////////////////////////////////////////// 982 | // RootElementService 983 | // see http://docs.angularjs.org/api/ng.$rootElement 984 | /////////////////////////////////////////////////////////////////////////// 985 | interface IRootElementService extends JQuery {} 986 | 987 | interface IQResolveReject { 988 | (): void; 989 | (value: T): void; 990 | } 991 | /** 992 | * $q - service in module ng 993 | * A promise/deferred implementation inspired by Kris Kowal's Q. 994 | * See http://docs.angularjs.org/api/ng/service/$q 995 | */ 996 | interface IQService { 997 | new (resolver: (resolve: IQResolveReject) => any): IPromise; 998 | new (resolver: (resolve: IQResolveReject, reject: IQResolveReject) => any): IPromise; 999 | (resolver: (resolve: IQResolveReject) => any): IPromise; 1000 | (resolver: (resolve: IQResolveReject, reject: IQResolveReject) => any): IPromise; 1001 | 1002 | /** 1003 | * Combines multiple promises into a single promise that is resolved when all of the input promises are resolved. 1004 | * 1005 | * Returns a single promise that will be resolved with an array of values, each value corresponding to the promise at the same index in the promises array. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value. 1006 | * 1007 | * @param promises An array of promises. 1008 | */ 1009 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise, T9 | IPromise, T10 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; 1010 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise, T9 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; 1011 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise, T8 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7, T8]>; 1012 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise, T7 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6, T7]>; 1013 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise, T6 | IPromise]): IPromise<[T1, T2, T3, T4, T5, T6]>; 1014 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise , T5 | IPromise]): IPromise<[T1, T2, T3, T4, T5]>; 1015 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise, T4 | IPromise ]): IPromise<[T1, T2, T3, T4]>; 1016 | all(values: [T1 | IPromise, T2 | IPromise, T3 | IPromise]): IPromise<[T1, T2, T3]>; 1017 | all(values: [T1 | IPromise, T2 | IPromise]): IPromise<[T1, T2]>; 1018 | all(promises: IPromise[]): IPromise; 1019 | /** 1020 | * Combines multiple promises into a single promise that is resolved when all of the input promises are resolved. 1021 | * 1022 | * Returns a single promise that will be resolved with a hash of values, each value corresponding to the promise at the same key in the promises hash. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value. 1023 | * 1024 | * @param promises A hash of promises. 1025 | */ 1026 | all(promises: { [id: string]: IPromise; }): IPromise<{ [id: string]: any; }>; 1027 | all(promises: { [id: string]: IPromise; }): IPromise; 1028 | /** 1029 | * Creates a Deferred object which represents a task which will finish in the future. 1030 | */ 1031 | defer(): IDeferred; 1032 | /** 1033 | * Creates a promise that is resolved as rejected with the specified reason. This api should be used to forward rejection in a chain of promises. If you are dealing with the last promise in a promise chain, you don't need to worry about it. 1034 | * 1035 | * When comparing deferreds/promises to the familiar behavior of try/catch/throw, think of reject as the throw keyword in JavaScript. This also means that if you "catch" an error via a promise error callback and you want to forward the error to the promise derived from the current promise, you have to "rethrow" the error by returning a rejection constructed via reject. 1036 | * 1037 | * @param reason Constant, message, exception or an object representing the rejection reason. 1038 | */ 1039 | reject(reason?: any): IPromise; 1040 | /** 1041 | * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. 1042 | * 1043 | * @param value Value or a promise 1044 | */ 1045 | resolve(value: IPromise|T): IPromise; 1046 | /** 1047 | * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. 1048 | */ 1049 | resolve(): IPromise; 1050 | /** 1051 | * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. 1052 | * 1053 | * @param value Value or a promise 1054 | */ 1055 | when(value: IPromise|T): IPromise; 1056 | /** 1057 | * Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted. 1058 | */ 1059 | when(): IPromise; 1060 | } 1061 | 1062 | interface IPromise { 1063 | /** 1064 | * Regardless of when the promise was or will be resolved or rejected, then calls one of the success or error callbacks asynchronously as soon as the result is available. The callbacks are called with a single argument: the result or rejection reason. Additionally, the notify callback may be called zero or more times to provide a progress indication, before the promise is resolved or rejected. 1065 | * The successCallBack may return IPromise for when a $q.reject() needs to be returned 1066 | * This method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback. It also notifies via the return value of the notifyCallback method. The promise can not be resolved or rejected from the notifyCallback method. 1067 | */ 1068 | then(successCallback: (promiseValue: T) => IPromise|TResult, errorCallback?: (reason: any) => any, notifyCallback?: (state: any) => any): IPromise; 1069 | 1070 | /** 1071 | * Shorthand for promise.then(null, errorCallback) 1072 | */ 1073 | catch(onRejected: (reason: any) => IPromise|TResult): IPromise; 1074 | 1075 | /** 1076 | * Allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful to release resources or do some clean-up that needs to be done whether the promise was rejected or resolved. See the full specification for more information. 1077 | * 1078 | * Because finally is a reserved word in JavaScript and reserved keywords are not supported as property names by ES3, you'll need to invoke the method like promise['finally'](callback) to make your code IE8 and Android 2.x compatible. 1079 | */ 1080 | finally(finallyCallback: () => any): IPromise; 1081 | } 1082 | 1083 | interface IDeferred { 1084 | resolve(value?: T|IPromise): void; 1085 | reject(reason?: any): void; 1086 | notify(state?: any): void; 1087 | promise: IPromise; 1088 | } 1089 | 1090 | /////////////////////////////////////////////////////////////////////////// 1091 | // AnchorScrollService 1092 | // see http://docs.angularjs.org/api/ng.$anchorScroll 1093 | /////////////////////////////////////////////////////////////////////////// 1094 | interface IAnchorScrollService { 1095 | (): void; 1096 | (hash: string): void; 1097 | yOffset: any; 1098 | } 1099 | 1100 | interface IAnchorScrollProvider extends IServiceProvider { 1101 | disableAutoScrolling(): void; 1102 | } 1103 | 1104 | /** 1105 | * $cacheFactory - service in module ng 1106 | * 1107 | * Factory that constructs Cache objects and gives access to them. 1108 | * 1109 | * see https://docs.angularjs.org/api/ng/service/$cacheFactory 1110 | */ 1111 | interface ICacheFactoryService { 1112 | /** 1113 | * Factory that constructs Cache objects and gives access to them. 1114 | * 1115 | * @param cacheId Name or id of the newly created cache. 1116 | * @param optionsMap Options object that specifies the cache behavior. Properties: 1117 | * 1118 | * capacity — turns the cache into LRU cache. 1119 | */ 1120 | (cacheId: string, optionsMap?: { capacity?: number; }): ICacheObject; 1121 | 1122 | /** 1123 | * Get information about all the caches that have been created. 1124 | * @returns key-value map of cacheId to the result of calling cache#info 1125 | */ 1126 | info(): any; 1127 | 1128 | /** 1129 | * Get access to a cache object by the cacheId used when it was created. 1130 | * 1131 | * @param cacheId Name or id of a cache to access. 1132 | */ 1133 | get(cacheId: string): ICacheObject; 1134 | } 1135 | 1136 | /** 1137 | * $cacheFactory.Cache - type in module ng 1138 | * 1139 | * A cache object used to store and retrieve data, primarily used by $http and the script directive to cache templates and other data. 1140 | * 1141 | * see https://docs.angularjs.org/api/ng/type/$cacheFactory.Cache 1142 | */ 1143 | interface ICacheObject { 1144 | /** 1145 | * Retrieve information regarding a particular Cache. 1146 | */ 1147 | info(): { 1148 | /** 1149 | * the id of the cache instance 1150 | */ 1151 | id: string; 1152 | 1153 | /** 1154 | * the number of entries kept in the cache instance 1155 | */ 1156 | size: number; 1157 | 1158 | //...: any additional properties from the options object when creating the cache. 1159 | }; 1160 | 1161 | /** 1162 | * Inserts a named entry into the Cache object to be retrieved later, and incrementing the size of the cache if the key was not already present in the cache. If behaving like an LRU cache, it will also remove stale entries from the set. 1163 | * 1164 | * It will not insert undefined values into the cache. 1165 | * 1166 | * @param key the key under which the cached data is stored. 1167 | * @param value the value to store alongside the key. If it is undefined, the key will not be stored. 1168 | */ 1169 | put(key: string, value?: T): T; 1170 | 1171 | /** 1172 | * Retrieves named data stored in the Cache object. 1173 | * 1174 | * @param key the key of the data to be retrieved 1175 | */ 1176 | get(key: string): T; 1177 | 1178 | /** 1179 | * Removes an entry from the Cache object. 1180 | * 1181 | * @param key the key of the entry to be removed 1182 | */ 1183 | remove(key: string): void; 1184 | 1185 | /** 1186 | * Clears the cache object of any entries. 1187 | */ 1188 | removeAll(): void; 1189 | 1190 | /** 1191 | * Destroys the Cache object entirely, removing it from the $cacheFactory set. 1192 | */ 1193 | destroy(): void; 1194 | } 1195 | 1196 | /////////////////////////////////////////////////////////////////////////// 1197 | // CompileService 1198 | // see http://docs.angularjs.org/api/ng.$compile 1199 | // see http://docs.angularjs.org/api/ng.$compileProvider 1200 | /////////////////////////////////////////////////////////////////////////// 1201 | interface ICompileService { 1202 | (element: string, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; 1203 | (element: Element, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; 1204 | (element: JQuery, transclude?: ITranscludeFunction, maxPriority?: number): ITemplateLinkingFunction; 1205 | } 1206 | 1207 | interface ICompileProvider extends IServiceProvider { 1208 | directive(name: string, directiveFactory: Function): ICompileProvider; 1209 | directive(directivesMap: Object, directiveFactory: Function): ICompileProvider; 1210 | directive(name: string, inlineAnnotatedFunction: any[]): ICompileProvider; 1211 | directive(directivesMap: Object, inlineAnnotatedFunction: any[]): ICompileProvider; 1212 | 1213 | // Undocumented, but it is there... 1214 | directive(directivesMap: any): ICompileProvider; 1215 | 1216 | component(name: string, options: IComponentOptions): ICompileProvider; 1217 | 1218 | aHrefSanitizationWhitelist(): RegExp; 1219 | aHrefSanitizationWhitelist(regexp: RegExp): ICompileProvider; 1220 | 1221 | imgSrcSanitizationWhitelist(): RegExp; 1222 | imgSrcSanitizationWhitelist(regexp: RegExp): ICompileProvider; 1223 | 1224 | debugInfoEnabled(enabled?: boolean): any; 1225 | } 1226 | 1227 | interface ICloneAttachFunction { 1228 | // Let's hint but not force cloneAttachFn's signature 1229 | (clonedElement?: JQuery, scope?: IScope): any; 1230 | } 1231 | 1232 | // This corresponds to the "publicLinkFn" returned by $compile. 1233 | interface ITemplateLinkingFunction { 1234 | (scope: IScope, cloneAttachFn?: ICloneAttachFunction): IAugmentedJQuery; 1235 | } 1236 | 1237 | // This corresponds to $transclude (and also the transclude function passed to link). 1238 | interface ITranscludeFunction { 1239 | // If the scope is provided, then the cloneAttachFn must be as well. 1240 | (scope: IScope, cloneAttachFn: ICloneAttachFunction): IAugmentedJQuery; 1241 | // If one argument is provided, then it's assumed to be the cloneAttachFn. 1242 | (cloneAttachFn?: ICloneAttachFunction): IAugmentedJQuery; 1243 | } 1244 | 1245 | /////////////////////////////////////////////////////////////////////////// 1246 | // ControllerService 1247 | // see http://docs.angularjs.org/api/ng.$controller 1248 | // see http://docs.angularjs.org/api/ng.$controllerProvider 1249 | /////////////////////////////////////////////////////////////////////////// 1250 | interface IControllerService { 1251 | // Although the documentation doesn't state this, locals are optional 1252 | (controllerConstructor: new (...args: any[]) => T, locals?: any, later?: boolean, ident?: string): T; 1253 | (controllerConstructor: Function, locals?: any, later?: boolean, ident?: string): T; 1254 | (controllerName: string, locals?: any, later?: boolean, ident?: string): T; 1255 | } 1256 | 1257 | interface IControllerProvider extends IServiceProvider { 1258 | register(name: string, controllerConstructor: Function): void; 1259 | register(name: string, dependencyAnnotatedConstructor: any[]): void; 1260 | allowGlobals(): void; 1261 | } 1262 | 1263 | /** 1264 | * xhrFactory 1265 | * Replace or decorate this service to create your own custom XMLHttpRequest objects. 1266 | * see https://docs.angularjs.org/api/ng/service/$xhrFactory 1267 | */ 1268 | interface IXhrFactory { 1269 | (method: string, url: string): T; 1270 | } 1271 | 1272 | /** 1273 | * HttpService 1274 | * see http://docs.angularjs.org/api/ng/service/$http 1275 | */ 1276 | interface IHttpService { 1277 | /** 1278 | * Object describing the request to be made and how it should be processed. 1279 | */ 1280 | (config: IRequestConfig): IHttpPromise; 1281 | 1282 | /** 1283 | * Shortcut method to perform GET request. 1284 | * 1285 | * @param url Relative or absolute URL specifying the destination of the request 1286 | * @param config Optional configuration object 1287 | */ 1288 | get(url: string, config?: IRequestShortcutConfig): IHttpPromise; 1289 | 1290 | /** 1291 | * Shortcut method to perform DELETE request. 1292 | * 1293 | * @param url Relative or absolute URL specifying the destination of the request 1294 | * @param config Optional configuration object 1295 | */ 1296 | delete(url: string, config?: IRequestShortcutConfig): IHttpPromise; 1297 | 1298 | /** 1299 | * Shortcut method to perform HEAD request. 1300 | * 1301 | * @param url Relative or absolute URL specifying the destination of the request 1302 | * @param config Optional configuration object 1303 | */ 1304 | head(url: string, config?: IRequestShortcutConfig): IHttpPromise; 1305 | 1306 | /** 1307 | * Shortcut method to perform JSONP request. 1308 | * 1309 | * @param url Relative or absolute URL specifying the destination of the request 1310 | * @param config Optional configuration object 1311 | */ 1312 | jsonp(url: string, config?: IRequestShortcutConfig): IHttpPromise; 1313 | 1314 | /** 1315 | * Shortcut method to perform POST request. 1316 | * 1317 | * @param url Relative or absolute URL specifying the destination of the request 1318 | * @param data Request content 1319 | * @param config Optional configuration object 1320 | */ 1321 | post(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; 1322 | 1323 | /** 1324 | * Shortcut method to perform PUT request. 1325 | * 1326 | * @param url Relative or absolute URL specifying the destination of the request 1327 | * @param data Request content 1328 | * @param config Optional configuration object 1329 | */ 1330 | put(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; 1331 | 1332 | /** 1333 | * Shortcut method to perform PATCH request. 1334 | * 1335 | * @param url Relative or absolute URL specifying the destination of the request 1336 | * @param data Request content 1337 | * @param config Optional configuration object 1338 | */ 1339 | patch(url: string, data: any, config?: IRequestShortcutConfig): IHttpPromise; 1340 | 1341 | /** 1342 | * Runtime equivalent of the $httpProvider.defaults property. Allows configuration of default headers, withCredentials as well as request and response transformations. 1343 | */ 1344 | defaults: IHttpProviderDefaults; 1345 | 1346 | /** 1347 | * Array of config objects for currently pending requests. This is primarily meant to be used for debugging purposes. 1348 | */ 1349 | pendingRequests: IRequestConfig[]; 1350 | } 1351 | 1352 | /** 1353 | * Object describing the request to be made and how it should be processed. 1354 | * see http://docs.angularjs.org/api/ng/service/$http#usage 1355 | */ 1356 | interface IRequestShortcutConfig extends IHttpProviderDefaults { 1357 | /** 1358 | * {Object.} 1359 | * Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified. 1360 | */ 1361 | params?: any; 1362 | 1363 | /** 1364 | * {string|Object} 1365 | * Data to be sent as the request message data. 1366 | */ 1367 | data?: any; 1368 | 1369 | /** 1370 | * Timeout in milliseconds, or promise that should abort the request when resolved. 1371 | */ 1372 | timeout?: number|IPromise; 1373 | 1374 | /** 1375 | * See [XMLHttpRequest.responseType]https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype 1376 | */ 1377 | responseType?: string; 1378 | } 1379 | 1380 | /** 1381 | * Object describing the request to be made and how it should be processed. 1382 | * see http://docs.angularjs.org/api/ng/service/$http#usage 1383 | */ 1384 | interface IRequestConfig extends IRequestShortcutConfig { 1385 | /** 1386 | * HTTP method (e.g. 'GET', 'POST', etc) 1387 | */ 1388 | method: string; 1389 | /** 1390 | * Absolute or relative URL of the resource that is being requested. 1391 | */ 1392 | url: string; 1393 | } 1394 | 1395 | interface IHttpHeadersGetter { 1396 | (): { [name: string]: string; }; 1397 | (headerName: string): string; 1398 | } 1399 | 1400 | interface IHttpPromiseCallback { 1401 | (data: T, status: number, headers: IHttpHeadersGetter, config: IRequestConfig): void; 1402 | } 1403 | 1404 | interface IHttpPromiseCallbackArg { 1405 | data?: T; 1406 | status?: number; 1407 | headers?: IHttpHeadersGetter; 1408 | config?: IRequestConfig; 1409 | statusText?: string; 1410 | } 1411 | 1412 | interface IHttpPromise extends IPromise> { 1413 | /** 1414 | * The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. 1415 | * If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error. 1416 | * @deprecated 1417 | */ 1418 | success?(callback: IHttpPromiseCallback): IHttpPromise; 1419 | /** 1420 | * The $http legacy promise methods success and error have been deprecated. Use the standard then method instead. 1421 | * If $httpProvider.useLegacyPromiseExtensions is set to false then these methods will throw $http/legacy error. 1422 | * @deprecated 1423 | */ 1424 | error?(callback: IHttpPromiseCallback): IHttpPromise; 1425 | } 1426 | 1427 | // See the jsdoc for transformData() at https://github.com/angular/angular.js/blob/master/src/ng/http.js#L228 1428 | interface IHttpRequestTransformer { 1429 | (data: any, headersGetter: IHttpHeadersGetter): any; 1430 | } 1431 | 1432 | // The definition of fields are the same as IHttpPromiseCallbackArg 1433 | interface IHttpResponseTransformer { 1434 | (data: any, headersGetter: IHttpHeadersGetter, status: number): any; 1435 | } 1436 | 1437 | type HttpHeaderType = {[requestType: string]:string|((config:IRequestConfig) => string)}; 1438 | 1439 | interface IHttpRequestConfigHeaders { 1440 | [requestType: string]: any; 1441 | common?: any; 1442 | get?: any; 1443 | post?: any; 1444 | put?: any; 1445 | patch?: any; 1446 | } 1447 | 1448 | /** 1449 | * Object that controls the defaults for $http provider. Not all fields of IRequestShortcutConfig can be configured 1450 | * via defaults and the docs do not say which. The following is based on the inspection of the source code. 1451 | * https://docs.angularjs.org/api/ng/service/$http#defaults 1452 | * https://docs.angularjs.org/api/ng/service/$http#usage 1453 | * https://docs.angularjs.org/api/ng/provider/$httpProvider The properties section 1454 | */ 1455 | interface IHttpProviderDefaults { 1456 | /** 1457 | * {boolean|Cache} 1458 | * If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching. 1459 | */ 1460 | cache?: any; 1461 | 1462 | /** 1463 | * Transform function or an array of such functions. The transform function takes the http request body and 1464 | * headers and returns its transformed (typically serialized) version. 1465 | * @see {@link https://docs.angularjs.org/api/ng/service/$http#transforming-requests-and-responses} 1466 | */ 1467 | transformRequest?: IHttpRequestTransformer |IHttpRequestTransformer[]; 1468 | 1469 | /** 1470 | * Transform function or an array of such functions. The transform function takes the http response body and 1471 | * headers and returns its transformed (typically deserialized) version. 1472 | */ 1473 | transformResponse?: IHttpResponseTransformer | IHttpResponseTransformer[]; 1474 | 1475 | /** 1476 | * Map of strings or functions which return strings representing HTTP headers to send to the server. If the 1477 | * return value of a function is null, the header will not be sent. 1478 | * The key of the map is the request verb in lower case. The "common" key applies to all requests. 1479 | * @see {@link https://docs.angularjs.org/api/ng/service/$http#setting-http-headers} 1480 | */ 1481 | headers?: IHttpRequestConfigHeaders; 1482 | 1483 | /** Name of HTTP header to populate with the XSRF token. */ 1484 | xsrfHeaderName?: string; 1485 | 1486 | /** Name of cookie containing the XSRF token. */ 1487 | xsrfCookieName?: string; 1488 | 1489 | /** 1490 | * whether to to set the withCredentials flag on the XHR object. See [requests with credentials]https://developer.mozilla.org/en/http_access_control#section_5 for more information. 1491 | */ 1492 | withCredentials?: boolean; 1493 | 1494 | /** 1495 | * A function used to the prepare string representation of request parameters (specified as an object). If 1496 | * specified as string, it is interpreted as a function registered with the $injector. Defaults to 1497 | * $httpParamSerializer. 1498 | */ 1499 | paramSerializer?: string | ((obj: any) => string); 1500 | } 1501 | 1502 | interface IHttpInterceptor { 1503 | request?: (config: IRequestConfig) => IRequestConfig|IPromise; 1504 | requestError?: (rejection: any) => any; 1505 | response?: (response: IHttpPromiseCallbackArg) => IPromise>|IHttpPromiseCallbackArg; 1506 | responseError?: (rejection: any) => any; 1507 | } 1508 | 1509 | interface IHttpInterceptorFactory { 1510 | (...args: any[]): IHttpInterceptor; 1511 | } 1512 | 1513 | interface IHttpProvider extends IServiceProvider { 1514 | defaults: IHttpProviderDefaults; 1515 | 1516 | /** 1517 | * Register service factories (names or implementations) for interceptors which are called before and after 1518 | * each request. 1519 | */ 1520 | interceptors: (string|IHttpInterceptorFactory|(string|IHttpInterceptorFactory)[])[]; 1521 | useApplyAsync(): boolean; 1522 | useApplyAsync(value: boolean): IHttpProvider; 1523 | 1524 | /** 1525 | * 1526 | * @param {boolean=} value If true, `$http` will return a normal promise without the `success` and `error` methods. 1527 | * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining. 1528 | * otherwise, returns the current configured value. 1529 | */ 1530 | useLegacyPromiseExtensions(value:boolean) : boolean | IHttpProvider; 1531 | } 1532 | 1533 | /////////////////////////////////////////////////////////////////////////// 1534 | // HttpBackendService 1535 | // see http://docs.angularjs.org/api/ng.$httpBackend 1536 | // You should never need to use this service directly. 1537 | /////////////////////////////////////////////////////////////////////////// 1538 | interface IHttpBackendService { 1539 | // XXX Perhaps define callback signature in the future 1540 | (method: string, url: string, post?: any, callback?: Function, headers?: any, timeout?: number, withCredentials?: boolean): void; 1541 | } 1542 | 1543 | /////////////////////////////////////////////////////////////////////////// 1544 | // InterpolateService 1545 | // see http://docs.angularjs.org/api/ng.$interpolate 1546 | // see http://docs.angularjs.org/api/ng.$interpolateProvider 1547 | /////////////////////////////////////////////////////////////////////////// 1548 | interface IInterpolateService { 1549 | (text: string, mustHaveExpression?: boolean, trustedContext?: string, allOrNothing?: boolean): IInterpolationFunction; 1550 | endSymbol(): string; 1551 | startSymbol(): string; 1552 | } 1553 | 1554 | interface IInterpolationFunction { 1555 | (context: any): string; 1556 | } 1557 | 1558 | interface IInterpolateProvider extends IServiceProvider { 1559 | startSymbol(): string; 1560 | startSymbol(value: string): IInterpolateProvider; 1561 | endSymbol(): string; 1562 | endSymbol(value: string): IInterpolateProvider; 1563 | } 1564 | 1565 | /////////////////////////////////////////////////////////////////////////// 1566 | // TemplateCacheService 1567 | // see http://docs.angularjs.org/api/ng.$templateCache 1568 | /////////////////////////////////////////////////////////////////////////// 1569 | interface ITemplateCacheService extends ICacheObject {} 1570 | 1571 | /////////////////////////////////////////////////////////////////////////// 1572 | // SCEService 1573 | // see http://docs.angularjs.org/api/ng.$sce 1574 | /////////////////////////////////////////////////////////////////////////// 1575 | interface ISCEService { 1576 | getTrusted(type: string, mayBeTrusted: any): any; 1577 | getTrustedCss(value: any): any; 1578 | getTrustedHtml(value: any): any; 1579 | getTrustedJs(value: any): any; 1580 | getTrustedResourceUrl(value: any): any; 1581 | getTrustedUrl(value: any): any; 1582 | parse(type: string, expression: string): (context: any, locals: any) => any; 1583 | parseAsCss(expression: string): (context: any, locals: any) => any; 1584 | parseAsHtml(expression: string): (context: any, locals: any) => any; 1585 | parseAsJs(expression: string): (context: any, locals: any) => any; 1586 | parseAsResourceUrl(expression: string): (context: any, locals: any) => any; 1587 | parseAsUrl(expression: string): (context: any, locals: any) => any; 1588 | trustAs(type: string, value: any): any; 1589 | trustAsHtml(value: any): any; 1590 | trustAsJs(value: any): any; 1591 | trustAsResourceUrl(value: any): any; 1592 | trustAsUrl(value: any): any; 1593 | isEnabled(): boolean; 1594 | } 1595 | 1596 | /////////////////////////////////////////////////////////////////////////// 1597 | // SCEProvider 1598 | // see http://docs.angularjs.org/api/ng.$sceProvider 1599 | /////////////////////////////////////////////////////////////////////////// 1600 | interface ISCEProvider extends IServiceProvider { 1601 | enabled(value: boolean): void; 1602 | } 1603 | 1604 | /////////////////////////////////////////////////////////////////////////// 1605 | // SCEDelegateService 1606 | // see http://docs.angularjs.org/api/ng.$sceDelegate 1607 | /////////////////////////////////////////////////////////////////////////// 1608 | interface ISCEDelegateService { 1609 | getTrusted(type: string, mayBeTrusted: any): any; 1610 | trustAs(type: string, value: any): any; 1611 | valueOf(value: any): any; 1612 | } 1613 | 1614 | 1615 | /////////////////////////////////////////////////////////////////////////// 1616 | // SCEDelegateProvider 1617 | // see http://docs.angularjs.org/api/ng.$sceDelegateProvider 1618 | /////////////////////////////////////////////////////////////////////////// 1619 | interface ISCEDelegateProvider extends IServiceProvider { 1620 | resourceUrlBlacklist(blacklist: any[]): void; 1621 | resourceUrlWhitelist(whitelist: any[]): void; 1622 | resourceUrlBlacklist(): any[]; 1623 | resourceUrlWhitelist(): any[]; 1624 | } 1625 | 1626 | /** 1627 | * $templateRequest service 1628 | * see http://docs.angularjs.org/api/ng/service/$templateRequest 1629 | */ 1630 | interface ITemplateRequestService { 1631 | /** 1632 | * Downloads a template using $http and, upon success, stores the 1633 | * contents inside of $templateCache. 1634 | * 1635 | * If the HTTP request fails or the response data of the HTTP request is 1636 | * empty then a $compile error will be thrown (unless 1637 | * {ignoreRequestError} is set to true). 1638 | * 1639 | * @param tpl The template URL. 1640 | * @param ignoreRequestError Whether or not to ignore the exception 1641 | * when the request fails or the template is 1642 | * empty. 1643 | * 1644 | * @return A promise whose value is the template content. 1645 | */ 1646 | (tpl: string, ignoreRequestError?: boolean): IPromise; 1647 | /** 1648 | * total amount of pending template requests being downloaded. 1649 | * @type {number} 1650 | */ 1651 | totalPendingRequests: number; 1652 | } 1653 | 1654 | /////////////////////////////////////////////////////////////////////////// 1655 | // Component 1656 | // see http://angularjs.blogspot.com.br/2015/11/angularjs-15-beta2-and-14-releases.html 1657 | // and http://toddmotto.com/exploring-the-angular-1-5-component-method/ 1658 | /////////////////////////////////////////////////////////////////////////// 1659 | /** 1660 | * Runtime representation a type that a Component or other object is instances of. 1661 | * 1662 | * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is be represented by 1663 | * the `MyCustomComponent` constructor function. 1664 | */ 1665 | interface Type extends Function { 1666 | } 1667 | 1668 | /** 1669 | * `RouteDefinition` defines a route within a {@link RouteConfig} decorator. 1670 | * 1671 | * Supported keys: 1672 | * - `path` or `aux` (requires exactly one of these) 1673 | * - `component`, `loader`, `redirectTo` (requires exactly one of these) 1674 | * - `name` or `as` (optional) (requires exactly one of these) 1675 | * - `data` (optional) 1676 | * 1677 | * See also {@link Route}, {@link AsyncRoute}, {@link AuxRoute}, and {@link Redirect}. 1678 | */ 1679 | interface RouteDefinition { 1680 | path?: string; 1681 | aux?: string; 1682 | component?: Type | ComponentDefinition | string; 1683 | loader?: Function; 1684 | redirectTo?: any[]; 1685 | as?: string; 1686 | name?: string; 1687 | data?: any; 1688 | useAsDefault?: boolean; 1689 | } 1690 | 1691 | /** 1692 | * Represents either a component type (`type` is `component`) or a loader function 1693 | * (`type` is `loader`). 1694 | * 1695 | * See also {@link RouteDefinition}. 1696 | */ 1697 | interface ComponentDefinition { 1698 | type: string; 1699 | loader?: Function; 1700 | component?: Type; 1701 | } 1702 | 1703 | /** 1704 | * Component definition object (a simplified directive definition object) 1705 | */ 1706 | interface IComponentOptions { 1707 | /** 1708 | * Controller constructor function that should be associated with newly created scope or the name of a registered 1709 | * controller if passed as a string. Empty function by default. 1710 | * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) 1711 | */ 1712 | controller?: string | Function | (string | Function)[]; 1713 | /** 1714 | * An identifier name for a reference to the controller. If present, the controller will be published to scope under 1715 | * the controllerAs name. If not present, this will default to be the same as the component name. 1716 | * @default "$ctrl" 1717 | */ 1718 | controllerAs?: string; 1719 | /** 1720 | * html template as a string or a function that returns an html template as a string which should be used as the 1721 | * contents of this component. Empty string by default. 1722 | * If template is a function, then it is injected with the following locals: 1723 | * $element - Current element 1724 | * $attrs - Current attributes object for the element 1725 | * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) 1726 | */ 1727 | template?: string | Function | (string | Function)[]; 1728 | /** 1729 | * path or function that returns a path to an html template that should be used as the contents of this component. 1730 | * If templateUrl is a function, then it is injected with the following locals: 1731 | * $element - Current element 1732 | * $attrs - Current attributes object for the element 1733 | * Use the array form to define dependencies (necessary if strictDi is enabled and you require dependency injection) 1734 | */ 1735 | templateUrl?: string | Function | (string | Function)[]; 1736 | /** 1737 | * Define DOM attribute binding to component properties. Component properties are always bound to the component 1738 | * controller and not to the scope. 1739 | */ 1740 | bindings?: {[binding: string]: string}; 1741 | /** 1742 | * Whether transclusion is enabled. Enabled by default. 1743 | */ 1744 | transclude?: boolean | string | {[slot: string]: string}; 1745 | require?: string | string[] | {[controller: string]: string}; 1746 | } 1747 | 1748 | interface IComponentTemplateFn { 1749 | ( $element?: IAugmentedJQuery, $attrs?: IAttributes ): string; 1750 | } 1751 | 1752 | /////////////////////////////////////////////////////////////////////////// 1753 | // Directive 1754 | // see http://docs.angularjs.org/api/ng.$compileProvider#directive 1755 | // and http://docs.angularjs.org/guide/directive 1756 | /////////////////////////////////////////////////////////////////////////// 1757 | 1758 | interface IDirectiveFactory { 1759 | (...args: any[]): IDirective; 1760 | } 1761 | 1762 | interface IDirectiveLinkFn { 1763 | ( 1764 | scope: IScope, 1765 | instanceElement: IAugmentedJQuery, 1766 | instanceAttributes: IAttributes, 1767 | controller: {}, 1768 | transclude: ITranscludeFunction 1769 | ): void; 1770 | } 1771 | 1772 | interface IDirectivePrePost { 1773 | pre?: IDirectiveLinkFn; 1774 | post?: IDirectiveLinkFn; 1775 | } 1776 | 1777 | interface IDirectiveCompileFn { 1778 | ( 1779 | templateElement: IAugmentedJQuery, 1780 | templateAttributes: IAttributes, 1781 | /** 1782 | * @deprecated 1783 | * Note: The transclude function that is passed to the compile function is deprecated, 1784 | * as it e.g. does not know about the right outer scope. Please use the transclude function 1785 | * that is passed to the link function instead. 1786 | */ 1787 | transclude: ITranscludeFunction 1788 | ): IDirectivePrePost; 1789 | } 1790 | 1791 | interface IDirective { 1792 | compile?: IDirectiveCompileFn; 1793 | controller?: any; 1794 | controllerAs?: string; 1795 | /** 1796 | * @deprecated 1797 | * Deprecation warning: although bindings for non-ES6 class controllers are currently bound to this before 1798 | * the controller constructor is called, this use is now deprecated. Please place initialization code that 1799 | * relies upon bindings inside a $onInit method on the controller, instead. 1800 | */ 1801 | bindToController?: boolean | Object; 1802 | link?: IDirectiveLinkFn | IDirectivePrePost; 1803 | multiElement?: boolean; 1804 | name?: string; 1805 | priority?: number; 1806 | /** 1807 | * @deprecated 1808 | */ 1809 | replace?: boolean; 1810 | require?: string | string[] | {[controller: string]: string}; 1811 | restrict?: string; 1812 | scope?: boolean | Object; 1813 | template?: string | Function; 1814 | templateNamespace?: string; 1815 | templateUrl?: string | Function; 1816 | terminal?: boolean; 1817 | transclude?: boolean | string | {[slot: string]: string}; 1818 | } 1819 | 1820 | /** 1821 | * angular.element 1822 | * when calling angular.element, angular returns a jQuery object, 1823 | * augmented with additional methods like e.g. scope. 1824 | * see: http://docs.angularjs.org/api/angular.element 1825 | */ 1826 | interface IAugmentedJQueryStatic extends JQueryStatic { 1827 | (selector: string, context?: any): IAugmentedJQuery; 1828 | (element: Element): IAugmentedJQuery; 1829 | (object: {}): IAugmentedJQuery; 1830 | (elementArray: Element[]): IAugmentedJQuery; 1831 | (object: JQuery): IAugmentedJQuery; 1832 | (func: Function): IAugmentedJQuery; 1833 | (array: any[]): IAugmentedJQuery; 1834 | (): IAugmentedJQuery; 1835 | } 1836 | 1837 | interface IAugmentedJQuery extends JQuery { 1838 | // TODO: events, how to define? 1839 | //$destroy 1840 | 1841 | find(selector: string): IAugmentedJQuery; 1842 | find(element: any): IAugmentedJQuery; 1843 | find(obj: JQuery): IAugmentedJQuery; 1844 | controller(): any; 1845 | controller(name: string): any; 1846 | injector(): any; 1847 | scope(): IScope; 1848 | 1849 | /** 1850 | * Overload for custom scope interfaces 1851 | */ 1852 | scope(): T; 1853 | isolateScope(): IScope; 1854 | 1855 | inheritedData(key: string, value: any): JQuery; 1856 | inheritedData(obj: { [key: string]: any; }): JQuery; 1857 | inheritedData(key?: string): any; 1858 | } 1859 | 1860 | /////////////////////////////////////////////////////////////////////////// 1861 | // AUTO module (angular.js) 1862 | /////////////////////////////////////////////////////////////////////////// 1863 | export module auto { 1864 | 1865 | /////////////////////////////////////////////////////////////////////// 1866 | // InjectorService 1867 | // see http://docs.angularjs.org/api/AUTO.$injector 1868 | /////////////////////////////////////////////////////////////////////// 1869 | interface IInjectorService { 1870 | annotate(fn: Function, strictDi?: boolean): string[]; 1871 | annotate(inlineAnnotatedFunction: any[]): string[]; 1872 | get(name: string, caller?: string): T; 1873 | has(name: string): boolean; 1874 | instantiate(typeConstructor: Function, locals?: any): T; 1875 | invoke(inlineAnnotatedFunction: any[]): any; 1876 | invoke(func: Function, context?: any, locals?: any): any; 1877 | strictDi: boolean; 1878 | } 1879 | 1880 | /////////////////////////////////////////////////////////////////////// 1881 | // ProvideService 1882 | // see http://docs.angularjs.org/api/AUTO.$provide 1883 | /////////////////////////////////////////////////////////////////////// 1884 | interface IProvideService { 1885 | // Documentation says it returns the registered instance, but actual 1886 | // implementation does not return anything. 1887 | // constant(name: string, value: any): any; 1888 | /** 1889 | * Register a constant service, such as a string, a number, an array, an object or a function, with the $injector. Unlike value it can be injected into a module configuration function (see config) and it cannot be overridden by an Angular decorator. 1890 | * 1891 | * @param name The name of the constant. 1892 | * @param value The constant value. 1893 | */ 1894 | constant(name: string, value: any): void; 1895 | 1896 | /** 1897 | * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. 1898 | * 1899 | * @param name The name of the service to decorate. 1900 | * @param decorator This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: 1901 | * 1902 | * $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. 1903 | */ 1904 | decorator(name: string, decorator: Function): void; 1905 | /** 1906 | * Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behaviour of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service. 1907 | * 1908 | * @param name The name of the service to decorate. 1909 | * @param inlineAnnotatedFunction This function will be invoked when the service needs to be instantiated and should return the decorated service instance. The function is called using the injector.invoke method and is therefore fully injectable. Local injection arguments: 1910 | * 1911 | * $delegate - The original service instance, which can be monkey patched, configured, decorated or delegated to. 1912 | */ 1913 | decorator(name: string, inlineAnnotatedFunction: any[]): void; 1914 | factory(name: string, serviceFactoryFunction: Function): IServiceProvider; 1915 | factory(name: string, inlineAnnotatedFunction: any[]): IServiceProvider; 1916 | provider(name: string, provider: IServiceProvider): IServiceProvider; 1917 | provider(name: string, serviceProviderConstructor: Function): IServiceProvider; 1918 | service(name: string, constructor: Function): IServiceProvider; 1919 | service(name: string, inlineAnnotatedFunction: any[]): IServiceProvider; 1920 | value(name: string, value: any): IServiceProvider; 1921 | } 1922 | 1923 | } 1924 | 1925 | /** 1926 | * $http params serializer that converts objects to strings 1927 | * see https://docs.angularjs.org/api/ng/service/$httpParamSerializer 1928 | */ 1929 | interface IHttpParamSerializer { 1930 | (obj: Object): string; 1931 | } 1932 | } 1933 | -------------------------------------------------------------------------------- /app/typings/jasmine/jasmine.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for Jasmine 2.2 2 | // Project: http://jasmine.github.io/ 3 | // Definitions by: Boris Yankov , Theodore Brown , David Pärsson 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | 7 | // For ddescribe / iit use : https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/karma-jasmine/karma-jasmine.d.ts 8 | 9 | declare function describe(description: string, specDefinitions: () => void): void; 10 | declare function fdescribe(description: string, specDefinitions: () => void): void; 11 | declare function xdescribe(description: string, specDefinitions: () => void): void; 12 | 13 | declare function it(expectation: string, assertion?: () => void, timeout?: number): void; 14 | declare function it(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; 15 | declare function fit(expectation: string, assertion?: () => void, timeout?: number): void; 16 | declare function fit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; 17 | declare function xit(expectation: string, assertion?: () => void, timeout?: number): void; 18 | declare function xit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; 19 | 20 | /** If you call the function pending anywhere in the spec body, no matter the expectations, the spec will be marked pending. */ 21 | declare function pending(reason?: string): void; 22 | 23 | declare function beforeEach(action: () => void, timeout?: number): void; 24 | declare function beforeEach(action: (done: DoneFn) => void, timeout?: number): void; 25 | declare function afterEach(action: () => void, timeout?: number): void; 26 | declare function afterEach(action: (done: DoneFn) => void, timeout?: number): void; 27 | 28 | declare function beforeAll(action: () => void, timeout?: number): void; 29 | declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; 30 | declare function afterAll(action: () => void, timeout?: number): void; 31 | declare function afterAll(action: (done: DoneFn) => void, timeout?: number): void; 32 | 33 | declare function expect(spy: Function): jasmine.Matchers; 34 | declare function expect(actual: any): jasmine.Matchers; 35 | 36 | declare function fail(e?: any): void; 37 | /** Action method that should be called when the async work is complete */ 38 | interface DoneFn extends Function { 39 | (): void; 40 | 41 | /** fails the spec and indicates that it has completed. If the message is an Error, Error.message is used */ 42 | fail: (message?: Error|string) => void; 43 | } 44 | 45 | declare function spyOn(object: any, method: string): jasmine.Spy; 46 | 47 | declare function runs(asyncMethod: Function): void; 48 | declare function waitsFor(latchMethod: () => boolean, failureMessage?: string, timeout?: number): void; 49 | declare function waits(timeout?: number): void; 50 | 51 | declare namespace jasmine { 52 | 53 | var clock: () => Clock; 54 | 55 | function any(aclass: any): Any; 56 | function anything(): Any; 57 | function arrayContaining(sample: any[]): ArrayContaining; 58 | function objectContaining(sample: any): ObjectContaining; 59 | function createSpy(name: string, originalFn?: Function): Spy; 60 | function createSpyObj(baseName: string, methodNames: any[]): any; 61 | function createSpyObj(baseName: string, methodNames: any[]): T; 62 | function pp(value: any): string; 63 | function getEnv(): Env; 64 | function addCustomEqualityTester(equalityTester: CustomEqualityTester): void; 65 | function addMatchers(matchers: CustomMatcherFactories): void; 66 | function stringMatching(str: string): Any; 67 | function stringMatching(str: RegExp): Any; 68 | 69 | interface Any { 70 | 71 | new (expectedClass: any): any; 72 | 73 | jasmineMatches(other: any): boolean; 74 | jasmineToString(): string; 75 | } 76 | 77 | // taken from TypeScript lib.core.es6.d.ts, applicable to CustomMatchers.contains() 78 | interface ArrayLike { 79 | length: number; 80 | [n: number]: T; 81 | } 82 | 83 | interface ArrayContaining { 84 | new (sample: any[]): any; 85 | 86 | asymmetricMatch(other: any): boolean; 87 | jasmineToString(): string; 88 | } 89 | 90 | interface ObjectContaining { 91 | new (sample: any): any; 92 | 93 | jasmineMatches(other: any, mismatchKeys: any[], mismatchValues: any[]): boolean; 94 | jasmineToString(): string; 95 | } 96 | 97 | interface Block { 98 | 99 | new (env: Env, func: SpecFunction, spec: Spec): any; 100 | 101 | execute(onComplete: () => void): void; 102 | } 103 | 104 | interface WaitsBlock extends Block { 105 | new (env: Env, timeout: number, spec: Spec): any; 106 | } 107 | 108 | interface WaitsForBlock extends Block { 109 | new (env: Env, timeout: number, latchFunction: SpecFunction, message: string, spec: Spec): any; 110 | } 111 | 112 | interface Clock { 113 | install(): void; 114 | uninstall(): void; 115 | /** Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds. */ 116 | tick(ms: number): void; 117 | mockDate(date?: Date): void; 118 | } 119 | 120 | interface CustomEqualityTester { 121 | (first: any, second: any): boolean; 122 | } 123 | 124 | interface CustomMatcher { 125 | compare(actual: T, expected: T): CustomMatcherResult; 126 | compare(actual: any, expected: any): CustomMatcherResult; 127 | } 128 | 129 | interface CustomMatcherFactory { 130 | (util: MatchersUtil, customEqualityTesters: Array): CustomMatcher; 131 | } 132 | 133 | interface CustomMatcherFactories { 134 | [index: string]: CustomMatcherFactory; 135 | } 136 | 137 | interface CustomMatcherResult { 138 | pass: boolean; 139 | message?: string; 140 | } 141 | 142 | interface MatchersUtil { 143 | equals(a: any, b: any, customTesters?: Array): boolean; 144 | contains(haystack: ArrayLike | string, needle: any, customTesters?: Array): boolean; 145 | buildFailureMessage(matcherName: string, isNot: boolean, actual: any, ...expected: Array): string; 146 | } 147 | 148 | interface Env { 149 | setTimeout: any; 150 | clearTimeout: void; 151 | setInterval: any; 152 | clearInterval: void; 153 | updateInterval: number; 154 | 155 | currentSpec: Spec; 156 | 157 | matchersClass: Matchers; 158 | 159 | version(): any; 160 | versionString(): string; 161 | nextSpecId(): number; 162 | addReporter(reporter: Reporter): void; 163 | execute(): void; 164 | describe(description: string, specDefinitions: () => void): Suite; 165 | // ddescribe(description: string, specDefinitions: () => void): Suite; Not a part of jasmine. Angular team adds these 166 | beforeEach(beforeEachFunction: () => void): void; 167 | beforeAll(beforeAllFunction: () => void): void; 168 | currentRunner(): Runner; 169 | afterEach(afterEachFunction: () => void): void; 170 | afterAll(afterAllFunction: () => void): void; 171 | xdescribe(desc: string, specDefinitions: () => void): XSuite; 172 | it(description: string, func: () => void): Spec; 173 | // iit(description: string, func: () => void): Spec; Not a part of jasmine. Angular team adds these 174 | xit(desc: string, func: () => void): XSpec; 175 | compareRegExps_(a: RegExp, b: RegExp, mismatchKeys: string[], mismatchValues: string[]): boolean; 176 | compareObjects_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean; 177 | equals_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean; 178 | contains_(haystack: any, needle: any): boolean; 179 | addCustomEqualityTester(equalityTester: CustomEqualityTester): void; 180 | addMatchers(matchers: CustomMatcherFactories): void; 181 | specFilter(spec: Spec): boolean; 182 | } 183 | 184 | interface FakeTimer { 185 | 186 | new (): any; 187 | 188 | reset(): void; 189 | tick(millis: number): void; 190 | runFunctionsWithinRange(oldMillis: number, nowMillis: number): void; 191 | scheduleFunction(timeoutKey: any, funcToCall: () => void, millis: number, recurring: boolean): void; 192 | } 193 | 194 | interface HtmlReporter { 195 | new (): any; 196 | } 197 | 198 | interface HtmlSpecFilter { 199 | new (): any; 200 | } 201 | 202 | interface Result { 203 | type: string; 204 | } 205 | 206 | interface NestedResults extends Result { 207 | description: string; 208 | 209 | totalCount: number; 210 | passedCount: number; 211 | failedCount: number; 212 | 213 | skipped: boolean; 214 | 215 | rollupCounts(result: NestedResults): void; 216 | log(values: any): void; 217 | getItems(): Result[]; 218 | addResult(result: Result): void; 219 | passed(): boolean; 220 | } 221 | 222 | interface MessageResult extends Result { 223 | values: any; 224 | trace: Trace; 225 | } 226 | 227 | interface ExpectationResult extends Result { 228 | matcherName: string; 229 | passed(): boolean; 230 | expected: any; 231 | actual: any; 232 | message: string; 233 | trace: Trace; 234 | } 235 | 236 | interface Trace { 237 | name: string; 238 | message: string; 239 | stack: any; 240 | } 241 | 242 | interface PrettyPrinter { 243 | 244 | new (): any; 245 | 246 | format(value: any): void; 247 | iterateObject(obj: any, fn: (property: string, isGetter: boolean) => void): void; 248 | emitScalar(value: any): void; 249 | emitString(value: string): void; 250 | emitArray(array: any[]): void; 251 | emitObject(obj: any): void; 252 | append(value: any): void; 253 | } 254 | 255 | interface StringPrettyPrinter extends PrettyPrinter { 256 | } 257 | 258 | interface Queue { 259 | 260 | new (env: any): any; 261 | 262 | env: Env; 263 | ensured: boolean[]; 264 | blocks: Block[]; 265 | running: boolean; 266 | index: number; 267 | offset: number; 268 | abort: boolean; 269 | 270 | addBefore(block: Block, ensure?: boolean): void; 271 | add(block: any, ensure?: boolean): void; 272 | insertNext(block: any, ensure?: boolean): void; 273 | start(onComplete?: () => void): void; 274 | isRunning(): boolean; 275 | next_(): void; 276 | results(): NestedResults; 277 | } 278 | 279 | interface Matchers { 280 | 281 | new (env: Env, actual: any, spec: Env, isNot?: boolean): any; 282 | 283 | env: Env; 284 | actual: any; 285 | spec: Env; 286 | isNot?: boolean; 287 | message(): any; 288 | 289 | toBe(expected: any, expectationFailOutput?: any): boolean; 290 | toEqual(expected: any, expectationFailOutput?: any): boolean; 291 | toMatch(expected: string | RegExp, expectationFailOutput?: any): boolean; 292 | toBeDefined(expectationFailOutput?: any): boolean; 293 | toBeUndefined(expectationFailOutput?: any): boolean; 294 | toBeNull(expectationFailOutput?: any): boolean; 295 | toBeNaN(): boolean; 296 | toBeTruthy(expectationFailOutput?: any): boolean; 297 | toBeFalsy(expectationFailOutput?: any): boolean; 298 | toHaveBeenCalled(): boolean; 299 | toHaveBeenCalledWith(...params: any[]): boolean; 300 | toHaveBeenCalledTimes(expected: number): boolean; 301 | toContain(expected: any, expectationFailOutput?: any): boolean; 302 | toBeLessThan(expected: number, expectationFailOutput?: any): boolean; 303 | toBeGreaterThan(expected: number, expectationFailOutput?: any): boolean; 304 | toBeCloseTo(expected: number, precision: any, expectationFailOutput?: any): boolean; 305 | toThrow(expected?: any): boolean; 306 | toThrowError(message?: string | RegExp): boolean; 307 | toThrowError(expected?: new (...args: any[]) => Error, message?: string | RegExp): boolean; 308 | not: Matchers; 309 | 310 | Any: Any; 311 | } 312 | 313 | interface Reporter { 314 | reportRunnerStarting(runner: Runner): void; 315 | reportRunnerResults(runner: Runner): void; 316 | reportSuiteResults(suite: Suite): void; 317 | reportSpecStarting(spec: Spec): void; 318 | reportSpecResults(spec: Spec): void; 319 | log(str: string): void; 320 | } 321 | 322 | interface MultiReporter extends Reporter { 323 | addReporter(reporter: Reporter): void; 324 | } 325 | 326 | interface Runner { 327 | 328 | new (env: Env): any; 329 | 330 | execute(): void; 331 | beforeEach(beforeEachFunction: SpecFunction): void; 332 | afterEach(afterEachFunction: SpecFunction): void; 333 | beforeAll(beforeAllFunction: SpecFunction): void; 334 | afterAll(afterAllFunction: SpecFunction): void; 335 | finishCallback(): void; 336 | addSuite(suite: Suite): void; 337 | add(block: Block): void; 338 | specs(): Spec[]; 339 | suites(): Suite[]; 340 | topLevelSuites(): Suite[]; 341 | results(): NestedResults; 342 | } 343 | 344 | interface SpecFunction { 345 | (spec?: Spec): void; 346 | } 347 | 348 | interface SuiteOrSpec { 349 | id: number; 350 | env: Env; 351 | description: string; 352 | queue: Queue; 353 | } 354 | 355 | interface Spec extends SuiteOrSpec { 356 | 357 | new (env: Env, suite: Suite, description: string): any; 358 | 359 | suite: Suite; 360 | 361 | afterCallbacks: SpecFunction[]; 362 | spies_: Spy[]; 363 | 364 | results_: NestedResults; 365 | matchersClass: Matchers; 366 | 367 | getFullName(): string; 368 | results(): NestedResults; 369 | log(arguments: any): any; 370 | runs(func: SpecFunction): Spec; 371 | addToQueue(block: Block): void; 372 | addMatcherResult(result: Result): void; 373 | expect(actual: any): any; 374 | waits(timeout: number): Spec; 375 | waitsFor(latchFunction: SpecFunction, timeoutMessage?: string, timeout?: number): Spec; 376 | fail(e?: any): void; 377 | getMatchersClass_(): Matchers; 378 | addMatchers(matchersPrototype: CustomMatcherFactories): void; 379 | finishCallback(): void; 380 | finish(onComplete?: () => void): void; 381 | after(doAfter: SpecFunction): void; 382 | execute(onComplete?: () => void): any; 383 | addBeforesAndAftersToQueue(): void; 384 | explodes(): void; 385 | spyOn(obj: any, methodName: string, ignoreMethodDoesntExist: boolean): Spy; 386 | removeAllSpies(): void; 387 | } 388 | 389 | interface XSpec { 390 | id: number; 391 | runs(): void; 392 | } 393 | 394 | interface Suite extends SuiteOrSpec { 395 | 396 | new (env: Env, description: string, specDefinitions: () => void, parentSuite: Suite): any; 397 | 398 | parentSuite: Suite; 399 | 400 | getFullName(): string; 401 | finish(onComplete?: () => void): void; 402 | beforeEach(beforeEachFunction: SpecFunction): void; 403 | afterEach(afterEachFunction: SpecFunction): void; 404 | beforeAll(beforeAllFunction: SpecFunction): void; 405 | afterAll(afterAllFunction: SpecFunction): void; 406 | results(): NestedResults; 407 | add(suiteOrSpec: SuiteOrSpec): void; 408 | specs(): Spec[]; 409 | suites(): Suite[]; 410 | children(): any[]; 411 | execute(onComplete?: () => void): void; 412 | } 413 | 414 | interface XSuite { 415 | execute(): void; 416 | } 417 | 418 | interface Spy { 419 | (...params: any[]): any; 420 | 421 | identity: string; 422 | and: SpyAnd; 423 | calls: Calls; 424 | mostRecentCall: { args: any[]; }; 425 | argsForCall: any[]; 426 | wasCalled: boolean; 427 | } 428 | 429 | interface SpyAnd { 430 | /** By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation. */ 431 | callThrough(): Spy; 432 | /** By chaining the spy with and.returnValue, all calls to the function will return a specific value. */ 433 | returnValue(val: any): Spy; 434 | /** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function. */ 435 | callFake(fn: Function): Spy; 436 | /** By chaining the spy with and.throwError, all calls to the spy will throw the specified value. */ 437 | throwError(msg: string): Spy; 438 | /** When a calling strategy is used for a spy, the original stubbing behavior can be returned at any time with and.stub. */ 439 | stub(): Spy; 440 | } 441 | 442 | interface Calls { 443 | /** By chaining the spy with calls.any(), will return false if the spy has not been called at all, and then true once at least one call happens. **/ 444 | any(): boolean; 445 | /** By chaining the spy with calls.count(), will return the number of times the spy was called **/ 446 | count(): number; 447 | /** By chaining the spy with calls.argsFor(), will return the arguments passed to call number index **/ 448 | argsFor(index: number): any[]; 449 | /** By chaining the spy with calls.allArgs(), will return the arguments to all calls **/ 450 | allArgs(): any[]; 451 | /** By chaining the spy with calls.all(), will return the context (the this) and arguments passed all calls **/ 452 | all(): CallInfo[]; 453 | /** By chaining the spy with calls.mostRecent(), will return the context (the this) and arguments for the most recent call **/ 454 | mostRecent(): CallInfo; 455 | /** By chaining the spy with calls.first(), will return the context (the this) and arguments for the first call **/ 456 | first(): CallInfo; 457 | /** By chaining the spy with calls.reset(), will clears all tracking for a spy **/ 458 | reset(): void; 459 | } 460 | 461 | interface CallInfo { 462 | /** The context (the this) for the call */ 463 | object: any; 464 | /** All arguments passed to the call */ 465 | args: any[]; 466 | /** The return value of the call */ 467 | returnValue: any; 468 | } 469 | 470 | interface Util { 471 | inherit(childClass: Function, parentClass: Function): any; 472 | formatException(e: any): any; 473 | htmlEscape(str: string): string; 474 | argsToArray(args: any): any; 475 | extend(destination: any, source: any): any; 476 | } 477 | 478 | interface JsApiReporter extends Reporter { 479 | 480 | started: boolean; 481 | finished: boolean; 482 | result: any; 483 | messages: any; 484 | 485 | new (): any; 486 | 487 | suites(): Suite[]; 488 | summarize_(suiteOrSpec: SuiteOrSpec): any; 489 | results(): any; 490 | resultsForSpec(specId: any): any; 491 | log(str: any): any; 492 | resultsForSpecs(specIds: any): any; 493 | summarizeResult_(result: any): any; 494 | } 495 | 496 | interface Jasmine { 497 | Spec: Spec; 498 | clock: Clock; 499 | util: Util; 500 | } 501 | 502 | export var HtmlReporter: HtmlReporter; 503 | export var HtmlSpecFilter: HtmlSpecFilter; 504 | export var DEFAULT_TIMEOUT_INTERVAL: number; 505 | } 506 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "turnerjs", 3 | "version": "1.0.276", 4 | "main": "dist/test/lib/turner-driver.js", 5 | "ignore": [ 6 | ".*", 7 | "Gemfile*", 8 | "Gruntfile.js", 9 | "pom.xml", 10 | "/*.json", 11 | "*.conf.js", 12 | "*-conf.js", 13 | "app/*", 14 | "!app/styles", 15 | "test/*", 16 | "!test/lib", 17 | "dist/bower_components", 18 | "dist/concat", 19 | "dist/_debug*", 20 | "maven", 21 | "*.sublime*" 22 | ], 23 | "dependencies": { 24 | "angular": "~1.5.0" 25 | }, 26 | "devDependencies": { 27 | "angular-mocks": "~1.5.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // http://karma-runner.github.io/0.10/config/configuration-file.html 3 | 'use strict'; 4 | 5 | module.exports = function (config) { 6 | config.set({ 7 | plugins: ['karma-jasmine', 'karma-coverage', 'karma-phantomjs-launcher', 'karma-ng-html2js-preprocessor'], 8 | 9 | preprocessors: { 10 | '{.tmp,app}/scripts/{,!(lib)/**/}*.js': 'coverage', 11 | '{app,.tmp}/views/**/*.html': 'ng-html2js' 12 | }, 13 | 14 | ngHtml2JsPreprocessor: { 15 | stripPrefix: '(app|.tmp)/', 16 | moduleName: 'componentTestKitAppInternal' 17 | }, 18 | 19 | // base path, that will be used to resolve files and exclude 20 | basePath: '', 21 | 22 | // testing framework to use (jasmine/mocha/qunit/...) 23 | frameworks: ['jasmine'], 24 | 25 | // list of files / patterns to load in the browser 26 | files: [ 27 | 'app/bower_components/angular/angular.js', 28 | 'app/bower_components/angular-mocks/angular-mocks.js', 29 | '{app,.tmp}/*.js', 30 | '{app,.tmp}/scripts/*.js', 31 | '{app,.tmp}/scripts/*/**/*.js', 32 | '{app,.tmp}/test/**/*.js', 33 | '{app,.tmp}/views/**/*.html' 34 | ], 35 | 36 | // list of files / patterns to exclude 37 | exclude: [ 38 | '{app,.tmp}/test/e2e/**/*.js', 39 | '{app,.tmp}/scripts/locale/*_!(en).js' 40 | ], 41 | 42 | // test results reporter to use 43 | // possible values: dots || progress || growl 44 | reporters: ['progress', 'coverage'], 45 | 46 | // web server port 47 | port: 8880, 48 | 49 | // level of logging 50 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 51 | logLevel: config.LOG_INFO, 52 | 53 | // enable / disable watching file and executing tests whenever any file changes 54 | autoWatch: false, 55 | 56 | // Start these browsers, currently available: 57 | // - Chrome 58 | // - ChromeCanary 59 | // - Firefox 60 | // - Opera 61 | // - Safari (only Mac) 62 | // - PhantomJS 63 | // - IE (only Windows) 64 | browsers: ['PhantomJS'], 65 | 66 | // Continuous Integration mode 67 | // if true, it capture browsers, run tests and exit 68 | singleRun: true 69 | }); 70 | }; 71 | -------------------------------------------------------------------------------- /module/generated/turnerjs-driver.d.ts: -------------------------------------------------------------------------------- 1 | declare const enum TurnerChildDriverType { 2 | CHILD_REGULAR = 0, 3 | CHILD_ARRAY = 1, 4 | } 5 | interface TurnerChildDriver { 6 | selector?: string; 7 | selectorIndex?: number; 8 | type: TurnerChildDriverType; 9 | factory?: (item?, index?) => T; 10 | drivers?: Array; 11 | fullDriversArr?: Array; 12 | } 13 | declare class TurnerComponentDriver { 14 | $rootScope: ng.IRootScopeService; 15 | $compile: ng.ICompileService; 16 | body: ng.IAugmentedJQuery; 17 | appendedToBody: boolean; 18 | private _element; 19 | private _scope; 20 | private parent; 21 | private templateRoot; 22 | private childDrivers; 23 | constructor(); 24 | static byDataHook(dataHook: any): string; 25 | readonly element: ng.IAugmentedJQuery; 26 | readonly scope: ng.IScope; 27 | readonly isRendered: boolean; 28 | connectToBody(): void; 29 | disconnectFromBody(): void; 30 | applyChanges(): void; 31 | protected findByDataHook(dataHook: string): ng.IAugmentedJQuery; 32 | protected findAllByDataHook(dataHook: string): ng.IAugmentedJQuery; 33 | protected renderFromTemplate(template: string, args?: Object, selector?: any, appendToBody?: boolean): void; 34 | protected initChildDrivers(): void; 35 | protected defineChild(childDriver: T, selector?: string): T; 36 | protected defineChildren(factory: (item?, index?) => T, selector: string): Array; 37 | private appendTemplateToBody(); 38 | private defineIndexedChild(childDriver, selector?, selectorIndex?); 39 | private initializeDriver(containingElement, selector?, selectorIndex?); 40 | private initArrayChild(child); 41 | private initRegularChild(child); 42 | verifyRendered(): void; 43 | } 44 | declare function byDataHook(dataHook: string): string; 45 | -------------------------------------------------------------------------------- /module/generated/turnerjs-driver.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var TurnerComponentDriver = (function () { 3 | function TurnerComponentDriver() { 4 | this.childDrivers = []; 5 | this.body = angular.element(document.body); 6 | } 7 | TurnerComponentDriver.byDataHook = function (dataHook) { 8 | return "[data-hook='" + dataHook + "']"; 9 | }; 10 | Object.defineProperty(TurnerComponentDriver.prototype, "element", { 11 | get: function () { 12 | this.verifyRendered(); 13 | return this._element; 14 | }, 15 | enumerable: true, 16 | configurable: true 17 | }); 18 | Object.defineProperty(TurnerComponentDriver.prototype, "scope", { 19 | get: function () { 20 | this.verifyRendered(); 21 | return this._scope; 22 | }, 23 | enumerable: true, 24 | configurable: true 25 | }); 26 | Object.defineProperty(TurnerComponentDriver.prototype, "isRendered", { 27 | get: function () { 28 | return !!this._scope; 29 | }, 30 | enumerable: true, 31 | configurable: true 32 | }); 33 | TurnerComponentDriver.prototype.connectToBody = function () { 34 | this.verifyRendered(); 35 | this.appendTemplateToBody(); 36 | }; 37 | TurnerComponentDriver.prototype.disconnectFromBody = function () { 38 | if (this.templateRoot) { 39 | this.templateRoot.remove(); 40 | } 41 | if (this.appendedToBody) { 42 | this._element.remove(); 43 | } 44 | }; 45 | TurnerComponentDriver.prototype.applyChanges = function () { 46 | this.$rootScope.$digest(); 47 | }; 48 | TurnerComponentDriver.prototype.findByDataHook = function (dataHook) { 49 | return angular.element(this.element[0].querySelector(TurnerComponentDriver.byDataHook(dataHook))); 50 | }; 51 | TurnerComponentDriver.prototype.findAllByDataHook = function (dataHook) { 52 | return angular.element(this.element[0].querySelectorAll(TurnerComponentDriver.byDataHook(dataHook))); 53 | }; 54 | TurnerComponentDriver.prototype.renderFromTemplate = function (template, args, selector, appendToBody) { 55 | var _this = this; 56 | if (args === void 0) { args = {}; } 57 | if (appendToBody === void 0) { appendToBody = false; } 58 | angular.mock.inject(function ($rootScope, $compile) { 59 | _this.$rootScope = $rootScope; 60 | _this.$compile = $compile; 61 | }); 62 | var scope = this.$rootScope.$new(); 63 | scope = angular.extend(scope, args); 64 | this.templateRoot = angular.element(template); 65 | this.$compile(this.templateRoot)(scope); 66 | if (appendToBody) { 67 | this.appendTemplateToBody(); 68 | } 69 | this.$rootScope.$digest(); 70 | this.initializeDriver(this.templateRoot, selector); 71 | this.$rootScope.$watch(function () { return _this.initChildDrivers(); }); 72 | }; 73 | TurnerComponentDriver.prototype.initChildDrivers = function () { 74 | var _this = this; 75 | this.childDrivers.forEach(function (child) { 76 | if (child.type === 0 /* CHILD_REGULAR */) { 77 | _this.initRegularChild(child); 78 | } 79 | else if (child.type === 1 /* CHILD_ARRAY */) { 80 | _this.initArrayChild(child); 81 | } 82 | }); 83 | }; 84 | TurnerComponentDriver.prototype.defineChild = function (childDriver, selector) { 85 | return this.defineIndexedChild(childDriver, selector, 0); 86 | }; 87 | TurnerComponentDriver.prototype.defineChildren = function (factory, selector) { 88 | var children = []; 89 | this.childDrivers.push({ 90 | type: 1 /* CHILD_ARRAY */, 91 | selector: selector, 92 | factory: factory, 93 | drivers: children, 94 | fullDriversArr: [] 95 | }); 96 | return children; 97 | }; 98 | TurnerComponentDriver.prototype.appendTemplateToBody = function () { 99 | this.body.append(this.templateRoot); 100 | }; 101 | TurnerComponentDriver.prototype.defineIndexedChild = function (childDriver, selector, selectorIndex) { 102 | if (selectorIndex === void 0) { selectorIndex = 0; } 103 | this.childDrivers.push({ 104 | selector: selector, 105 | selectorIndex: selectorIndex, 106 | type: 0 /* CHILD_REGULAR */, 107 | drivers: [childDriver] 108 | }); 109 | childDriver.parent = this; 110 | return childDriver; 111 | }; 112 | TurnerComponentDriver.prototype.initializeDriver = function (containingElement, selector, selectorIndex) { 113 | if (selectorIndex === void 0) { selectorIndex = 0; } 114 | var searchElement = this.appendedToBody ? this.body : containingElement; 115 | this._element = selector ? angular.element(searchElement[0].querySelectorAll(selector)[selectorIndex]) : containingElement; 116 | this._scope = this._element.isolateScope() || this._element.scope(); 117 | if (this.isRendered) { 118 | this.initChildDrivers(); 119 | } 120 | }; 121 | TurnerComponentDriver.prototype.initArrayChild = function (child) { 122 | var _this = this; 123 | child.drivers.splice(0, child.drivers.length); 124 | [].forEach.call(this._element[0].querySelectorAll(child.selector), function (item, index) { 125 | if (child.fullDriversArr.length <= index) { 126 | child.fullDriversArr.push(_this.defineIndexedChild(child.factory(item, index), child.selector, index)); 127 | } 128 | child.drivers.push(child.fullDriversArr[index]); 129 | }); 130 | }; 131 | TurnerComponentDriver.prototype.initRegularChild = function (child) { 132 | var childDriver = child.drivers[0]; 133 | childDriver.initializeDriver(this._element, child.selector, child.selectorIndex); 134 | childDriver.$compile = this.$compile; 135 | childDriver.$rootScope = this.$rootScope; 136 | }; 137 | TurnerComponentDriver.prototype.verifyRendered = function () { 138 | if (this.parent) { 139 | this.parent.verifyRendered(); 140 | } 141 | else { 142 | this.initChildDrivers(); 143 | } 144 | if (!this.isRendered) { 145 | throw 'cannot interact with driver before element is rendered'; 146 | } 147 | }; 148 | return TurnerComponentDriver; 149 | }()); 150 | if (window) { 151 | window['byDataHook'] = window['byDataHook'] || TurnerComponentDriver.byDataHook; 152 | } 153 | if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') { 154 | module.exports = { 155 | TurnerComponentDriver: TurnerComponentDriver, 156 | byDataHook: TurnerComponentDriver.byDataHook 157 | }; 158 | } 159 | //# sourceMappingURL=turnerjs-driver.js.map -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "turnerjs", 3 | "version": "1.0.248", 4 | "scripts": { 5 | "release": "node_modules/wix-gruntfile/scripts/release.sh", 6 | "test": "grunt build", 7 | "start": "grunt serve", 8 | "build": ":", 9 | "postinstall": "node_modules/wix-gruntfile/scripts/postinstall.sh || true" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/wix/turnerjs.git" 14 | }, 15 | "publishConfig": { 16 | "registry": "https://registry.npmjs.org/" 17 | }, 18 | "main": "module/generated/turnerjs-driver.js", 19 | "files": [ 20 | "index.js", 21 | "index.d.ts", 22 | "module/index.d.ts", 23 | "module/generated/turnerjs-driver.js", 24 | "module/generated/turnerjs-driver.d.ts" 25 | ], 26 | "dependencies": {}, 27 | "devDependencies": { 28 | "@types/es6-shim": "^0.31.39", 29 | "wix-gruntfile": "^0.1.231", 30 | "wix-statics-parent": "*" 31 | }, 32 | "engines": { 33 | "node": ">=0.8.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.wixpress.cx 5 | turnerjs 6 | pom 7 | turnerjs 8 | 1.0.0-SNAPSHOT 9 | Component test kit 10 | 11 | 12 | Carmel Cohen 13 | carmelc@wix.com 14 | 15 | owner 16 | 17 | 18 | 19 | 20 | com.wixpress.common 21 | wix-master-parent 22 | 100.0.0-SNAPSHOT 23 | 24 | 25 | 26 | 27 | org.apache.maven.plugins 28 | maven-assembly-plugin 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tsd.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "v4", 3 | "repo": "borisyankov/DefinitelyTyped", 4 | "ref": "master", 5 | "path": "app/typings", 6 | "installed": { 7 | "jquery/jquery.d.ts": { 8 | "commit": "b2d17b5dad042e293e77d09f2a30d281325cb606" 9 | }, 10 | "jasmine/jasmine.d.ts": { 11 | "commit": "419793fb796b0e5c1ed11e018ad28475de0c3735" 12 | }, 13 | "es6-shim/es6-shim.d.ts": { 14 | "commit": "b2d17b5dad042e293e77d09f2a30d281325cb606" 15 | }, 16 | "angularjs/angular.d.ts": { 17 | "commit": "b2d17b5dad042e293e77d09f2a30d281325cb606" 18 | }, 19 | "angularjs/angular-mocks.d.ts": { 20 | "commit": "b2d17b5dad042e293e77d09f2a30d281325cb606" 21 | }, 22 | "node/node.d.ts": { 23 | "commit": "f5ab2df94e1aabf0fc6d783ad01c4c4671760627" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "class-name": true, 4 | "curly": true, 5 | "eofline": true, 6 | "forin": true, 7 | "indent": [ 8 | true, 9 | "spaces" 10 | ], 11 | "label-position": true, 12 | "label-undefined": true, 13 | "no-arg": true, 14 | "no-bitwise": true, 15 | "no-console": [ 16 | true, 17 | "debug", 18 | "info", 19 | "time", 20 | "timeEnd", 21 | "trace" 22 | ], 23 | "no-consecutive-blank-lines": true, 24 | "no-construct": true, 25 | "no-debugger": true, 26 | "no-duplicate-key": true, 27 | "no-duplicate-variable": true, 28 | "no-empty": true, 29 | "no-eval": true, 30 | "no-trailing-whitespace": true, 31 | "no-unused-expression": true, 32 | "no-unused-variable": true, 33 | "no-unreachable": true, 34 | "no-use-before-declare": true, 35 | "one-line": [ 36 | true, 37 | "check-open-brace", 38 | "check-catch", 39 | "check-else", 40 | "check-whitespace" 41 | ], 42 | "quotemark": [ 43 | true, 44 | "single" 45 | ], 46 | "radix": true, 47 | "semicolon": true, 48 | "triple-equals": [ 49 | true, 50 | "allow-null-check" 51 | ], 52 | "variable-name": false, 53 | "whitespace": [ 54 | true, 55 | "check-branch", 56 | "check-decl", 57 | "check-operator", 58 | "check-separator", 59 | "check-type" 60 | ], 61 | "trailing-comma": [ 62 | true, 63 | { 64 | "singleline": "never", 65 | "multiline": "never" 66 | } 67 | ] 68 | } 69 | } --------------------------------------------------------------------------------