├── .editorconfig
├── .gitattributes
├── .github
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .npmignore
├── .travis.yml
├── CONTRIBUTING.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── codecov.yml
├── deploy_key.enc
├── docs
└── api.json
├── intern.json
├── package-lock.json
├── package.json
├── src
├── interfaces.d.ts
└── loader.ts
├── tests
├── common
│ ├── a
│ │ ├── app.js
│ │ ├── map2.js
│ │ ├── relative1.js
│ │ └── remappedApp.js
│ ├── amd
│ │ └── onlyFactory.js
│ ├── app.js
│ ├── commonJs
│ │ ├── Deep2.js
│ │ ├── app.js
│ │ ├── app1.js
│ │ ├── circular1.js
│ │ ├── circular2.js
│ │ ├── deep1.js
│ │ ├── deep3.js
│ │ ├── deep4.js
│ │ ├── testModule1.js
│ │ ├── testModule2.js
│ │ └── testModule3.js
│ ├── map1.js
│ ├── plugin.js
│ ├── pluginConfig.js
│ ├── recursive
│ │ ├── a.js
│ │ ├── b.js
│ │ ├── c.js
│ │ ├── d.js
│ │ └── e.js
│ └── usesApp.js
├── functional
│ ├── all.ts
│ ├── amdApp
│ │ ├── Deep2.ts
│ │ ├── app.ts
│ │ ├── app1.js
│ │ ├── circular1.ts
│ │ ├── circular2.ts
│ │ ├── crossOrigin.js
│ │ ├── deep1.ts
│ │ ├── deep3.ts
│ │ ├── deep4.ts
│ │ ├── module1.js
│ │ ├── module2.js
│ │ ├── module3.js
│ │ └── module4.js
│ ├── amdFactoryOnly.html
│ ├── amdModuleCircular.html
│ ├── amdModuleCircular2.html
│ ├── amdModuleCircular3.html
│ ├── amdModuleDeepDeps.html
│ ├── amdModuleWithId1.html
│ ├── amdModuleWithId1a.html
│ ├── amdModuleWithId2.html
│ ├── amdModuleWithId2a.html
│ ├── amdModuleWithId3.html
│ ├── amdModuleWithId3a.html
│ ├── amdModuleWithId4.html
│ ├── amdModuleWithId4a.html
│ ├── amdModuleWithId5.html
│ ├── amdModuleWithId6.html
│ ├── amdModuleWithId6a.html
│ ├── basicAmdLoading.html
│ ├── basicAmdLoading.ts
│ ├── basicCommonJsLoading.html
│ ├── basicCommonJsLoading.ts
│ ├── commonJsModuleCircular.html
│ ├── commonJsModuleCircular2.html
│ ├── commonJsModuleCircular3.html
│ ├── commonJsModuleDeepDeps.html
│ ├── commonJsModuleWithId1.html
│ ├── commonJsModuleWithId2.html
│ ├── commonJsModuleWithId3.html
│ ├── commonJsModuleWithId4.html
│ ├── crossOrigin.ts
│ ├── crossOriginAnon.html
│ ├── crossOriginCreds.html
│ ├── crossOriginFalse.html
│ ├── csp-cdn.html
│ ├── csp-cdn.ts
│ ├── csp-simple.html
│ ├── csp-simple.ts
│ ├── csp-success.html
│ ├── csp.ts
│ ├── executeTest.ts
│ ├── map.html
│ ├── require
│ │ ├── config
│ │ │ ├── baseUrl.html
│ │ │ ├── defaultConfig.html
│ │ │ ├── map-hierarchy.html
│ │ │ ├── map-merge.html
│ │ │ ├── map-nested.html
│ │ │ ├── map-plugin.html
│ │ │ ├── map-relative.html
│ │ │ ├── map-simple.html
│ │ │ ├── map-star.html
│ │ │ ├── packages1.html
│ │ │ ├── packages2.html
│ │ │ ├── packages3.html
│ │ │ ├── packages4.html
│ │ │ ├── paths1.html
│ │ │ └── pkg
│ │ │ │ └── main.js
│ │ ├── has.html
│ │ ├── on
│ │ │ ├── error.html
│ │ │ └── remove.html
│ │ ├── plugin-config.html
│ │ ├── plugin-load.html
│ │ ├── require.ts
│ │ ├── toAbsMid.html
│ │ ├── toUrl.html
│ │ └── undef.html
│ ├── scriptConfigReading.html
│ ├── scriptConfigReading.ts
│ ├── shimAmdLoading.html
│ ├── shimAmdLoading.ts
│ ├── shimAmdLoading2.html
│ ├── webworkerAmd.ts
│ ├── webworkerBasic.html
│ └── worker.ts
├── interfaces.d.ts
├── module.d.ts
├── run.html
├── support
│ └── util.ts
├── tsconfig.json
└── unit
│ ├── all-node.ts
│ ├── all.ts
│ ├── bad-module.js
│ ├── basicCommonJsLoading.ts
│ ├── require.ts
│ └── simpleTest.js
├── tsconfig.json
└── tslint.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = tab
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [{package.json,.travis.yml}]
16 | indent_style = space
17 | indent_size = 2
18 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set the default behavior, in case users don't have core.autocrlf set
2 | * text=auto
3 |
4 | # Files that should always be normalized and converted to native line
5 | # endings on checkout.
6 | *.js text
7 | *.json text
8 | *.ts text
9 | *.md text
10 | *.yml text
11 | LICENSE text
12 |
13 | # Files that are truly binary and should not be modified
14 | *.png binary
15 | *.jpg binary
16 | *.jpeg binary
17 | *.gif binary
18 | *.jar binary
19 | *.zip binary
20 | *.psd binary
21 | *.enc binary
22 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Thank You
2 |
3 | We very much welcome contributions to Dojo 2.
4 |
5 | Because we have so many repositories that are part of Dojo 2, we have located our [Contributing Guidelines](https://github.com/dojo/meta/blob/master/CONTRIBUTING.md) in our [Dojo 2 Meta Repository](https://github.com/dojo/meta#readme).
6 |
7 | Look forward to working with you on Dojo 2!!!
8 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
11 |
12 | **Bug / Enhancement**
13 |
14 |
15 |
16 | Package Version:
17 |
18 | **Code**
19 |
20 |
21 |
22 | **Expected behavior:**
23 |
24 |
25 |
26 | **Actual behavior:**
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Type:** bug / feature
2 |
3 | The following has been addressed in the PR:
4 |
5 | * [ ] There is a related issue
6 | * [ ] All code has been formatted with [`prettier`](https://prettier.io/) as per the [readme code style guidelines](./../#code-style)
7 | * [ ] Unit or Functional tests are included in the PR
8 |
9 |
17 |
18 | **Description:**
19 |
20 | Resolves #???
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .sublimets
2 | .tscache
3 | *.js
4 | *.js.map
5 | !/*.js
6 | !tests/**/*.js
7 | !tasks/**/*.js
8 | /typings
9 | dist
10 | _build
11 | node_modules
12 | bower_components
13 | tests/typings/dist/
14 | .baseDir.ts
15 | /html-report
16 | coverage-final.lcov
17 | /_apidoc
18 | deploy_key
19 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /_build
2 | /support
3 | /tests
4 | /typings
5 | .editorconfig
6 | .gitattributes
7 | .gitignore
8 | .npmignore
9 | .travis.yml
10 | Gruntfile.js
11 | coverage-final.lcov
12 | coverage-unmapped.json
13 | tsconfig.json
14 | tslint.json
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | node_js:
4 | - '6'
5 | env:
6 | global:
7 | - SAUCE_USERNAME: dojo2-ts-ci
8 | - SAUCE_ACCESS_KEY: e92610e3-834e-4bec-a3b5-6f7b9d874601
9 | - BROWSERSTACK_USERNAME: dylanschiemann2
10 | - BROWSERSTACK_ACCESS_KEY: 4Q2g8YAc9qeZzB2hECnS
11 | before_install:
12 | - if [ ${TRAVIS_BRANCH-""} == "master" ] && [ -n ${encrypted_12c8071d2874_key-""}
13 | ]; then openssl aes-256-cbc -K $encrypted_12c8071d2874_key -iv $encrypted_12c8071d2874_iv
14 | -in deploy_key.enc -out deploy_key -d; fi
15 | install:
16 | - travis_retry npm install grunt-cli
17 | - travis_retry npm install
18 | script:
19 | - grunt
20 | - grunt intern:browserstack --test-reporter
21 | - grunt uploadCoverage
22 | - grunt dist
23 | - grunt doc
24 | notifications:
25 | slack:
26 | secure: QL+qrf9Y8h/v7WLu9rVRd6pU5CQSIKjaBeknyGtpCBpKW8suWQroSk0NmIRmH3//IHHd1VXIOsHC3wQVceAmktij1q9qaDqD1269G4+BRLJ9D7IaRlaayVIhZxd7FKEkPH9iSADg2vtN7i5NDoORqwp6BKMCMUMusPu1ME+gc4r98EjmKJ7u7Nh2sr0+jqWGttBGJ30yah7Uq+i6Cy9gUnKm4O5tP+emp0pRfZNpT8Ekyrjc0ZnKOrmgxvywVlEZaPnMoOWOWcxj/ZQSgP+0NeQ6pkSnLPA6X+tA9OinI3WiWvQTUTOfYEiLp7oOol6yuEghKR4dL5xSemy4cOMCHys1Ar754AYH9e7UReSTdFRm5/FRpH5TRDVqqbQ8BvZPBwP/qXRD1kxRf8QFrLOI+evSaFQSBoXpcquE0/ZDwC3GEn4vi0gOmxpXakUspoORGVTWCABIa639jm47wInClK5QNPtg++JytXIeQUufiFCqLy/IWKE/HiGkotYLf7jI61XabSY6yXC6lQ06UyZyD6WHp+v1Yw85oaovaYxPhHOFwmXUYGIIxwaK9NSBG6P7wuJJKHl6dnmXFrIsJYZVZZBMJuT8iapC9ogohnX4WPRnf8bTuaPFAM4++t/jZvHS4MhVBoMaaAc38J/GDicY9JrMn5xW8r1HEQDMIZKaOVE=
27 | on_success: change
28 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | The [Contributing Guidelines](https://github.com/dojo/meta/blob/master/CONTRIBUTING.md)
2 | for all Dojo 2 packages can be found in the [Dojo 2 Meta Repository](https://github.com/dojo/meta#readme).
3 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /* jshint node:true */
2 |
3 | module.exports = function (grunt) {
4 | grunt.loadNpmTasks('grunt-contrib-uglify');
5 | grunt.loadNpmTasks('dts-generator');
6 |
7 | require('grunt-dojo2').initConfig(grunt, {
8 | dtsGenerator: {
9 | options: {
10 | baseDir: 'src',
11 | name: 'dojo-loader'
12 | },
13 | dist: {
14 | options: {
15 | out: 'dist/umd/dojo-loader.d.ts'
16 | },
17 | src: [ '<%= skipTests %>' ]
18 | }
19 | },
20 |
21 | /* loader has to build in a slightly different way than the standard Dojo 2 package */
22 | ts: {
23 | tests: {
24 | compilerOptions: {
25 | module: 'umd'
26 | },
27 | include: [ 'tests/**/*.ts', 'typings/index.d.ts', 'src/interfaces.d.ts' ]
28 | },
29 | dist: {
30 | compilerOptions: {
31 | declaration: false,
32 | rootDir: 'src'
33 | }
34 | }
35 | },
36 |
37 | typedoc: {
38 | options: {
39 | ignoreCompilerErrors: true // Remove this once compile errors are resolved
40 | }
41 | },
42 |
43 | /* loader has minification built into the package, eventually this should be moved to grunt-dojo2 */
44 | uglify: {
45 | dist: {
46 | options: {
47 | banner: '/*! <%= name %>@<%= version %> - Copyright (c) 2016, The Dojo Foundation. ' +
48 | 'All rights reserved. */',
49 | sourceMap: true,
50 | sourceMapName: 'dist/umd/loader.min.js.map',
51 | sourceMapIncludeSources: true,
52 | sourceMapIn: 'dist/umd/loader.js.map',
53 | compress: {
54 | dead_code: true,
55 | unsafe: true
56 | }
57 | },
58 | files: {
59 | 'dist/umd/loader.min.js': 'dist/umd/loader.js'
60 | }
61 | }
62 | },
63 |
64 | intern: {
65 | version: 4
66 | }
67 | });
68 |
69 | /* we have to write the dev task from the default because of the need to copy compile the tests differently */
70 | grunt.registerTask('dev', [
71 | 'typings:dev',
72 | 'tslint',
73 | 'clean:dev',
74 | 'dojo-ts:dev',
75 | 'dojo-ts:tests',
76 | 'copy:staticTestFiles'
77 | ]);
78 |
79 | /* we also have to add the uglify task */
80 | grunt.registerTask('dist', grunt.config.get('distTasks').concat(['uglify:dist', 'dtsGenerator:dist']));
81 | };
82 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The "New" BSD License
2 | *********************
3 |
4 | Copyright (c) 2015-2017, [JS Foundation](https://js.foundation/)
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | * Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 | * Neither the name of the JS Foundation nor the names of its contributors
16 | may be used to endorse or promote products derived from this software
17 | without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # @dojo/loader
2 |
3 |
4 | [](https://travis-ci.org/dojo/loader)
5 | [](http://codecov.io/github/dojo/loader?branch=master)
6 | [](https://badge.fury.io/js/%40dojo%2Floader)
7 |
8 | This package provides a JavaScript AMD loader useful in applications running in either a web browser, node.js or nashorn.
9 |
10 | `@dojo/loader` does not have any dependencies on a JavaScript framework.
11 |
12 | - [Usage](#usage)
13 | - [Support](#support)
14 | - [Features](#features)
15 | - [How do I contribute?](#how-do-i-contribute)
16 | - [Code Style](#code-style)
17 | - [Installation](#installation)
18 | - [Testing](#testing)
19 | - [Licensing information](#licensing-information)
20 |
21 | ## Note
22 |
23 |
24 | We strongly recommend using the `@dojo/cli` build tools for a Dojo 2 application over a runtime loader such as `@dojo/loader`.
25 |
26 | ## Usage
27 |
28 | To use `@dojo/loader`, install the package:
29 |
30 | ```bash
31 | npm install @dojo/loader
32 | ```
33 |
34 | ## Support
35 |
36 | | Environment | Version |
37 | |---------------|----------:|
38 | | IE | 10+ |
39 | | Firefox | 30+ |
40 | | Chrome | 30+ |
41 | | Opera | 15+ |
42 | | Safari | 8, 9 |
43 | | Android | 4.4+ |
44 | | iOS | 7+ |
45 | | Node | 0.12+ |
46 | | Nashorn | 1.8+ |
47 |
48 | ## Features
49 |
50 | - AMD loading
51 | - CJS loading (in a node environment)
52 | - Plugins:
53 | - [text](https://github.com/dojo/core/blob/master/src/text.ts)
54 | - [has](https://github.com/dojo/core/blob/master/src/has.ts)
55 | - Loading in a Nashorn environment
56 |
57 | Use a script tag to import the loader. This will make `require` and `define` available in the global namespace.
58 |
59 | ``` html
60 |
61 | ```
62 |
63 | The loader can load both AMD and CJS formatted modules.
64 |
65 | There is no need to use the Dojo 1.x method of requiring node modules via `dojo/node!` plugin anymore.
66 |
67 | ## How do I contribute?
68 |
69 | We appreciate your interest! Please see the [Guidelines Repository](https://github.com/dojo/guidelines#readme) for the
70 | Contributing Guidelines.
71 |
72 | ### Code Style
73 |
74 | This repository uses [`prettier`](https://prettier.io/) for code styling rules and formatting. A pre-commit hook is installed automatically and configured to run `prettier` against all staged files as per the configuration in the project's `package.json`.
75 |
76 | An additional npm script to run `prettier` (with write set to `true`) against all `src` and `test` project files is available by running:
77 |
78 | ```bash
79 | npm run prettier
80 | ```
81 |
82 | ### Installation
83 |
84 | To start working with this package, clone the repository and run `npm install`.
85 |
86 | In order to build the project run `grunt dev` or `grunt dist`.
87 |
88 | ### Testing
89 |
90 | Test cases MUST be written using Intern using the Object test interface and Assert assertion interface.
91 |
92 | 90% branch coverage MUST be provided for all code submitted to this repository, as reported by istanbul’s combined coverage results for all supported platforms.
93 |
94 | ## Licensing information
95 |
96 | © 2004–2018 [JS Foundation](https://js.foundation/) & contributors. [New BSD](http://opensource.org/licenses/BSD-3-Clause) license.
97 |
98 |
103 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | fixes:
2 | - "_build/::"
3 | coverage:
4 | notify:
5 | slack:
6 | default:
7 | url: "secret:s0/VflRMgHsftySwh6fwCN0LmIG3OtUt+21uJBS6E8qd7QIzRLvNdOwYipBwWb5ME1uFxNDrEqh5Giu0qlTAWALYP3N8HyTUU6te1eEchIJuMkmk174Uq0FH7c99sBbUQPt2xVWUcdTNAYCc4BJmXaYqCg7DSK5XCKBgLi9XP4c="
8 | threshold: 2
9 | attachments: "sunburst, diff"
10 |
--------------------------------------------------------------------------------
/deploy_key.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dojo/loader/147cb45a67a4de9a411c388af0047ae8bdd4d5aa/deploy_key.enc
--------------------------------------------------------------------------------
/docs/api.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 0,
3 | "name": "@dojo/loader",
4 | "kind": 0,
5 | "flags": {
6 | "__visited__": true
7 | },
8 | "children": [
9 | {
10 | "id": 1,
11 | "name": "\"loader\"",
12 | "kind": 1,
13 | "kindString": "External module",
14 | "flags": {
15 | "isExported": true,
16 | "__visited__": true
17 | },
18 | "originalName": "src/loader.ts",
19 | "children": [
20 | {
21 | "id": 2,
22 | "name": "Packages",
23 | "kind": 32,
24 | "kindString": "Variable",
25 | "flags": {
26 | "__visited__": true
27 | },
28 | "sources": [
29 | {
30 | "fileName": "loader.ts",
31 | "line": 7,
32 | "character": 20
33 | }
34 | ],
35 | "type": {
36 | "type": "union",
37 | "types": [
38 | {
39 | "type": "reflection",
40 | "declaration": {
41 | "id": 3,
42 | "name": "__type",
43 | "kind": 65536,
44 | "kindString": "Type literal",
45 | "flags": {
46 | "__visited__": true
47 | },
48 | "indexSignature": [
49 | {
50 | "id": 4,
51 | "name": "__index",
52 | "kind": 8192,
53 | "kindString": "Index signature",
54 | "flags": {
55 | "__visited__": true
56 | },
57 | "parameters": [
58 | {
59 | "id": 5,
60 | "name": "key",
61 | "kind": 32768,
62 | "kindString": "Parameter",
63 | "flags": {
64 | "__visited__": true
65 | },
66 | "type": {
67 | "type": "intrinsic",
68 | "name": "string"
69 | }
70 | }
71 | ],
72 | "type": {
73 | "type": "intrinsic",
74 | "name": "any"
75 | }
76 | }
77 | ],
78 | "sources": [
79 | {
80 | "fileName": "loader.ts",
81 | "line": 7,
82 | "character": 21
83 | }
84 | ]
85 | }
86 | },
87 | {
88 | "type": "intrinsic",
89 | "name": "undefined"
90 | }
91 | ]
92 | }
93 | }
94 | ],
95 | "groups": [
96 | {
97 | "title": "Variables",
98 | "kind": 32,
99 | "children": [
100 | 2
101 | ]
102 | }
103 | ],
104 | "sources": [
105 | {
106 | "fileName": "loader.ts",
107 | "line": 1,
108 | "character": 0
109 | }
110 | ]
111 | }
112 | ],
113 | "groups": [
114 | {
115 | "title": "External modules",
116 | "kind": 1,
117 | "children": [
118 | 1
119 | ]
120 | }
121 | ]
122 | }
--------------------------------------------------------------------------------
/intern.json:
--------------------------------------------------------------------------------
1 | {
2 | "capabilities+": {
3 | "project": "Dojo 2",
4 | "name": "@dojo/loader",
5 | "fixSessionCapabilities": false,
6 | "browserstack.debug": false
7 | },
8 |
9 | "environments": [
10 | { "browserName": "node" }
11 | ],
12 |
13 | "suites": [
14 | "./_build/tests/unit/all.js"
15 | ],
16 |
17 | "functionalSuites": [
18 | "./_build/tests/functional/all.js"
19 | ],
20 |
21 | "browser": {
22 | "loader": {
23 | "script": "dojo2",
24 | "options": {
25 | "packages": [
26 | { "name": "src", "location": "_build/src" },
27 | { "name": "tests", "location": "_build/tests" },
28 | { "name": "@dojo", "location": "node_modules/@dojo" },
29 | { "name": "sinon", "location": "node_modules/sinon/pkg", "main": "sinon" }
30 | ]
31 | }
32 | }
33 | },
34 |
35 | "node": {
36 | "suites": [
37 | "./_build/tests/unit/all-node.js"
38 | ]
39 | },
40 |
41 | "coverage": [
42 | "./_build/src/**/*.js"
43 | ],
44 |
45 | "configs": {
46 | "browserstack": {
47 | "tunnel": "browserstack",
48 | "environments+": [
49 | { "browserName": "internet explorer", "version": "11" },
50 | { "browserName": "edge" },
51 | { "browserName": "firefox", "platform": "WINDOWS" },
52 | { "browserName": "chrome", "platform": "WINDOWS" }
53 | ],
54 |
55 | "maxConcurrency": 5
56 | },
57 |
58 | "local": {
59 | "tunnel": "selenium",
60 | "tunnelOptions": {
61 | "hostname": "localhost",
62 | "port": 4444
63 | },
64 |
65 | "environments+": [
66 | { "browserName": "chrome" }
67 | ]
68 | },
69 |
70 | "saucelabs": {
71 | "tunnel": "saucelabs",
72 | "tunnelOptions": {},
73 |
74 | "defaultTimeout": 10000,
75 | "environments+": [
76 | { "browserName": "internet explorer", "version": [ "11.0" ], "platform": "Windows 7" },
77 | { "browserName": "firefox", "version": "43", "platform": "Windows 10" },
78 | { "browserName": "chrome", "platform": "Windows 10" }
79 | ],
80 | "maxConcurrency": 4
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@dojo/loader",
3 | "version": "2.0.1-pre",
4 | "description": "JavaScript module loader for web applications.",
5 | "engines": {
6 | "npm": ">=3.0.0"
7 | },
8 | "homepage": "https://dojo.io",
9 | "bugs": {
10 | "url": "https://github.com/dojo/loader/issues"
11 | },
12 | "license": "BSD-3-Clause",
13 | "repository": {
14 | "type": "git",
15 | "url": "https://github.com/dojo/loader.git"
16 | },
17 | "main": "loader.js",
18 | "private": true,
19 | "scripts": {
20 | "precommit": "lint-staged",
21 | "prettier": "prettier --write 'src/**/*.ts' 'tests/**/*.ts'",
22 | "test": "grunt test"
23 | },
24 | "typings": "dojo-loader.d.ts",
25 | "devDependencies": {
26 | "@dojo/loader": "0.1.1",
27 | "@types/glob": "~5.0.0",
28 | "@types/grunt": "~0.4.0",
29 | "@types/node": "~9.6.5",
30 | "dts-generator": "~2.0.0",
31 | "grunt": "^1.0.1",
32 | "grunt-contrib-uglify": "^2.0.0",
33 | "grunt-dojo2": "latest",
34 | "grunt-tslint": "5.0.1",
35 | "husky": "0.14.3",
36 | "intern": "~4.1.0",
37 | "lint-staged": "6.0.0",
38 | "prettier": "1.9.2",
39 | "tslint": "5.8.0",
40 | "typescript": "~2.6.1"
41 | },
42 | "lint-staged": {
43 | "*.{ts,tsx}": [
44 | "prettier --write",
45 | "git add"
46 | ]
47 | },
48 | "prettier": {
49 | "singleQuote": true,
50 | "tabWidth": 4,
51 | "useTabs": true,
52 | "parser": "typescript",
53 | "printWidth": 120,
54 | "arrowParens": "always"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/interfaces.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace DojoLoader {
2 | /**
3 | * Common AMD Configuration
4 | *
5 | * See [Common Config](https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md)
6 | */
7 | export interface Config {
8 | /**
9 | * Indicates the root used for ID-to-path resolutions. Relative paths are relative to the current
10 | * working directory. In web browsers, the current working directory is the directory containing
11 | * the web page running the script.
12 | */
13 | baseUrl?: string;
14 |
15 | /**
16 | * Specifies for a given module ID prefix, what module ID prefix to use in place of another
17 | * module ID prefix. For example, how to express "when `bar` asks for module ID `foo`,
18 | * actually use module ID 'foo1.2'".
19 | *
20 | * This sort of capability is important for larger projects which may have two sets of
21 | * modules that need to use two different versions of `foo`, but they still need to
22 | * cooperate with each other.
23 | *
24 | * This is different from `paths` config. `paths` is only for setting up root paths for
25 | * module IDs, not for mapping one module ID to another one.
26 | */
27 | map?: ModuleMap;
28 |
29 | /**
30 | * Array of package configuration (packageConfig) objects. Package configuration is for
31 | * traditional CommonJS packages, which has different path lookup rules than the default
32 | * ID-to-path lookup rules used by an AMD loader.
33 | *
34 | * Default lookup rules are ,baseUrl + 'module/id' + .js, where paths config can be used
35 | * to map part of 'module/id' to another path.
36 | */
37 | packages?: Package[];
38 |
39 | /**
40 | * For specifying a path for a the given module ID prefix.
41 | *
42 | * A property in the paths object is an absolute module ID prefix.
43 | */
44 | paths?: { [path: string]: string };
45 |
46 | /* TODO: We should remove internal APIs like this */
47 | pkgs?: { [path: string]: Package };
48 |
49 | shim?: { [path: string]: ModuleShim | string[] };
50 |
51 | crossOrigin?: false | 'anonymous' | 'use-credentials';
52 | }
53 |
54 | interface Define {
55 | (moduleId: string, dependencies: string[], factory: Factory): void;
56 | (dependencies: string[], factory: Factory): void;
57 | (factory: Factory): void;
58 | (value: any): void;
59 | amd: { [prop: string]: string | number | boolean };
60 | }
61 |
62 | interface Factory {
63 | (...modules: any[]): any;
64 | }
65 |
66 | interface Has {
67 | (name: string): any;
68 | add(
69 | name: string,
70 | value: (global: Window, document?: HTMLDocument, element?: HTMLDivElement) => any,
71 | now?: boolean,
72 | force?: boolean
73 | ): void;
74 | add(name: string, value: any, now?: boolean, force?: boolean): void;
75 | }
76 |
77 | interface LoaderError extends Error {
78 | readonly src: string;
79 | readonly info: { module: Module; url: string; parentMid: string; details?: string };
80 | }
81 |
82 | /**
83 | * AMD Loader Plugin API
84 | *
85 | * See [Loader Plugin API](https://github.com/amdjs/amdjs-api/blob/master/LoaderPlugins.md)
86 | */
87 | interface LoaderPlugin {
88 | /**
89 | * A function that is called to load a resource. This is the only mandatory API method that needs
90 | * to be implemented for the plugin to be useful, assuming the resource IDs do not need special
91 | * ID normalization.
92 | * @param resourceId The resource ID that the plugin should load. This ID MUST be normalized.
93 | * @param require A local require function to use to load other modules. This require function
94 | * has some utilities on it:
95 | * * **require.toUrl('moduleId+extension')** See the `require.toUrl` API notes
96 | * for more information.
97 | * @param load A function to call once the value of the resource ID has been determined. This
98 | * tells the loader that the plugin is done loading the resource.
99 | * @param config A configuration object. This is a way for the optimizer and the web app to
100 | * pass configuration information to the plugin. An optimization tool may set
101 | * an `isBuild` property in the config to true if this plugin is being called
102 | * as part of an optimizer build.
103 | */
104 | load?(
105 | resourceId: string,
106 | require: Require,
107 | load: (value?: any) => void,
108 | config?: { [prop: string]: any }
109 | ): void;
110 |
111 | /**
112 | * A function to normalize the passed-in resource ID. Normalization of an module ID normally
113 | * means converting relative paths, like `./some/path` or `../another/path` to be non-relative,
114 | * absolute IDs
115 | * @param resourceId The resource ID to normalize.
116 | * @param normalize A normalization function that accepts a string ID to normalize using the
117 | * standard relative module normalization rules using the loader's current
118 | * configuration.
119 | */
120 | normalize?(resourceId: string, normalize: (moduleId: string) => string): string;
121 | }
122 |
123 | interface MapItem extends Array {
124 | /* prefix */ 0: string;
125 | /* replacement */ 1: any;
126 | /* regExp */ 2: RegExp;
127 | /* length */ 3: number;
128 | }
129 |
130 | interface MapReplacement extends MapItem {
131 | /* replacement */ 1: string;
132 | }
133 |
134 | interface MapRoot extends Array {
135 | star?: MapSource;
136 | }
137 |
138 | interface MapSource extends MapItem {
139 | /* replacement */ 1: MapReplacement[];
140 | }
141 |
142 | // TODO are we still abbreviating these properties?
143 | // TODO shouldn't extend for LoaderPlugin because technically `load` is not optional
144 | interface Module extends LoaderPlugin {
145 | cjs: {
146 | exports: any;
147 | id: string;
148 | setExports: (exports: any) => void;
149 | uri: string;
150 | };
151 | def: Factory;
152 | deps: Module[];
153 | executed: any; // TODO: enum
154 | injected: boolean;
155 | fix?: (module: Module) => void;
156 | gc: boolean;
157 | mid: string;
158 | pack: Package;
159 | req: Require;
160 | require?: Require; // TODO: WTF?
161 | result: any;
162 | url: string;
163 |
164 | // plugin interface
165 | loadQ?: Module[];
166 | plugin?: Module;
167 | prid: string;
168 | }
169 |
170 | interface ModuleDefinitionArguments extends Array {
171 | 0: string[];
172 | 1: Factory;
173 | }
174 |
175 | interface ModuleMap extends ModuleMapItem {
176 | [sourceMid: string]: ModuleMapReplacement | string;
177 | }
178 |
179 | interface ModuleMapItem {
180 | [mid: string]: /* ModuleMapReplacement | ModuleMap */ any;
181 | }
182 |
183 | interface ModuleMapReplacement extends ModuleMapItem {
184 | [findMid: string]: /* replaceMid */ string;
185 | }
186 |
187 | interface ObjectMap {
188 | [key: string]: any;
189 | }
190 |
191 | interface Package {
192 | location?: string;
193 | main?: string;
194 | name?: string;
195 | }
196 |
197 | interface PackageMap {
198 | [packageId: string]: Package;
199 | }
200 |
201 | interface PathMap extends MapReplacement {}
202 |
203 | interface ModuleShim {
204 | deps?: string[];
205 | exports?: string;
206 | init?: (...dependencies: any[]) => any;
207 | }
208 |
209 | interface Require {
210 | (dependencies: string[], callback: RequireCallback): void;
211 | (moduleId: string): ModuleType;
212 |
213 | toAbsMid(moduleId: string): string;
214 | toUrl(path: string): string;
215 | }
216 |
217 | interface RequireCallback {
218 | (...modules: any[]): void;
219 | }
220 |
221 | interface RootRequire extends Require {
222 | cache(cache: DojoLoader.ObjectMap): void;
223 | has: Has;
224 | on(type: SignalType, listener: any): { remove: () => void };
225 | config(config: Config): void;
226 | inspect?(name: string): any;
227 | nodeRequire?(id: string): any;
228 | undef(moduleId: string, recursive?: boolean): void;
229 | }
230 |
231 | type SignalType = 'error';
232 | }
233 |
234 | declare const define: DojoLoader.Define;
235 |
236 | declare interface NodeRequire {
237 | (dependencies: string[], callback: DojoLoader.RequireCallback): void;
238 |
239 | config(config: DojoLoader.Config): void;
240 | has: DojoLoader.Has;
241 | inspect?(name: string): any;
242 | nodeRequire?: NodeRequire;
243 | on(type: DojoLoader.SignalType, listener: any): { remove: () => void };
244 | toAbsMid(moduleId: string): string;
245 | toUrl(path: string): string;
246 | undef(moduleId: string, recursive?: boolean): void;
247 | }
248 |
249 | declare var arguments: IArguments;
250 |
--------------------------------------------------------------------------------
/src/loader.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import ModuleShim = DojoLoader.ModuleShim;
3 | import Module = DojoLoader.Module;
4 | import Package = DojoLoader.Package;
5 |
6 | // Nashorn global
7 | declare var Packages: { [key: string]: any; } | undefined;
8 |
9 | (function(args?: string[]): void {
10 | let globalObject: any = (function(): any {
11 | if (typeof window !== 'undefined') {
12 | // Browsers
13 | return window;
14 | } else if (typeof global !== 'undefined') {
15 | // Node
16 | return global;
17 | } else if (typeof self !== 'undefined') {
18 | // Web workers
19 | return self;
20 | }
21 | return {};
22 | })();
23 |
24 | // Nashorn global
25 | const load: (module: string) => any = globalObject.load;
26 |
27 | // webworker global
28 | const importScripts: ((url: string) => void) = globalObject.importScripts;
29 |
30 | const EXECUTING = 'executing';
31 | const ABORT_EXECUTION: Object = {};
32 | //
33 | // loader state data
34 | //
35 |
36 | // hash: (mid | url)-->(function | string)
37 | //
38 | // A cache of resources. The resources arrive via a require.cache application, which takes a hash from either
39 | // mid --> function or url --> string. The function associated with mid keys causes the same code to execute as if
40 | // the module was script injected.
41 | //
42 | // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate
43 | // keys as given by any mappings *iff* the cache was received as part of a module resource request.
44 | let cache: DojoLoader.ObjectMap = {};
45 |
46 | let checkCompleteGuard = 0;
47 |
48 | // The configuration passed to the loader
49 | let config: DojoLoader.Config = {
50 | baseUrl: './',
51 | packages: [],
52 | paths: {},
53 | pkgs: {},
54 | shim: {},
55 | crossOrigin: false
56 | };
57 |
58 | // The arguments sent to loader via AMD define().
59 | let moduleDefinitionArguments: DojoLoader.ModuleDefinitionArguments | undefined = undefined;
60 |
61 | // The list of modules that need to be evaluated.
62 | let executionQueue: DojoLoader.Module[] = [];
63 |
64 | let executedSomething = false;
65 |
66 | let injectUrl: (
67 | url: string,
68 | callback: (node?: HTMLScriptElement) => void,
69 | module: DojoLoader.Module,
70 | parent?: DojoLoader.Module
71 | ) => void;
72 |
73 | // array of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value
74 | let mapPrograms: DojoLoader.MapRoot = [];
75 |
76 | // A hash: (mid) --> (module-object) the module namespace
77 | //
78 | // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default
79 | // package
80 | // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier
81 | // (e.g., "dojo/io/script")
82 | // url: the URL from which the module was retrieved
83 | // pack: the package object of the package to which the module belongs
84 | // executed: false => not executed; EXECUTING => in the process of tranversing deps and running factory;
85 | // true => factory has been executed
86 | // deps: the dependency array for this module (array of modules objects)
87 | // def: the factory for this module
88 | // result: the result of the running the factory for this module
89 | // injected: true => module has been injected
90 | // load, normalize: plugin functions applicable only for plugins
91 | //
92 | // Modules go through several phases in creation:
93 | //
94 | // 1. Requested: some other module's definition or a require application contained the requested module in
95 | // its dependency array
96 | //
97 | // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by
98 | // the URL
99 | //
100 | // 3. Loaded: the resource injected in [2] has been evaluated.
101 | //
102 | // 4. Defined: the resource contained a define statement that advised the loader about the module.
103 | //
104 | // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
105 | let modules: { [moduleId: string]: DojoLoader.Module | undefined } = {};
106 |
107 | // list of (from-path, to-path, regex, length) derived from paths;
108 | // a "program" to apply paths; see computeMapProg
109 | let pathMapPrograms: DojoLoader.PathMap[] = [];
110 |
111 | let setGlobals: (require: DojoLoader.RootRequire, define: DojoLoader.Define) => void;
112 |
113 | let uidGenerator = 0;
114 |
115 | // the number of modules the loader has injected but has not seen defined
116 | let waitingCount = 0;
117 |
118 | const has: DojoLoader.Has = (function(): DojoLoader.Has {
119 | const hasCache: { [name: string]: any } = Object.create(null);
120 | const global: Window = globalObject;
121 | const document: HTMLDocument = global.document;
122 | const element: HTMLDivElement = document && document.createElement('div');
123 |
124 | const has: DojoLoader.Has = function(name: string): any {
125 | return typeof hasCache[name] === 'function'
126 | ? (hasCache[name] = hasCache[name](global, document, element))
127 | : hasCache[name];
128 | };
129 |
130 | has.add = function(name: string, test: any, now: boolean, force: boolean): void {
131 | (!(name in hasCache) || force) && (hasCache[name] = test);
132 | now && has(name);
133 | };
134 |
135 | return has;
136 | })();
137 |
138 | const requireModule: DojoLoader.RootRequire = function(
139 | dependencies: any,
140 | callback?: DojoLoader.RequireCallback
141 | ): DojoLoader.Module {
142 | return contextRequire(dependencies, callback);
143 | };
144 |
145 | const listenerQueues: { [queue: string]: ((...args: any[]) => void)[] } = {};
146 |
147 | const emit = function(type: DojoLoader.SignalType, args: {}): number | boolean {
148 | let queue = listenerQueues[type];
149 | let hasListeners = queue && queue.length;
150 |
151 | if (hasListeners) {
152 | for (let listener of queue.slice(0)) {
153 | listener.apply(null, Array.isArray(args) ? args : [args]);
154 | }
155 | }
156 |
157 | return hasListeners;
158 | };
159 |
160 | const reportModuleLoadError = function(
161 | parent: DojoLoader.Module | undefined,
162 | module: DojoLoader.Module,
163 | url: string,
164 | details?: string
165 | ): void {
166 | const parentMid = parent ? ` (parent: ${parent.mid})` : '';
167 | const message = `Failed to load module ${module.mid} from ${url}${parentMid}`;
168 | const error = mix(new Error(message), {
169 | src: 'dojo/loader',
170 | info: {
171 | module,
172 | url,
173 | parentMid,
174 | details
175 | }
176 | });
177 |
178 | if (!emit('error', error)) {
179 | throw error;
180 | }
181 | };
182 |
183 | const on = function(type: string, listener: (error: DojoLoader.LoaderError) => void): { remove: () => void } {
184 | let queue = listenerQueues[type] || (listenerQueues[type] = []);
185 |
186 | queue.push(listener);
187 |
188 | return {
189 | remove(): void {
190 | queue.splice(queue.indexOf(listener), 1);
191 | }
192 | };
193 | };
194 |
195 | requireModule.has = has;
196 | requireModule.on = on;
197 |
198 | has.add('host-browser', typeof document !== 'undefined' && typeof location !== 'undefined');
199 | has.add('host-node', typeof process === 'object' && process.versions && process.versions.node);
200 | has.add('host-nashorn', typeof load === 'function' && typeof Packages !== 'undefined');
201 | has.add('host-web-worker', !has('host-browser') && typeof importScripts !== 'undefined');
202 | has.add('debug', true);
203 |
204 | has.add('loader-configurable', true);
205 | has.add('loader-config-attribute', true);
206 | if (has('loader-configurable')) {
207 | /**
208 | * Configures the loader.
209 | *
210 | * @param {{ ?baseUrl: string, ?map: Object, ?packages: Array.<({ name, ?location, ?main }|string)> }} config
211 | * The configuration data.
212 | */
213 | requireModule.config = function(configuration: DojoLoader.Config): void {
214 | // Make sure baseUrl ends in a slash
215 | if (configuration.baseUrl) {
216 | configuration.baseUrl = configuration.baseUrl.replace(/\/*$/, '/');
217 | }
218 |
219 | const mergeProps: DojoLoader.ObjectMap = {
220 | paths: true,
221 | bundles: true,
222 | config: true,
223 | map: true
224 | };
225 |
226 | // Copy configuration over to config object
227 | for (let key in configuration) {
228 | const value = (configuration)[key];
229 | if (mergeProps[key]) {
230 | if (!(config)[key]) {
231 | (config)[key] = {};
232 | }
233 | mix((config)[key], value, true);
234 | } else {
235 | (config)[key] = value;
236 | }
237 | }
238 |
239 | // TODO: Expose all properties on req as getter/setters? Plugin modules like dojo/node being able to
240 | // retrieve baseUrl is important. baseUrl is defined as a getter currently.
241 |
242 | forEach(configuration.packages || [], function(packageDescriptor: DojoLoader.Package): void {
243 | // Allow shorthand package definition, where name and location are the same
244 | if (typeof packageDescriptor === 'string') {
245 | packageDescriptor = { name: packageDescriptor, location: packageDescriptor };
246 | }
247 |
248 | if (packageDescriptor.location != null) {
249 | packageDescriptor.location = packageDescriptor.location.replace(/\/*$/, '/');
250 | }
251 |
252 | if (config && config.pkgs && packageDescriptor.name) {
253 | config.pkgs[packageDescriptor.name] = packageDescriptor;
254 | }
255 | });
256 |
257 | function computeMapProgram(map: DojoLoader.ModuleMapItem | undefined): DojoLoader.MapItem[] {
258 | // This method takes a map as represented by a JavaScript object and initializes an array of
259 | // arrays of (map-key, map-value, regex-for-map-key, length-of-map-key), sorted decreasing by length-
260 | // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning
261 | // of a the search source.
262 | //
263 | // Maps look like this:
264 | //
265 | // map: { C: { D: E } }
266 | // A B
267 | //
268 | // The computed mapping is a 4-array deep tree, where the outermost array corresponds to the source
269 | // mapping object A, the 2nd level arrays each correspond to one of the source mappings C -> B, the 3rd
270 | // level arrays correspond to each destination mapping object B, and the innermost arrays each
271 | // correspond to one of the destination mappings D -> E.
272 | //
273 | // So, the overall structure looks like this:
274 | //
275 | // mapPrograms = [ source mapping array, source mapping array, ... ]
276 | // source mapping array = [
277 | // source module id,
278 | // [ destination mapping array, destination mapping array, ... ],
279 | // RegExp that matches on source module id,
280 | // source module id length
281 | // ]
282 | // destination mapping array = [
283 | // original module id,
284 | // destination module id,
285 | // RegExp that matches on original module id,
286 | // original module id length
287 | // ]
288 |
289 | const result: DojoLoader.MapItem[] = [];
290 |
291 | if (map) {
292 | for (let moduleId in map) {
293 | const value: any = (map)[moduleId];
294 | const isValueAMapReplacement: boolean = typeof value === 'object';
295 |
296 | const item = {
297 | 0: moduleId,
298 | 1: isValueAMapReplacement ? computeMapProgram(value) : value,
299 | 2: new RegExp('^' + moduleId.replace(/[-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&') + '(?:/|$)'),
300 | 3: moduleId.length
301 | };
302 | result.push(item);
303 |
304 | if (isValueAMapReplacement && moduleId === '*') {
305 | (result).star = item[1];
306 | }
307 | }
308 | }
309 |
310 | result.sort(function(left: DojoLoader.MapItem, right: DojoLoader.MapItem): number {
311 | return right[3] - left[3];
312 | });
313 |
314 | return result;
315 | }
316 |
317 | // FIXME this is a down-cast.
318 | // computeMapProgram => MapItem[] => mapPrograms: MapSource[]
319 | // MapSource[1] => MapReplacement[] is more specific than MapItems[1] => any
320 | mapPrograms = computeMapProgram(config.map);
321 |
322 | // Note that old paths will get destroyed if reconfigured
323 | configuration.paths && (pathMapPrograms = computeMapProgram(configuration.paths));
324 |
325 | // shim API
326 | if (config.shim) {
327 | Object.keys(config.shim).forEach((moduleId) => {
328 | // guards currently get reset in callbacks: https://github.com/Microsoft/TypeScript/issues/11498
329 | const value = config.shim![moduleId];
330 | let moduleDef: ModuleShim;
331 |
332 | // using shorthand module syntax, convert to full syntax
333 | if (Array.isArray(value)) {
334 | moduleDef = {
335 | deps: value
336 | };
337 | } else {
338 | moduleDef = value;
339 | }
340 |
341 | define(moduleId, moduleDef.deps || [], function(...dependencies) {
342 | let root: any;
343 |
344 | let globalPath = moduleDef.exports;
345 |
346 | if (globalPath) {
347 | root = globalObject;
348 |
349 | globalPath.split('.').forEach((pathComponent) => {
350 | if (!(pathComponent in root)) {
351 | throw new Error(`Tried to find ${globalPath} but it did not exist`);
352 | } else {
353 | root = root[pathComponent];
354 | }
355 | });
356 | }
357 |
358 | if (moduleDef.init) {
359 | let newReturnValue: any = moduleDef.init(...dependencies);
360 |
361 | if (newReturnValue !== undefined) {
362 | root = newReturnValue;
363 | }
364 | }
365 |
366 | return root;
367 | });
368 | });
369 | }
370 | };
371 |
372 | if (has('loader-config-attribute') && has('host-browser')) {
373 | Array.prototype.slice
374 | .call(document.getElementsByTagName('script'), 0)
375 | .forEach((script: HTMLScriptElement) => {
376 | if (script.hasAttribute('data-loader-config')) {
377 | const attr = script.getAttribute('data-loader-config');
378 | let dojoConfig: DojoLoader.Config | null = null;
379 |
380 | try {
381 | dojoConfig = JSON.parse(`{ ${attr} }`);
382 | } catch (e) {
383 | console.error('Unable to parse data-loader-config, ' + attr);
384 | console.error(e);
385 | }
386 |
387 | if (dojoConfig !== null) {
388 | requireModule.config(dojoConfig);
389 | }
390 | }
391 | });
392 | }
393 | }
394 |
395 | function forEach(array: T[], callback: (value: T, index: number, array: T[]) => void): void {
396 | array && array.forEach(callback);
397 | }
398 |
399 | function mix(target: {}, source: {}, deep?: boolean): T {
400 | if (source) {
401 | for (let key in source) {
402 | let sourceValue = (source)[key];
403 |
404 | if (
405 | deep &&
406 | typeof sourceValue === 'object' &&
407 | !Array.isArray(sourceValue) &&
408 | !(sourceValue instanceof RegExp)
409 | ) {
410 | if (!(target)[key]) {
411 | (target)[key] = {};
412 | }
413 | mix((target)[key], sourceValue, true);
414 | } else {
415 | (target)[key] = sourceValue;
416 | }
417 | }
418 | }
419 | return target;
420 | }
421 |
422 | function noop(): void {}
423 |
424 | let loadNodeModule: (moduleId: string, parent?: DojoLoader.Module) => any = noop;
425 |
426 | function contextRequire(moduleId: string, unused?: void, referenceModule?: DojoLoader.Module): DojoLoader.Module;
427 | function contextRequire(
428 | dependencies: string[],
429 | callback?: DojoLoader.RequireCallback,
430 | referenceModule?: DojoLoader.Module
431 | ): DojoLoader.Module;
432 | function contextRequire(
433 | dependencies: string | string[],
434 | callback: any,
435 | referenceModule?: DojoLoader.Module
436 | ): DojoLoader.Module | undefined {
437 | let module: DojoLoader.Module | undefined = undefined;
438 | if (typeof dependencies === 'string') {
439 | module = getModule(dependencies, referenceModule);
440 | if (module.executed !== true && module.executed !== EXECUTING) {
441 | if (has('host-node') && !module.plugin) {
442 | try {
443 | let result = loadNodeModule(module.mid, referenceModule);
444 |
445 | initializeModule(module, [], undefined);
446 | module.result = result;
447 | module.cjs.setExports(result);
448 | module.executed = true;
449 | module.injected = true;
450 | } catch (error) {
451 | throw new Error('Attempt to require unloaded module ' + module.mid);
452 | }
453 | } else if (module.plugin) {
454 | injectModule(module, undefined);
455 | }
456 | }
457 | // Assign the result of the module to `module`
458 | // otherwise require('moduleId') returns the internal
459 | // module representation
460 | module = module.result;
461 | } else if (Array.isArray(dependencies)) {
462 | // signature is (requestList [,callback])
463 | // construct a synthetic module to control execution of the requestList, and, optionally, callback
464 | module = getModuleInformation('*' + ++uidGenerator);
465 | mix(module, {
466 | deps: resolveDependencies(dependencies, module, referenceModule),
467 | def: callback || {},
468 | gc: true // garbage collect
469 | });
470 | guardCheckComplete(function(): void {
471 | forEach(module ? module.deps : [], injectModule.bind(null, module));
472 | });
473 | executionQueue.push(module);
474 | checkComplete();
475 | }
476 | return module;
477 | }
478 |
479 | function createRequire(module: DojoLoader.Module | undefined): DojoLoader.Require | undefined {
480 | let result: DojoLoader.Require | undefined = (!module && requireModule) || (module && module.require);
481 | if (!result && module) {
482 | module.require = result = function(
483 | dependencies: any,
484 | callback: any
485 | ): DojoLoader.Module {
486 | return contextRequire(dependencies, callback, module);
487 | };
488 | mix(mix(result, requireModule), {
489 | toUrl: function(name: string): string {
490 | return toUrl(name, module);
491 | },
492 | toAbsMid: function(mid: string): string {
493 | return toAbsMid(mid, module);
494 | }
495 | });
496 | }
497 | return result;
498 | }
499 |
500 | function runMapProgram(targetModuleId: string, map?: DojoLoader.MapItem[]): DojoLoader.MapSource | undefined {
501 | // search for targetModuleId in map; return the map item if found; falsy otherwise
502 | if (map) {
503 | for (let i = 0, j = map.length; i < j; ++i) {
504 | if (map[i][2].test(targetModuleId)) {
505 | return map[i];
506 | }
507 | }
508 | }
509 |
510 | return undefined;
511 | }
512 |
513 | function compactPath(path: string): string {
514 | const pathSegments: string[] = path.replace(/\\/g, '/').split('/');
515 | let absolutePathSegments: (string | undefined)[] = [];
516 | let segment: string | undefined;
517 | let lastSegment: string | undefined = '';
518 |
519 | while (pathSegments.length) {
520 | segment = pathSegments.shift();
521 | if (segment === '..' && absolutePathSegments.length && lastSegment !== '..') {
522 | absolutePathSegments.pop();
523 | lastSegment = absolutePathSegments[absolutePathSegments.length - 1];
524 | } else if (segment !== '.') {
525 | absolutePathSegments.push((lastSegment = segment));
526 | } // else ignore "."
527 | }
528 |
529 | return absolutePathSegments.join('/');
530 | }
531 |
532 | function updateModuleIdFromMap(moduleId: string, referenceModule?: DojoLoader.Module): string {
533 | // relative module ids are relative to the referenceModule; get rid of any dots
534 | moduleId = compactPath(
535 | /^\./.test(moduleId) && referenceModule ? referenceModule.mid + '/../' + moduleId : moduleId
536 | );
537 | // at this point, moduleId is an absolute moduleId
538 |
539 | // if there is a reference module, then use its module map, if one exists; otherwise, use the global map.
540 | // see computeMapProg for more information on the structure of the map arrays
541 | let moduleMap: DojoLoader.MapItem | undefined =
542 | referenceModule && runMapProgram(referenceModule.mid, mapPrograms);
543 | moduleMap = moduleMap ? moduleMap[1] : mapPrograms.star;
544 |
545 | let mapItem: DojoLoader.MapItem | undefined;
546 | if ((mapItem = runMapProgram(moduleId, moduleMap))) {
547 | moduleId = mapItem[1] + moduleId.slice(mapItem[3]);
548 | }
549 |
550 | return moduleId;
551 | }
552 |
553 | function getPluginInformation(
554 | moduleId: string,
555 | match: string[],
556 | referenceModule?: DojoLoader.Module
557 | ): DojoLoader.Module {
558 | const plugin = getModule(match[1], referenceModule);
559 | const isPluginLoaded = Boolean(plugin.load);
560 |
561 | const contextRequire = createRequire(referenceModule);
562 |
563 | let pluginResourceId: string;
564 | if (isPluginLoaded) {
565 | pluginResourceId = resolvePluginResourceId(plugin, match[2], contextRequire);
566 | moduleId = plugin.mid + '!' + pluginResourceId;
567 | } else {
568 | // if not loaded, need to mark in a way that it will get properly resolved later
569 | pluginResourceId = match[2];
570 | moduleId = plugin.mid + '!' + ++uidGenerator + '!*';
571 | }
572 | return ({
573 | plugin: plugin,
574 | mid: moduleId,
575 | req: contextRequire,
576 | prid: pluginResourceId,
577 | fix: !isPluginLoaded
578 | });
579 | }
580 |
581 | function getModuleInformation(moduleId: string, referenceModule?: DojoLoader.Module): DojoLoader.Module {
582 | let packageId = '';
583 | let pack: Package = {};
584 | let moduleIdInPackage = '';
585 |
586 | const matches = Object.keys((config && config.pkgs) || {})
587 | .filter((pkg) => (moduleId + '/').indexOf(pkg + '/') === 0)
588 | .sort((a, b) => (a.length > b.length ? -1 : 1));
589 |
590 | if (matches.length) {
591 | packageId = matches.shift() as string;
592 | pack = config.pkgs![packageId];
593 | moduleId =
594 | packageId + '/' + (moduleIdInPackage = moduleId.substr(packageId.length + 1) || pack.main || 'main');
595 | }
596 |
597 | let module = modules[moduleId];
598 | if (!module) {
599 | let mapItem = runMapProgram(moduleId, pathMapPrograms);
600 | let url = mapItem
601 | ? mapItem[1] + moduleId.slice(mapItem[3])
602 | : packageId ? pack.location + moduleIdInPackage : moduleId;
603 | module = ({
604 | pid: packageId,
605 | mid: moduleId,
606 | pack: pack,
607 | url: compactPath(
608 | // absolute urls should not be prefixed with baseUrl
609 | (/^(?:\/|\w+:)/.test(url) ? '' : config.baseUrl) +
610 | url +
611 | // urls with a javascript extension should not have another one added
612 | (/\.js(?:\?[^?]*)?$/.test(url) ? '' : '.js')
613 | )
614 | });
615 | }
616 |
617 | return module;
618 | }
619 |
620 | function resolvePluginResourceId(
621 | plugin: DojoLoader.Module,
622 | pluginResourceId: string,
623 | contextRequire?: DojoLoader.Require
624 | ): string {
625 | const toAbsMid = contextRequire ? contextRequire.toAbsMid : undefined;
626 | return plugin.normalize
627 | ? plugin.normalize(pluginResourceId, toAbsMid)
628 | : toAbsMid ? toAbsMid(pluginResourceId) : '';
629 | }
630 |
631 | function getModule(moduleId: string, referenceModule?: DojoLoader.Module): DojoLoader.Module {
632 | // compute and construct (if necessary) the module implied by the moduleId with respect to referenceModule
633 | let module: DojoLoader.Module;
634 | const pluginRegEx = /^(.+?)\!(.*)$/;
635 |
636 | // Foreseable situations (where ?-> is a map lookup function)
637 | // module
638 | // plugin!arg
639 | // module ?-> mappedModule
640 | // module ?-> mappedPlugin!arg
641 | // plugin!arg ?-> mappedPlugin + ! + arg
642 |
643 | // Do inital check on the passed in moduleId
644 | const passedModuleMatch = moduleId.match(pluginRegEx);
645 | if (passedModuleMatch) {
646 | // Passed in moduleId is a plugin, so check the map using only the plugin name
647 | // then reconstruct using the pluginArgs
648 | let pluginId: string = updateModuleIdFromMap(passedModuleMatch[1], referenceModule);
649 | moduleId = `${pluginId}!${passedModuleMatch[2]}`;
650 | } else {
651 | // Not a module, so check the map using the full moduleId passed
652 | moduleId = updateModuleIdFromMap(moduleId, referenceModule);
653 | }
654 |
655 | // Do final check on the mapped module / plugin Id to see what we're dealing with
656 | const mappedModuleMatch = moduleId.match(pluginRegEx);
657 | if (mappedModuleMatch) {
658 | module = getPluginInformation(moduleId, mappedModuleMatch, referenceModule);
659 | } else {
660 | module = getModuleInformation(moduleId, referenceModule);
661 | }
662 |
663 | return modules[module.mid] || (modules[module.mid] = module);
664 | }
665 |
666 | function toAbsMid(moduleId: string, referenceModule: DojoLoader.Module | undefined): string {
667 | moduleId = updateModuleIdFromMap(moduleId, referenceModule);
668 | return getModuleInformation(moduleId, referenceModule).mid;
669 | }
670 |
671 | function toUrl(name: string, referenceModule: DojoLoader.Module | undefined): string {
672 | let moduleId = name + '/x';
673 | moduleId = updateModuleIdFromMap(moduleId, referenceModule);
674 | const moduleInfo: DojoLoader.Module = getModuleInformation(moduleId, referenceModule);
675 | const url: string = moduleInfo.url;
676 |
677 | // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look like a
678 | // module id
679 | return url.slice(0, url.length - 5);
680 | }
681 |
682 | function makeCommonJs(mid: string): DojoLoader.Module {
683 | return (modules[mid] = ({
684 | mid: mid,
685 | injected: true,
686 | executed: true
687 | }));
688 | }
689 | const commonJsRequireModule: DojoLoader.Module = makeCommonJs('require');
690 | const commonJsExportsModule: DojoLoader.Module = makeCommonJs('exports');
691 | const commonJsModuleModule: DojoLoader.Module = makeCommonJs('module');
692 | let circularTrace: string[];
693 |
694 | has.add('loader-debug-circular-dependencies', true);
695 | if (has('loader-debug-circular-dependencies')) {
696 | circularTrace = [];
697 | }
698 |
699 | function executeModule(module: DojoLoader.Module): any {
700 | // run the dependency array, then run the factory for module
701 | if (module.executed === EXECUTING) {
702 | // for circular dependencies, assume the first module encountered was executed OK
703 | // modules that circularly depend on a module that has not run its factory will get
704 | // the premade cjs.exports===module.result. They can take a reference to this object and/or
705 | // add properties to it. When the module finally runs its factory, the factory can
706 | // read/write/replace this object. Notice that so long as the object isn't replaced, any
707 | // reference taken earlier while walking the dependencies list is still valid.
708 | if (
709 | has('loader-debug-circular-dependencies') &&
710 | module.deps.indexOf(commonJsExportsModule) === -1 &&
711 | typeof console !== 'undefined'
712 | ) {
713 | console.warn('Circular dependency: ' + circularTrace.concat(module.mid).join(' -> '));
714 | }
715 |
716 | return module.result;
717 | }
718 |
719 | if (!module.executed) {
720 | // TODO: This seems like an incorrect condition inference. Originally it was simply !module.def
721 | // which caused modules with falsy defined values to never execute.
722 | if (!module.def && !module.deps) {
723 | return ABORT_EXECUTION;
724 | }
725 |
726 | has('loader-debug-circular-dependencies') && circularTrace.push(module.mid);
727 |
728 | const dependencies: DojoLoader.Module[] = module.deps;
729 | let result: any;
730 |
731 | module.executed = EXECUTING;
732 | let executedDependencies = dependencies.map(function(dependency: DojoLoader.Module): any {
733 | if (result !== ABORT_EXECUTION) {
734 | // check for keyword dependencies: DojoLoader.require, exports, module; then execute module dependency
735 | result =
736 | dependency === commonJsRequireModule
737 | ? createRequire(module)
738 | : dependency === commonJsExportsModule
739 | ? module.cjs.exports
740 | : dependency === commonJsModuleModule ? module.cjs : executeModule(dependency);
741 | }
742 | return result;
743 | });
744 |
745 | if (result === ABORT_EXECUTION) {
746 | module.executed = false;
747 | has('loader-debug-circular-dependencies') && circularTrace.pop();
748 | return ABORT_EXECUTION;
749 | }
750 |
751 | const factory: DojoLoader.Factory = module.def;
752 | result = typeof factory === 'function' ? factory.apply(null, executedDependencies) : factory;
753 |
754 | // TODO: But of course, module.cjs always exists.
755 | // Assign the new module.result to result so plugins can use exports
756 | // to define their interface; the plugin checks below use result
757 | result = module.result = result === undefined && module.cjs ? module.cjs.exports : result;
758 | module.executed = true;
759 | executedSomething = true;
760 |
761 | // delete references to synthetic modules
762 | if (module.gc) {
763 | modules[module.mid] = undefined;
764 | }
765 |
766 | // if result defines load, just assume it's a plugin; harmless if the assumption is wrong
767 | result &&
768 | result.load &&
769 | ['normalize', 'load'].forEach(function(key: string): void {
770 | (module)[key] = (result)[key];
771 | });
772 |
773 | // for plugins, resolve the loadQ
774 | forEach(module.loadQ || [], function(pseudoPluginResource: DojoLoader.Module): void {
775 | // manufacture and insert the real module in modules
776 | const pluginResourceId: string = resolvePluginResourceId(
777 | module,
778 | pseudoPluginResource.prid,
779 | pseudoPluginResource.req
780 | );
781 | const moduleId: string = module.mid + '!' + pluginResourceId;
782 | const pluginResource: DojoLoader.Module = mix(mix({}, pseudoPluginResource), {
783 | mid: moduleId,
784 | prid: pluginResourceId
785 | });
786 |
787 | if (!modules[moduleId]) {
788 | // create a new (the real) plugin resource and inject it normally now that the plugin is on board
789 | injectPlugin((modules[moduleId] = pluginResource));
790 | } // else this was a duplicate request for the same (plugin, rid)
791 |
792 | // pluginResource is really just a placeholder with the wrong moduleId (because we couldn't calculate it
793 | // until the plugin was on board) fix() replaces the pseudo module in a resolved dependencies array with the
794 | // real module lastly, mark the pseudo module as arrived and delete it from modules
795 | if (pseudoPluginResource && pseudoPluginResource.fix) {
796 | pseudoPluginResource.fix(modules[moduleId]);
797 | }
798 | --waitingCount;
799 | modules[pseudoPluginResource.mid] = undefined;
800 | });
801 | module.loadQ = undefined;
802 |
803 | has('loader-debug-circular-dependencies') && circularTrace.pop();
804 | }
805 |
806 | // at this point the module is guaranteed fully executed
807 | return module.result;
808 | }
809 |
810 | // TODO: Figure out what proc actually is
811 | function guardCheckComplete(callback: Function): void {
812 | ++checkCompleteGuard;
813 | callback();
814 | --checkCompleteGuard;
815 | }
816 |
817 | function checkComplete(): void {
818 | // keep going through the executionQueue as long as at least one factory is executed
819 | // plugins, recursion, cached modules all make for many execution path possibilities
820 | !checkCompleteGuard &&
821 | guardCheckComplete(function(): void {
822 | for (let module: DojoLoader.Module, i = 0; i < executionQueue.length; ) {
823 | module = executionQueue[i];
824 | if (module.executed === true) {
825 | executionQueue.splice(i, 1);
826 | } else {
827 | executedSomething = false;
828 | executeModule(module);
829 | if (executedSomething) {
830 | // something was executed; this indicates the executionQueue was modified, maybe a
831 | // lot (for example a later module causes an earlier module to execute)
832 | i = 0;
833 | } else {
834 | // nothing happened; check the next module in the exec queue
835 | i++;
836 | }
837 | }
838 | }
839 | });
840 | }
841 |
842 | function injectPlugin(module: DojoLoader.Module): void {
843 | // injects the plugin module given by module; may have to inject the plugin itself
844 | const plugin: DojoLoader.Module | undefined = module.plugin;
845 | const onLoad = function(def: any): void {
846 | module.result = def;
847 | --waitingCount;
848 | module.executed = true;
849 | checkComplete();
850 | };
851 |
852 | if (plugin && plugin.load) {
853 | plugin.load(module.prid, module.req, onLoad, config);
854 | } else if (plugin && plugin.loadQ) {
855 | plugin.loadQ.push(module);
856 | } else if (plugin) {
857 | // the unshift instead of push is important: we don't want plugins to execute as
858 | // dependencies of some other module because this may cause circles when the plugin
859 | // loadQ is run; also, generally, we want plugins to run early since they may load
860 | // several other modules and therefore can potentially unblock many modules
861 | plugin.loadQ = [module];
862 | executionQueue.unshift(plugin);
863 | injectModule(module, plugin);
864 | }
865 | }
866 |
867 | function injectModule(parent?: DojoLoader.Module, module?: DojoLoader.Module): void {
868 | // TODO: This is for debugging, we should bracket it
869 | if (!module) {
870 | module = parent;
871 | parent = undefined;
872 | }
873 |
874 | if (module && module.plugin) {
875 | injectPlugin(module);
876 | } else if (module && !module.injected) {
877 | let cached: DojoLoader.Factory;
878 | const onLoadCallback = function(node?: HTMLScriptElement): void {
879 | let moduleDefArgs: string[] = [];
880 | let moduleDefFactory: DojoLoader.Factory | undefined = undefined;
881 |
882 | // non-amd module
883 | if (moduleDefinitionArguments) {
884 | moduleDefArgs = moduleDefinitionArguments[0];
885 | moduleDefFactory = moduleDefinitionArguments[1];
886 | }
887 |
888 | defineModule(module, moduleDefArgs, moduleDefFactory);
889 | moduleDefinitionArguments = undefined;
890 |
891 | guardCheckComplete(function(): void {
892 | forEach((module && module.deps) || [], injectModule.bind(null, module));
893 | });
894 | checkComplete();
895 | };
896 |
897 | ++waitingCount;
898 | module.injected = true;
899 | if ((cached = cache[module.mid])) {
900 | try {
901 | cached();
902 | onLoadCallback();
903 | return;
904 | } catch (error) {
905 | // If a cache load fails, retrieve using injectUrl
906 | // TODO: report error, 'cachedThrew', [ error, module ]
907 | }
908 | }
909 | injectUrl(module.url, onLoadCallback, module, parent);
910 | }
911 | }
912 |
913 | function resolveDependencies(
914 | dependencies: string[],
915 | module: DojoLoader.Module,
916 | referenceModule?: DojoLoader.Module
917 | ): DojoLoader.Module[] {
918 | // resolve dependencies with respect to this module
919 | return dependencies.map(function(dependency: string, i: number): DojoLoader.Module {
920 | const result: DojoLoader.Module = getModule(dependency, referenceModule);
921 | if (result.fix) {
922 | result.fix = function(m: DojoLoader.Module): void {
923 | module.deps[i] = m;
924 | };
925 | }
926 | return result;
927 | });
928 | }
929 |
930 | function defineModule(
931 | module: DojoLoader.Module | undefined,
932 | dependencies: string[],
933 | factory?: DojoLoader.Factory
934 | ): DojoLoader.Module | undefined {
935 | --waitingCount;
936 | return initializeModule(module, dependencies, factory);
937 | }
938 |
939 | function initializeModule(
940 | module: DojoLoader.Module | undefined,
941 | dependencies: string[],
942 | factory?: DojoLoader.Factory
943 | ): DojoLoader.Module | undefined {
944 | const moduleToInitialize = module;
945 | let initializedModule: DojoLoader.Module | undefined = undefined;
946 |
947 | if (moduleToInitialize) {
948 | initializedModule = mix(moduleToInitialize, {
949 | def: factory,
950 | deps: resolveDependencies(dependencies, moduleToInitialize, moduleToInitialize),
951 | cjs: {
952 | id: moduleToInitialize.mid,
953 | uri: moduleToInitialize.url,
954 | exports: (moduleToInitialize.result = {}),
955 | setExports: function(exports: any): void {
956 | moduleToInitialize.cjs.exports = exports;
957 | }
958 | }
959 | });
960 | }
961 | return initializedModule;
962 | }
963 |
964 | has.add('function-bind', Boolean(Function.prototype.bind));
965 | if (!has('function-bind')) {
966 | injectModule.bind = function(thisArg: any): typeof injectModule {
967 | const slice = Array.prototype.slice;
968 | const args: any[] = slice.call(arguments, 1);
969 |
970 | return function(): void {
971 | return injectModule.apply(thisArg, args.concat(slice.call(arguments, 0)));
972 | };
973 | };
974 | }
975 |
976 | let globalObjectGlobals = function(require: DojoLoader.Require, define: DojoLoader.Define): void {
977 | globalObject.require = require;
978 | globalObject.define = define;
979 | };
980 |
981 | if (has('host-node')) {
982 | loadNodeModule = (moduleId: string, parent?: DojoLoader.Module): any => {
983 | let module: any = require('module');
984 | let result: any;
985 |
986 | if (module._findPath && module._nodeModulePaths) {
987 | let localModulePath = module._findPath(moduleId, module._nodeModulePaths(toUrl('.', parent)));
988 |
989 | if (localModulePath !== false) {
990 | moduleId = localModulePath;
991 | }
992 | }
993 |
994 | // Some modules attempt to detect an AMD loader by looking for global AMD `define`. This causes issues
995 | // when other CommonJS modules attempt to load them via the standard Node.js `require`, so hide it
996 | // during the load
997 | globalObject.define = undefined;
998 |
999 | try {
1000 | if (requireModule && requireModule.nodeRequire) {
1001 | result = requireModule.nodeRequire(moduleId);
1002 | }
1003 | } catch (error) {
1004 | throw error;
1005 | } finally {
1006 | globalObject.define = define;
1007 | }
1008 |
1009 | return result;
1010 | };
1011 |
1012 | const vm: any = require('vm');
1013 | const fs: any = require('fs');
1014 |
1015 | // retain the ability to get node's require
1016 | requireModule.nodeRequire = require;
1017 | injectUrl = function(
1018 | url: string,
1019 | callback: (node?: HTMLScriptElement) => void,
1020 | module: DojoLoader.Module,
1021 | parent?: DojoLoader.Module
1022 | ): void {
1023 | fs.readFile(url, 'utf8', function(error: Error, data: string): void {
1024 | function loadCallback() {
1025 | try {
1026 | let result = loadNodeModule(module.mid, parent);
1027 | return result;
1028 | } catch (error) {
1029 | reportModuleLoadError(parent, module, url, error.message);
1030 | }
1031 | }
1032 | if (error) {
1033 | moduleDefinitionArguments = [[], loadCallback];
1034 | } else {
1035 | // global `module` variable needs to be shadowed for UMD modules that are loaded in an Electron
1036 | // webview; in Node.js the `module` variable does not exist when using `vm.runInThisContext`,
1037 | // but in Electron it exists in the webview when Node.js integration is enabled which causes loaded
1038 | // modules to register with Node.js and break the loader
1039 | let oldModule = globalObject.module;
1040 | globalObject.module = undefined;
1041 | try {
1042 | /**
1043 | * Using an `object` as a second argument causes Instabul
1044 | * issues and then thinks the file should not be instrumented
1045 | *
1046 | * See: dojo/loader#57
1047 | */
1048 | vm.runInThisContext(data, url);
1049 | } catch (error) {
1050 | reportModuleLoadError(parent, module, url, error.message);
1051 | } finally {
1052 | globalObject.module = oldModule;
1053 | }
1054 | }
1055 |
1056 | callback();
1057 | });
1058 | };
1059 |
1060 | setGlobals = function(require: DojoLoader.RootRequire, define: DojoLoader.Define): void {
1061 | module.exports = globalObject.require = require;
1062 | globalObject.define = define;
1063 | };
1064 | } else if (has('host-browser')) {
1065 | injectUrl = function(
1066 | url: string,
1067 | callback: (node?: HTMLScriptElement) => void,
1068 | module: DojoLoader.Module,
1069 | parent?: DojoLoader.Module
1070 | ): void {
1071 | // insert a script element to the insert-point element with src=url;
1072 | // apply callback upon detecting the script has loaded.
1073 | const node: HTMLScriptElement = document.createElement('script');
1074 | const handler: EventListener = function(event: Event): void {
1075 | document.head.removeChild(node);
1076 |
1077 | if (event.type === 'load') {
1078 | callback();
1079 | } else {
1080 | reportModuleLoadError(parent, module, url);
1081 | }
1082 | };
1083 |
1084 | node.addEventListener('load', handler, false);
1085 | node.addEventListener('error', handler, false);
1086 |
1087 | if (config.crossOrigin !== false) {
1088 | (node).crossOrigin = config.crossOrigin;
1089 | }
1090 |
1091 | node.charset = 'utf-8';
1092 | node.src = url;
1093 | document.head.appendChild(node);
1094 | };
1095 |
1096 | setGlobals = globalObjectGlobals;
1097 | } else if (has('host-nashorn')) {
1098 | injectUrl = function(
1099 | url: string,
1100 | callback: (node?: HTMLScriptElement) => void,
1101 | module: DojoLoader.Module,
1102 | parent?: DojoLoader.Module
1103 | ): void {
1104 | load(url);
1105 | callback();
1106 | };
1107 |
1108 | setGlobals = globalObjectGlobals;
1109 | } else if (has('host-web-worker')) {
1110 | injectUrl = function(
1111 | url: string,
1112 | callback: (node?: HTMLScriptElement) => void,
1113 | module: DojoLoader.Module,
1114 | parent?: DojoLoader.Module
1115 | ): void {
1116 | try {
1117 | importScripts(url);
1118 | } catch (e) {
1119 | reportModuleLoadError(parent, module, url);
1120 | }
1121 | callback();
1122 | };
1123 |
1124 | setGlobals = globalObjectGlobals;
1125 | } else {
1126 | throw new Error('Unsupported platform');
1127 | }
1128 |
1129 | has.add('loader-debug-internals', true);
1130 | if (has('loader-debug-internals')) {
1131 | requireModule.inspect = function(name: string): any {
1132 | /* tslint:disable:no-eval */
1133 | // TODO: Should this use console.log so people do not get any bright ideas about using this in apps?
1134 | return eval(name);
1135 | /* tslint:enable:no-eval */
1136 | };
1137 | }
1138 |
1139 | has.add('loader-undef', true);
1140 | if (has('loader-undef')) {
1141 | requireModule.undef = function(id: string, recursive?: boolean): void {
1142 | const module: Module | undefined = modules[id];
1143 | const undefDeps = function(mod: Module): void {
1144 | if (mod === commonJsRequireModule || mod === commonJsModuleModule || mod === commonJsExportsModule) {
1145 | return;
1146 | }
1147 | if (mod.deps) {
1148 | forEach(mod.deps, undefDeps);
1149 | }
1150 |
1151 | modules[mod.mid] = undefined;
1152 | };
1153 | if (module) {
1154 | if (recursive && module.deps) {
1155 | forEach(module.deps, undefDeps);
1156 | }
1157 | delete modules[module.mid];
1158 | delete cache[module.mid];
1159 | }
1160 | };
1161 | }
1162 |
1163 | mix(requireModule, {
1164 | toAbsMid: toAbsMid,
1165 | toUrl: toUrl,
1166 |
1167 | cache: function(cacheModules: DojoLoader.ObjectMap): void {
1168 | let item: any;
1169 |
1170 | for (let key in cacheModules) {
1171 | item = cacheModules[key];
1172 |
1173 | cache[getModuleInformation(key, undefined).mid] = item;
1174 | }
1175 | }
1176 | });
1177 |
1178 | Object.defineProperty(requireModule, 'baseUrl', {
1179 | get: function(): string | undefined {
1180 | return config.baseUrl;
1181 | },
1182 | enumerable: true
1183 | });
1184 |
1185 | has.add('loader-cjs-wrapping', true);
1186 |
1187 | let comments: RegExp;
1188 | let requireCall: RegExp;
1189 |
1190 | if (has('loader-cjs-wrapping')) {
1191 | comments = /\/\*[\s\S]*?\*\/|\/\/.*$/gm;
1192 | requireCall = /require\s*\(\s*(["'])(.*?[^\\])\1\s*\)/g;
1193 | }
1194 |
1195 | has.add('loader-explicit-mid', true);
1196 |
1197 | /**
1198 | * @param deps //(array of commonjs.moduleId, optional)
1199 | * @param factory //(any)
1200 | */
1201 | let define: DojoLoader.Define = mix(
1202 | function(dependencies: string[], factory: DojoLoader.Factory): void {
1203 | let originalFactory: any;
1204 | if (has('loader-explicit-mid') && arguments.length > 1 && typeof dependencies === 'string') {
1205 | let id: string = dependencies;
1206 | if (arguments.length === 3) {
1207 | dependencies = factory;
1208 | factory = arguments[2];
1209 | } else {
1210 | dependencies = [];
1211 | }
1212 |
1213 | // Some modules in the wild have an explicit module ID that is null; ignore the module ID in this case and
1214 | // register normally using the request module ID
1215 | if (id != null) {
1216 | let module: DojoLoader.Module = getModule(id);
1217 | if (factory) {
1218 | originalFactory = factory;
1219 | factory = function() {
1220 | module.executed = true;
1221 | return (module.result = originalFactory.apply
1222 | ? originalFactory.apply(null, arguments)
1223 | : originalFactory);
1224 | };
1225 | }
1226 | module.injected = true;
1227 | defineModule(module, dependencies, factory);
1228 | guardCheckComplete(function(): void {
1229 | forEach(module.deps, injectModule.bind(null, module));
1230 | });
1231 | }
1232 | }
1233 |
1234 | if (arguments.length === 1) {
1235 | if (has('loader-cjs-wrapping') && typeof dependencies === 'function') {
1236 | originalFactory = dependencies;
1237 | dependencies = ['require', 'exports', 'module'];
1238 |
1239 | // Scan factory for require() calls and add them to the
1240 | // list of dependencies
1241 | originalFactory
1242 | .toString()
1243 | .replace(comments, '')
1244 | .replace(requireCall, function(): string {
1245 | dependencies.push(/* mid */ arguments[2]);
1246 | return arguments[0];
1247 | });
1248 | factory = function(require, exports, module): any {
1249 | const originalModuleId = module.id;
1250 | let result: any = originalFactory.apply(null, arguments);
1251 | if (originalModuleId !== module.id) {
1252 | const newModule: DojoLoader.Module = getModule(module.id);
1253 | defineModule(newModule, dependencies, undefined);
1254 | newModule.injected = true;
1255 | newModule.executed = true;
1256 | newModule.result = module.exports = result || module.exports;
1257 | }
1258 | return result;
1259 | };
1260 | } else if (/* define(value) */ !Array.isArray(dependencies)) {
1261 | const value: any = dependencies;
1262 | dependencies = [];
1263 | factory = function(): any {
1264 | return value;
1265 | };
1266 | }
1267 | }
1268 |
1269 | moduleDefinitionArguments = [dependencies, factory];
1270 | },
1271 | {
1272 | amd: { vendor: 'dojotoolkit.org' }
1273 | }
1274 | );
1275 |
1276 | setGlobals(requireModule, define);
1277 | if (has('host-nashorn') && args && args[0]) {
1278 | load(args[0]);
1279 | }
1280 | })(typeof Packages !== 'undefined' ? Array.prototype.slice.call(arguments, 0) : []);
1281 |
--------------------------------------------------------------------------------
/tests/common/a/app.js:
--------------------------------------------------------------------------------
1 | define([], 'app A');
2 |
--------------------------------------------------------------------------------
/tests/common/a/map2.js:
--------------------------------------------------------------------------------
1 | define([
2 | 'mapped/app'
3 | ], function (app) {
4 | return {
5 | app: app
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/tests/common/a/relative1.js:
--------------------------------------------------------------------------------
1 | define([
2 | './app'
3 | ], function (app) {
4 | return {
5 | app: app
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/tests/common/a/remappedApp.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../app'
3 | ], function (app) {
4 | return 'remapped' + app;
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/amd/onlyFactory.js:
--------------------------------------------------------------------------------
1 | define(function () {
2 | return {
3 | property: 'value'
4 | };
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/app.js:
--------------------------------------------------------------------------------
1 | define([], 'app');
2 |
--------------------------------------------------------------------------------
/tests/common/commonJs/Deep2.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | var deep3 = require('./deep3');
3 |
4 | function Deep2() {}
5 |
6 | Deep2.prototype.deep3 = function () {
7 | return deep3();
8 | };
9 |
10 | module.exports = Deep2;
11 | });
12 |
--------------------------------------------------------------------------------
/tests/common/commonJs/app.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports) {
2 | exports.getMessage = function () {
3 | return 'Message from CommonJS app.';
4 | };
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/commonJs/app1.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | var testModule1 = require('test/module1');
3 |
4 | exports.getMessage = function () {
5 | return testModule1;
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/tests/common/commonJs/circular1.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports) {
2 | var circular2 = require('./circular2');
3 |
4 | exports.getMessage = function () {
5 | return 'circular1';
6 | };
7 |
8 | exports.circular2Message = function () {
9 | return circular2.getMessage();
10 | };
11 | });
12 |
--------------------------------------------------------------------------------
/tests/common/commonJs/circular2.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports) {
2 | var circular1 = require('./circular1');
3 |
4 | exports.getMessage = function () {
5 | return 'circular2';
6 | };
7 |
8 | exports.circular1Message = function() {
9 | return circular1.getMessage();
10 | };
11 | });
12 |
--------------------------------------------------------------------------------
/tests/common/commonJs/deep1.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | var Deep2 = require('./Deep2');
3 |
4 | module.exports = function () {
5 | return new Deep2();
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/tests/common/commonJs/deep3.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | var deep4 = require('./deep4');
3 |
4 | module.exports = function () {
5 | return deep4;
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/tests/common/commonJs/deep4.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | module.exports = {
3 | objectExport: 'objectExport'
4 | };
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/commonJs/testModule1.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | module.exports = 'testModule1';
3 | module.id = 'test/module1';
4 | });
5 |
--------------------------------------------------------------------------------
/tests/common/commonJs/testModule2.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | var testModule1 = require('test/module1');
3 |
4 | module.exports = {
5 | testModule1Value: testModule1,
6 | testModule2Value: 'testModule2'
7 | };
8 |
9 | module.id = 'test/module2';
10 | });
11 |
--------------------------------------------------------------------------------
/tests/common/commonJs/testModule3.js:
--------------------------------------------------------------------------------
1 | define(function (require, exports, module) {
2 | var app = require('./app');
3 |
4 | module.exports = {
5 | appModuleValue: app.getMessage(),
6 | testModule3Value: 'testModule3'
7 | };
8 |
9 | module.id = 'test/module3';
10 | });
11 |
--------------------------------------------------------------------------------
/tests/common/map1.js:
--------------------------------------------------------------------------------
1 | define([
2 | 'mapped/app'
3 | ], function (app) {
4 | return {
5 | app: app
6 | };
7 | });
8 |
--------------------------------------------------------------------------------
/tests/common/plugin.js:
--------------------------------------------------------------------------------
1 | define({
2 | load: function (name, require, loaded) {
3 | loaded(name);
4 | }
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/pluginConfig.js:
--------------------------------------------------------------------------------
1 | define({
2 | load: function (name, require, loaded, config) {
3 | loaded(config);
4 | }
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/recursive/a.js:
--------------------------------------------------------------------------------
1 | define([
2 | './b'
3 | ], function (b) {
4 | return 'a';
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/recursive/b.js:
--------------------------------------------------------------------------------
1 | define([
2 | './c',
3 | './d'
4 | ], function (c) {
5 | return 'b';
6 | });
7 |
--------------------------------------------------------------------------------
/tests/common/recursive/c.js:
--------------------------------------------------------------------------------
1 | define([], 'c');
2 |
--------------------------------------------------------------------------------
/tests/common/recursive/d.js:
--------------------------------------------------------------------------------
1 | define([
2 | './e'
3 | ], function (e) {
4 | return 'd';
5 | });
6 |
--------------------------------------------------------------------------------
/tests/common/recursive/e.js:
--------------------------------------------------------------------------------
1 | define([], 'e');
2 |
--------------------------------------------------------------------------------
/tests/common/usesApp.js:
--------------------------------------------------------------------------------
1 | define([
2 | './app'
3 | ], function (app) {
4 | return app;
5 | });
6 |
--------------------------------------------------------------------------------
/tests/functional/all.ts:
--------------------------------------------------------------------------------
1 | import './basicAmdLoading';
2 | import './basicCommonJsLoading';
3 | import './crossOrigin';
4 | import './csp';
5 | import './scriptConfigReading';
6 | import './shimAmdLoading';
7 | import './webworkerAmd';
8 | import './require/require';
9 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/Deep2.ts:
--------------------------------------------------------------------------------
1 | import deep3, { Deep4 } from './deep3';
2 |
3 | class Deep2 {
4 | deep3(): Deep4 {
5 | return deep3();
6 | }
7 | }
8 |
9 | export default Deep2;
10 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/app.ts:
--------------------------------------------------------------------------------
1 | export function getMessage() {
2 | return 'Message from AMD app.';
3 | }
4 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/app1.js:
--------------------------------------------------------------------------------
1 | define([
2 | 'test/module1'
3 | ], function (testModule1) {
4 | return {
5 | getMessage: function () {
6 | return testModule1;
7 | }
8 | };
9 | });
10 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/circular1.ts:
--------------------------------------------------------------------------------
1 | import circular2 from './circular2';
2 |
3 | export default function(): string {
4 | return circular2();
5 | }
6 |
7 | export function getMessage(): string {
8 | return 'circular1.getMessage';
9 | }
10 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/circular2.ts:
--------------------------------------------------------------------------------
1 | import { getMessage as circular1Message } from './circular1';
2 |
3 | export default function(): string {
4 | return 'circular2';
5 | }
6 |
7 | export function getMessage(): string {
8 | return circular1Message();
9 | }
10 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/crossOrigin.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var scripts = document.getElementsByTagName('script'), i;
3 |
4 | for (i = 0; i < scripts.length; i++) {
5 | var script = scripts[i];
6 |
7 | if (script.src && script.src.indexOf('crossOrigin.js') >= 0) {
8 | window.crossOriginResult = {
9 | node: script,
10 | value: script.crossOrigin || 'null'
11 | };
12 | }
13 | }
14 | })();
15 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/deep1.ts:
--------------------------------------------------------------------------------
1 | import Deep2 from './Deep2';
2 | import { Deep4 } from './deep3';
3 |
4 | export default function(): Deep2 {
5 | return new Deep2();
6 | }
7 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/deep3.ts:
--------------------------------------------------------------------------------
1 | import deep4 from './deep4';
2 |
3 | export type Deep4 = typeof deep4;
4 |
5 | export default function(): Deep4 {
6 | return deep4;
7 | }
8 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/deep4.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | objectExport: 'objectExport'
3 | };
4 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/module1.js:
--------------------------------------------------------------------------------
1 | define('test/module1', [], function () {
2 | return 'testModule1';
3 | });
4 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/module2.js:
--------------------------------------------------------------------------------
1 | define('test/module2', [
2 | 'test/module1'
3 | ], function (testModule1) {
4 | return {
5 | testModule1Value: testModule1,
6 | testModule2Value: 'testModule2'
7 | };
8 | });
9 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/module3.js:
--------------------------------------------------------------------------------
1 | define('test/module3', [
2 | 'amdApp/app'
3 | ], function (app) {
4 | return {
5 | appModuleValue: app.getMessage(),
6 | testModule3Value: 'testModule3'
7 | };
8 | });
9 |
--------------------------------------------------------------------------------
/tests/functional/amdApp/module4.js:
--------------------------------------------------------------------------------
1 | define({
2 | aModuleProperty: 'a property value'
3 | });
4 |
--------------------------------------------------------------------------------
/tests/functional/amdFactoryOnly.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic AMD Loading Test
6 |
7 |
8 |
9 |
10 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleCircular.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleCircular2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleCircular3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleDeepDeps.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId1a.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId2a.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId3a.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId4a.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId6.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/tests/functional/amdModuleWithId6a.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD Loading Test
6 |
7 |
8 |
9 |
10 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/tests/functional/basicAmdLoading.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic AMD Loading Test
6 |
7 |
8 |
9 |
10 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/tests/functional/basicAmdLoading.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import executeTest from './executeTest';
5 |
6 | const AMD_APP_MESSAGE = 'Message from AMD app.';
7 |
8 | registerSuite('basic AMD loading', {
9 | 'simple test'() {
10 | return executeTest(this, require, './basicAmdLoading.html', function(results: any) {
11 | assert.strictEqual(results.message, AMD_APP_MESSAGE);
12 | });
13 | },
14 |
15 | 'AMD module with ID'() {
16 | return executeTest(this, require, './amdModuleWithId1.html', function(results: any) {
17 | assert.strictEqual(results.testModule1Value, 'testModule1', 'Test module should load');
18 | });
19 | },
20 |
21 | 'AMD module with ID - separate module file'() {
22 | return executeTest(this, require, './amdModuleWithId1a.html', function(results: any) {
23 | assert.strictEqual(results.testModule1Value, 'testModule1', 'Test module should load');
24 | });
25 | },
26 |
27 | 'AMD module with ID and dependency - ID'() {
28 | return executeTest(this, require, './amdModuleWithId2.html', function(results: any) {
29 | assert.strictEqual(results.testModule1Value, 'testModule1', 'Dependency module should load');
30 | assert.strictEqual(results.testModule2Value, 'testModule2', 'Test module should load');
31 | });
32 | },
33 |
34 | 'AMD module with ID and dependency - ID and separate module files'() {
35 | return executeTest(this, require, './amdModuleWithId2a.html', function(results: any) {
36 | assert.strictEqual(results.testModule1Value, 'testModule1', 'Dependency module should load');
37 | assert.strictEqual(results.testModule2Value, 'testModule2', 'Test module should load');
38 | });
39 | },
40 |
41 | 'AMD module with ID and dependency - module'() {
42 | return executeTest(this, require, './amdModuleWithId3.html', function(results: any) {
43 | assert.strictEqual(results.appModuleValue, AMD_APP_MESSAGE, 'Test module and dependency should load');
44 | assert.strictEqual(results.testModule3Value, 'testModule3', 'Test module and dependency should load');
45 | });
46 | },
47 |
48 | 'AMD module with ID and dependency - module and separate module files'() {
49 | return executeTest(this, require, './amdModuleWithId3a.html', function(results: any) {
50 | assert.strictEqual(results.appModuleValue, AMD_APP_MESSAGE, 'Test module and dependency should load');
51 | assert.strictEqual(results.testModule3Value, 'testModule3', 'Test module and dependency should load');
52 | });
53 | },
54 |
55 | 'AMD module without ID and dependency - id'() {
56 | return executeTest(this, require, './amdModuleWithId4.html', function(results: any) {
57 | assert.strictEqual(results, 'testModule1', 'Test module and dependency should load');
58 | });
59 | },
60 |
61 | 'AMD module without ID and dependency - id and separate module files'() {
62 | return executeTest(this, require, './amdModuleWithId4a.html', function(results: any) {
63 | assert.strictEqual(results, 'testModule1', 'Test module and dependency should load');
64 | });
65 | },
66 |
67 | 'AMD module with ID - dependency param omitted'() {
68 | return executeTest(this, require, './amdModuleWithId5.html', function(results: any) {
69 | assert.strictEqual(results.testModule1Value, 'testModule1', 'Test module should load');
70 | });
71 | },
72 |
73 | 'AMD module with ID - no dependencies - object returned'() {
74 | return executeTest(this, require, './amdModuleWithId6.html', function(results: any) {
75 | assert.strictEqual(results.testModuleProperty, 'property value', 'Test module should load');
76 | });
77 | },
78 |
79 | 'AMD module without ID and dependency - separate module file - object returned'() {
80 | return executeTest(this, require, './amdModuleWithId6a.html', function(results: any) {
81 | assert.strictEqual(results.aModuleProperty, 'a property value', 'Test module should load');
82 | });
83 | },
84 |
85 | 'AMD module with circular dependency'() {
86 | const expected = {
87 | default: 'circular2',
88 | message: 'circular1.getMessage'
89 | };
90 |
91 | return executeTest(this, require, './amdModuleCircular.html', function(results: any) {
92 | assert.deepEqual(results, expected, 'Circular dependency should be resolved');
93 | });
94 | },
95 |
96 | 'AMD module with circular dependency 2'() {
97 | const expected = {
98 | default: 'circular2',
99 | message: 'circular1.getMessage'
100 | };
101 |
102 | return executeTest(this, require, './amdModuleCircular2.html', function(results: any) {
103 | assert.deepEqual(results, expected, 'Circular dependency should be resolved');
104 | });
105 | },
106 |
107 | 'AMD module with circular dependency 3'() {
108 | const expected = {
109 | c1default: 'circular2',
110 | c1message: 'circular1.getMessage',
111 | c2default: 'circular2',
112 | c2message: 'circular1.getMessage'
113 | };
114 |
115 | return executeTest(this, require, './amdModuleCircular3.html', function(results: any) {
116 | assert.deepEqual(results, expected, 'Circular dependency should be resolved');
117 | });
118 | },
119 |
120 | 'AMD module with deep dependencies'() {
121 | const expected = {
122 | objectExport: 'objectExport'
123 | };
124 |
125 | return executeTest(this, require, './amdModuleDeepDeps.html', function(results: any) {
126 | assert.deepEqual(results, expected, 'Deep dependency should be resolved');
127 | });
128 | },
129 |
130 | 'AMD only factory require'() {
131 | const expected = {
132 | property: 'value'
133 | };
134 | return executeTest(this, require, './amdFactoryOnly.html', function(results: any) {
135 | assert.deepEqual(results, expected, 'Factory only should be resolved');
136 | });
137 | }
138 | });
139 |
--------------------------------------------------------------------------------
/tests/functional/basicCommonJsLoading.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tests/functional/basicCommonJsLoading.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import executeTest from './executeTest';
5 |
6 | const COMMON_JS_APP_MESSAGE = 'Message from CommonJS app.';
7 |
8 | registerSuite('browser - basic CommonJS loading', {
9 | 'simple test'() {
10 | return executeTest(this, require, './basicCommonJsLoading.html', function(results: any) {
11 | assert.strictEqual(results.message, COMMON_JS_APP_MESSAGE);
12 | });
13 | },
14 |
15 | 'CommonJS module with ID'() {
16 | return executeTest(this, require, './commonJsModuleWithId1.html', function(results: any) {
17 | assert.strictEqual(results.testModule1Value, 'testModule1', 'Test module with explicit mid should load');
18 | });
19 | },
20 |
21 | 'CommonJS module with ID and dependency - ID'() {
22 | const expected = {
23 | testModule1Value: 'testModule1',
24 | testModule2Value: 'testModule2'
25 | };
26 |
27 | return executeTest(this, require, './commonJsModuleWithId2.html', function(results: any) {
28 | assert.deepEqual(results, expected, 'Test modules with explicit mids should load');
29 | });
30 | },
31 |
32 | 'CommonJS module with ID and dependency - module'() {
33 | const expected = {
34 | appModuleValue: COMMON_JS_APP_MESSAGE,
35 | testModule3Value: 'testModule3'
36 | };
37 |
38 | return executeTest(this, require, './commonJsModuleWithId3.html', function(results: any) {
39 | assert.deepEqual(results, expected, 'Test module and dependency should load');
40 | });
41 | },
42 |
43 | 'CommonJS module without ID and dependency - id'() {
44 | return executeTest(this, require, './commonJsModuleWithId4.html', function(results: any) {
45 | assert.strictEqual(results, 'testModule1', 'Test module and dependency should load');
46 | });
47 | },
48 |
49 | 'CommonJS module with circular dependency'() {
50 | const expected = {
51 | message: 'circular1',
52 | circular2Message: 'circular2'
53 | };
54 |
55 | return executeTest(this, require, './commonJsModuleCircular.html', function(results: any) {
56 | assert.deepEqual(results, expected, 'Circular dependency should be resolved');
57 | });
58 | },
59 |
60 | 'CommonJS module with circular dependency 2'() {
61 | const expected = {
62 | message: 'circular2',
63 | circular1Message: 'circular1'
64 | };
65 |
66 | return executeTest(this, require, './commonJsModuleCircular2.html', function(results: any) {
67 | assert.deepEqual(results, expected, 'Circular dependency should be resolved');
68 | });
69 | },
70 |
71 | 'CommonJS module with circular dependency 3'() {
72 | const expected = {
73 | c1message: 'circular1',
74 | c1message2: 'circular2',
75 | c2message: 'circular2',
76 | c2message1: 'circular1'
77 | };
78 |
79 | return executeTest(this, require, './commonJsModuleCircular3.html', function(results: any) {
80 | assert.deepEqual(results, expected, 'Circular dependency should be resolved');
81 | });
82 | },
83 |
84 | 'CommonJS module with deep dependencies'() {
85 | const expected = {
86 | objectExport: 'objectExport'
87 | };
88 |
89 | return executeTest(this, require, './commonJsModuleDeepDeps.html', function(results: any) {
90 | assert.deepEqual(results, expected, 'Deep dependency should be resolved');
91 | });
92 | }
93 | });
94 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleCircular.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleCircular2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleCircular3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleDeepDeps.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleWithId1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleWithId2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleWithId3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tests/functional/commonJsModuleWithId4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CommonJS Loading Test
6 |
7 |
8 |
9 |
10 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/tests/functional/crossOrigin.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import executeTest from './executeTest';
5 |
6 | registerSuite('Cross origin configuration', {
7 | 'cross origin false'() {
8 | return executeTest(this, require, './crossOriginFalse.html', function(results: any) {
9 | assert.strictEqual(results.message, 'The cross origin value is null');
10 | });
11 | },
12 | 'cross origin anonymous'() {
13 | return executeTest(this, require, './crossOriginAnon.html', function(results: any) {
14 | assert.strictEqual(results.message, 'The cross origin value is anonymous');
15 | });
16 | },
17 | 'cross origin use-credentials'() {
18 | return executeTest(this, require, './crossOriginCreds.html', function(results: any) {
19 | assert.strictEqual(results.message, 'The cross origin value is use-credentials');
20 | });
21 | }
22 | });
23 |
--------------------------------------------------------------------------------
/tests/functional/crossOriginAnon.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic AMD Loading Test
6 |
7 |
8 |
9 |
10 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/functional/crossOriginCreds.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic AMD Loading Test
6 |
7 |
8 |
9 |
10 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/functional/crossOriginFalse.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic AMD Loading Test
6 |
7 |
8 |
9 |
10 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/functional/csp-cdn.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | CSP with CDN Test
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tests/functional/csp-cdn.ts:
--------------------------------------------------------------------------------
1 | require.config({
2 | packages: [
3 | { name: 'amdApp', location: './amdApp' },
4 | { name: 'dojo', location: '//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo' }
5 | ]
6 | });
7 |
8 | require(['amdApp/app', 'dojo/debounce'], function(app, debounce) {
9 | window.location.href = 'csp-success.html#' + typeof debounce;
10 | });
11 |
--------------------------------------------------------------------------------
/tests/functional/csp-simple.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Basic CSP Test
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tests/functional/csp-simple.ts:
--------------------------------------------------------------------------------
1 | require.config({
2 | packages: [{ name: 'amdApp', location: './amdApp' }]
3 | });
4 |
5 | require(['amdApp/app'], function(app) {
6 | window.location.href = 'csp-success.html';
7 | });
8 |
--------------------------------------------------------------------------------
/tests/functional/csp-success.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Basic CSP Success
6 |
7 |
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/tests/functional/csp.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import executeTest from './executeTest';
5 | import Node from 'intern/lib/executors/Node';
6 |
7 | const amdAppMessage = 'Success';
8 |
9 | let oldShouldInstrument: any;
10 |
11 | /**
12 | * Gotchas for CSP testing
13 | *
14 | * - Selenium Drivers aren't able to inject scripts in most cases, as that violates the CSP rules, so
15 | * the general process is:
16 | *
17 | * - Load HTML page with CSP enabled
18 | * - Load the loader with CSP enabled
19 | * - Load test module with CSP enabled
20 | * - The module, on load, redirects the location to a non-CSP page
21 | * - The final results are read from this non-CSP page
22 | *
23 | * - CSP does not work with instrumentation enabled, but, we want instrumentation in all other cases. As such, we need
24 | * to disable instrumentation for this suite, and re-enable it afterwards. There is no public API for this, so we need
25 | * to perform some Intern wizardry.
26 | */
27 | registerSuite('AMD loading with CSP enabled', {
28 | before() {
29 | oldShouldInstrument = (this.executor).shouldInstrumentFile;
30 | (this.executor).shouldInstrumentFile = (_filename: string) => false;
31 | },
32 |
33 | after() {
34 | (this.executor).shouldInstrumentFile = oldShouldInstrument;
35 | },
36 |
37 | tests: {
38 | simple() {
39 | if (this.remote.session.capabilities.browserName === 'MicrosoftEdge') {
40 | this.skip('CSP tests do not work in Edge');
41 | }
42 |
43 | return executeTest(this, require, './csp-simple.html', function(results: any) {
44 | assert.strictEqual(results.message, amdAppMessage, 'Local module should load');
45 | });
46 | },
47 |
48 | cdn() {
49 | if (this.remote.session.capabilities.browserName === 'MicrosoftEdge') {
50 | this.skip('CSP tests do not work in Edge');
51 | }
52 |
53 | const expected = {
54 | message: amdAppMessage,
55 | debounce: '#function'
56 | };
57 |
58 | return executeTest(this, require, './csp-cdn.html', function(results: any) {
59 | assert.deepEqual(results, expected, 'Local module and CDN module should load');
60 | });
61 | }
62 | }
63 | });
64 |
--------------------------------------------------------------------------------
/tests/functional/executeTest.ts:
--------------------------------------------------------------------------------
1 | import Test from 'intern/lib/Test';
2 | import Command from '@theintern/leadfoot/Command';
3 | import pollUntil from '@theintern/leadfoot/helpers/pollUntil';
4 |
5 | export default function(
6 | test: Test,
7 | require: NodeRequire,
8 | htmlTestPath: string,
9 | testFunction: (result: any) => void,
10 | timeout = 10000
11 | ): Command {
12 | return test.remote
13 | .get(require.resolve(htmlTestPath))
14 | .then(
15 | pollUntil(
16 | function() {
17 | return (window).loaderTestResults;
18 | },
19 | undefined,
20 | timeout
21 | ),
22 | undefined
23 | )
24 | .then(testFunction, function() {
25 | throw new Error('loaderTestResult was not set.');
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/tests/functional/map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config map Test
6 |
7 |
8 |
9 |
10 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/functional/require/config/baseUrl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/tests/functional/require/config/defaultConfig.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/tests/functional/require/config/map-hierarchy.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/tests/functional/require/config/map-merge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/tests/functional/require/config/map-nested.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/tests/functional/require/config/map-plugin.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/functional/require/config/map-relative.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/functional/require/config/map-simple.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/tests/functional/require/config/map-star.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/functional/require/config/packages1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/tests/functional/require/config/packages2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/tests/functional/require/config/packages3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/tests/functional/require/config/packages4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/functional/require/config/paths1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tests/functional/require/config/pkg/main.js:
--------------------------------------------------------------------------------
1 | define([
2 | '../../../../common/app'
3 | ], function (app) {
4 | return app;
5 | });
6 |
--------------------------------------------------------------------------------
/tests/functional/require/has.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.has Test
6 |
7 |
8 |
9 |
10 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/tests/functional/require/on/error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.undef Test
6 |
7 |
8 |
9 |
10 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/tests/functional/require/on/remove.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.undef Test
6 |
7 |
8 |
9 |
10 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/tests/functional/require/plugin-config.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/tests/functional/require/plugin-load.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.config Test
6 |
7 |
8 |
9 |
10 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/tests/functional/require/require.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import Test from 'intern/lib/Test';
5 | import Command from '@theintern/leadfoot/Command';
6 | import pollUntil from '@theintern/leadfoot/helpers/pollUntil';
7 |
8 | function executeTest(suite: Test, htmlTestPath: string, testFn: (result: any) => void, timeout = 5000): Command {
9 | return suite.remote
10 | .get(require.resolve(htmlTestPath))
11 | .then(
12 | pollUntil(
13 | function() {
14 | return (window).loaderTestResults;
15 | },
16 | undefined,
17 | timeout
18 | ),
19 | undefined
20 | )
21 | .then(testFn, function() {
22 | throw new Error('loaderTestResult was not set.');
23 | });
24 | }
25 |
26 | const appMessage = 'app';
27 |
28 | registerSuite('browser - require', {
29 | config: {
30 | baseUrl: {
31 | default(this: any) {
32 | return executeTest(this, './config/defaultConfig.html', function(results: any) {
33 | assert.strictEqual(results, appMessage, '"app" module should load');
34 | });
35 | },
36 |
37 | explicit(this: any) {
38 | return executeTest(this, './config/baseUrl.html', function(results: any) {
39 | assert.strictEqual(results, appMessage, '"app" module should load');
40 | });
41 | }
42 | },
43 |
44 | map: {
45 | star(this: any) {
46 | return executeTest(this, './config/map-star.html', function(results: any) {
47 | assert.strictEqual(results, appMessage, '"app" module should load');
48 | });
49 | },
50 |
51 | simple(this: any) {
52 | return executeTest(this, './config/map-simple.html', function(results: any) {
53 | assert.strictEqual(results.app, appMessage, '"map1" module and dependency should load');
54 | });
55 | },
56 |
57 | hierarchy(this: any) {
58 | return executeTest(this, './config/map-hierarchy.html', function(results: any) {
59 | assert.strictEqual(results.app, 'app A', '"map2" module and dependency should load');
60 | });
61 | },
62 |
63 | merge(this: any) {
64 | return executeTest(this, './config/map-merge.html', function(results: any) {
65 | assert.strictEqual(results.map1App, appMessage, '"map1" module and dependency should load');
66 | assert.strictEqual(results.map2App, 'app A', '"map2" module and dependency should load');
67 | });
68 | },
69 |
70 | relative(this: any) {
71 | return executeTest(this, './config/map-relative.html', function(results: any) {
72 | assert.strictEqual(
73 | results.app,
74 | appMessage,
75 | '"relative1" module and dependency "common/app" should load'
76 | );
77 | });
78 | },
79 |
80 | nested(this: any) {
81 | return executeTest(this, './config/map-nested.html', function(results: any) {
82 | assert.strictEqual(
83 | results.app,
84 | 'remappedapp',
85 | '"usesApp" module should get remapped "a/remappedApp" module'
86 | );
87 | assert.strictEqual(
88 | results.remappedApp,
89 | 'remappedapp',
90 | '"remappedApp" module should get unmapped "app" module'
91 | );
92 | });
93 | },
94 |
95 | plugin(this: any) {
96 | return executeTest(this, './config/map-plugin.html', function(results: any) {
97 | assert.strictEqual(results.plugin1, 'one', 'Plug-in module should load');
98 | assert.strictEqual(results.plugin2, 'two', 'Plug-in module should load');
99 | });
100 | }
101 | },
102 |
103 | packages: {
104 | 'name and location'(this: any) {
105 | return executeTest(this, './config/packages1.html', function(results: any) {
106 | assert.strictEqual(results, appMessage, '"app" module should load');
107 | });
108 | },
109 |
110 | 'name, location and main'(this: any) {
111 | return executeTest(this, './config/packages2.html', function(results: any) {
112 | assert.strictEqual(results, appMessage, '"app" module should load');
113 | });
114 | },
115 |
116 | 'package name with slashes'(this: any) {
117 | return executeTest(this, './config/packages3.html', function(results: any) {
118 | assert.strictEqual(results, appMessage, '"app" module should load');
119 | });
120 | },
121 |
122 | 'nested packages'(this: any) {
123 | return executeTest(this, './config/packages4.html', function(results: any) {
124 | assert.strictEqual(results, appMessage, '"app" module should load');
125 | });
126 | }
127 | },
128 |
129 | paths: {
130 | simple(this: any) {
131 | return executeTest(this, './config/paths1.html', function(results: any) {
132 | assert.strictEqual(results, appMessage, '"app" module should load');
133 | });
134 | }
135 | }
136 | },
137 |
138 | plugin: {
139 | load(this: any) {
140 | return executeTest(this, './plugin-load.html', function(results: any) {
141 | assert.strictEqual(results, 'one', 'Plug-in module should load');
142 | });
143 | },
144 | config(this: any) {
145 | return executeTest(this, './plugin-config.html', function(results: any) {
146 | if (results !== 'success') {
147 | assert.fail(null, null, results);
148 | }
149 | });
150 | }
151 | },
152 |
153 | has(this: any) {
154 | return executeTest(this, './has.html', function(results: any) {
155 | if (results !== 'success') {
156 | assert.fail(null, null, results);
157 | }
158 | });
159 | },
160 |
161 | toAbsMid(this: any) {
162 | return executeTest(this, './toAbsMid.html', function(results: any) {
163 | if (results !== 'success') {
164 | assert.fail(null, null, results);
165 | }
166 | });
167 | },
168 |
169 | toUrl(this: any) {
170 | return executeTest(this, './toUrl.html', function(results: any) {
171 | if (results !== 'success') {
172 | assert.fail(null, null, results);
173 | }
174 | });
175 | },
176 |
177 | undef(this: any) {
178 | return executeTest(this, './undef.html', function(results: any) {
179 | if (results !== 'success') {
180 | assert.fail(null, null, results);
181 | }
182 | });
183 | },
184 |
185 | on: {
186 | error(this: any) {
187 | return executeTest(this, './on/error.html', function(results: any) {
188 | if (results !== 'success') {
189 | assert.fail(null, null, results);
190 | }
191 | });
192 | },
193 |
194 | remove(this: any) {
195 | return executeTest(this, './on/remove.html', function(results: any) {
196 | if (results !== 'success') {
197 | assert.fail(null, null, results);
198 | }
199 | });
200 | }
201 | }
202 | });
203 |
--------------------------------------------------------------------------------
/tests/functional/require/toAbsMid.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.toAbsMid Test
6 |
7 |
8 |
9 |
10 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/tests/functional/require/toUrl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.toUrl Test
6 |
7 |
8 |
9 |
10 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/tests/functional/require/undef.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | require.undef Test
6 |
7 |
8 |
9 |
10 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/tests/functional/scriptConfigReading.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Script Config Reading Test
6 |
7 |
8 |
9 |
10 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tests/functional/scriptConfigReading.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import executeTest from './executeTest';
5 |
6 | const AMD_APP_MESSAGE = 'Message from AMD app.';
7 |
8 | registerSuite('Script tag configuration', {
9 | 'script tag config'() {
10 | return executeTest(this, require, './scriptConfigReading.html', function(results: any) {
11 | assert.strictEqual(results.message, AMD_APP_MESSAGE);
12 | });
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/tests/functional/shimAmdLoading.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Shim AMD Loading Test
6 |
7 |
8 |
9 |
10 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/tests/functional/shimAmdLoading.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import executeTest from './executeTest';
5 |
6 | registerSuite('Shim API AMD loading', {
7 | 'shim tests'() {
8 | return executeTest(this, require, './shimAmdLoading.html', function(results: any) {
9 | assert.strictEqual(results.stringValue, 'string', 'Global value should have been read from nested path');
10 | assert.strictEqual(results.numberValue, 5, 'Init return value should be used as module value');
11 | assert.strictEqual(results.initTwice, 1, 'Module init function should only be called once');
12 | assert.strictEqual(results.addedValues, 8, 'Module dependencies should have resolved');
13 | assert.strictEqual(
14 | results.pluginDep,
15 | 'plugin-dep',
16 | 'Module dependencies should have loaded with no exports'
17 | );
18 | assert.isUndefined(
19 | results.initNotReturn,
20 | 'Empty module export and init function should result in empty object'
21 | );
22 | });
23 | },
24 |
25 | 'non-existent global variable'() {
26 | return executeTest(this, require, './shimAmdLoading2.html', function(results: any) {
27 | assert.strictEqual(
28 | results.error,
29 | 'Tried to find badVariable but it did not exist',
30 | 'Non existent global variable expected to error'
31 | );
32 | });
33 | }
34 | });
35 |
--------------------------------------------------------------------------------
/tests/functional/shimAmdLoading2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Shim AMD Loading Test
6 |
7 |
8 |
9 |
10 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/tests/functional/webworkerAmd.ts:
--------------------------------------------------------------------------------
1 | const { registerSuite } = intern.getInterface('object');
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | import executeTest from './executeTest';
5 |
6 | const AMD_APP_MESSAGE = 'Message from AMD app.';
7 |
8 | registerSuite('AMD loading in web worker', {
9 | 'basic loading'() {
10 | return executeTest(this, require, './webworkerBasic.html', function(results: any) {
11 | assert.strictEqual(results.message, AMD_APP_MESSAGE);
12 | });
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/tests/functional/webworkerBasic.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
20 |
21 |
--------------------------------------------------------------------------------
/tests/functional/worker.ts:
--------------------------------------------------------------------------------
1 | declare function importScripts(url: string): void;
2 |
3 | onmessage = function(e) {
4 | try {
5 | /* load the loader */
6 | importScripts('../../src/loader.js');
7 |
8 | require.config({
9 | packages: [{ name: 'amdApp', location: './amdApp' }]
10 | });
11 |
12 | require(['amdApp/app'], function(app) {
13 | /* post message back with the results */
14 | (postMessage)({
15 | message: app.getMessage()
16 | });
17 | });
18 | } catch (e) {
19 | (postMessage)({
20 | message: e.message,
21 | status: 'fail'
22 | });
23 | throw e;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/tests/interfaces.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace NodeJS {
2 | interface Global {
3 | require: DojoLoader.RootRequire;
4 | define: DojoLoader.Define;
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/tests/module.d.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dojo/loader/147cb45a67a4de9a411c388af0047ae8bdd4d5aa/tests/module.d.ts
--------------------------------------------------------------------------------
/tests/run.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Intern suite
6 |
7 |
8 |
9 | Redirecting to Intern client
10 |
11 |
12 |
--------------------------------------------------------------------------------
/tests/support/util.ts:
--------------------------------------------------------------------------------
1 | export function isEventuallyRejected(promise: Promise): Promise {
2 | return promise.then(
3 | function() {
4 | throw new Error('unexpected code path');
5 | },
6 | (() => {
7 | return true; // expect rejection
8 | })
9 | );
10 | }
11 |
12 | export function throwImmediatly() {
13 | throw new Error('unexpected code path');
14 | }
15 |
--------------------------------------------------------------------------------
/tests/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "module": "umd"
5 | },
6 | "include": [
7 | "./**/*.ts",
8 | "../src/interfaces.d.ts"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/tests/unit/all-node.ts:
--------------------------------------------------------------------------------
1 | import './basicCommonJsLoading';
2 | import './require';
3 |
--------------------------------------------------------------------------------
/tests/unit/all.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dojo/loader/147cb45a67a4de9a411c388af0047ae8bdd4d5aa/tests/unit/all.ts
--------------------------------------------------------------------------------
/tests/unit/bad-module.js:
--------------------------------------------------------------------------------
1 | %6238ff230
2 |
--------------------------------------------------------------------------------
/tests/unit/basicCommonJsLoading.ts:
--------------------------------------------------------------------------------
1 | intern.getInterface('object').registerSuite('basic CommonJS loading', () => {
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | const COMMON_JS_APP_MESSAGE = 'Message from CommonJS app.';
5 | const DEFAULT_TIMEOUT = 1000;
6 |
7 | let globalErrorHandler: any;
8 | let originalDefine: any;
9 | let originalRequire: any;
10 |
11 | function setErrorHandler(dfd: any) {
12 | (process)._events.uncaughtException = function(error: Error) {
13 | dfd.reject(error);
14 | };
15 | }
16 |
17 | function reloadLoader() {
18 | let loaderPath = require.resolve('../../src/loader.js');
19 |
20 | global.define = null;
21 | global.require = null;
22 |
23 | if (require.cache) {
24 | delete require.cache[loaderPath];
25 | }
26 |
27 | require(loaderPath);
28 | }
29 |
30 | return {
31 | before() {
32 | originalDefine = global.define;
33 | originalRequire = global.require;
34 | },
35 |
36 | after() {
37 | global.define = originalDefine;
38 | global.require = originalRequire;
39 | },
40 |
41 | beforeEach() {
42 | // Do this before each test to ensure a clean loader environment with empty cache
43 | reloadLoader();
44 |
45 | global.require.config({
46 | packages: [
47 | {
48 | name: 'commonJs',
49 | location: './tests/common/commonJs'
50 | }
51 | ]
52 | });
53 |
54 | // Need to handle global errors to catch errors thrown by 'require' or 'define'
55 | // otherwise the whole test suite dies
56 | // Note: process.on('uncaughtException') does not work
57 | globalErrorHandler = (process)._events.uncaughtException;
58 | delete (process)._events.uncaughtException;
59 | },
60 |
61 | afterEach() {
62 | (process)._events.uncaughtException = globalErrorHandler;
63 | },
64 |
65 | tests: {
66 | 'simple test'(this: any) {
67 | let dfd = this.async(DEFAULT_TIMEOUT);
68 |
69 | setErrorHandler(dfd);
70 |
71 | global.require(
72 | ['commonJs/app'],
73 | dfd.callback(function(app: any) {
74 | assert.strictEqual(app.getMessage(), COMMON_JS_APP_MESSAGE);
75 | })
76 | );
77 | },
78 |
79 | 'CommonJS module with ID'(this: any) {
80 | let dfd = this.async(DEFAULT_TIMEOUT);
81 |
82 | setErrorHandler(dfd);
83 |
84 | global.require(
85 | ['require', 'commonJs/testModule1'],
86 | dfd.callback(function(require: any) {
87 | let testModule1 = require('test/module1');
88 |
89 | assert.strictEqual(testModule1, 'testModule1', 'Test module with explicit mid should load');
90 | })
91 | );
92 | },
93 |
94 | 'CommonJS module with ID and dependency - ID'(this: any) {
95 | const expected = {
96 | testModule1Value: 'testModule1',
97 | testModule2Value: 'testModule2'
98 | };
99 |
100 | let dfd = this.async(DEFAULT_TIMEOUT);
101 |
102 | setErrorHandler(dfd);
103 |
104 | global.require(
105 | ['require', 'commonJs/testModule1', 'commonJs/testModule2'],
106 | dfd.callback(function(require: any) {
107 | let testModule2 = require('test/module2');
108 |
109 | assert.deepEqual(testModule2, expected, 'Test modules with explicit mids should load');
110 | })
111 | );
112 | },
113 |
114 | 'CommonJS module with ID and dependency - module'(this: any) {
115 | const expected = {
116 | appModuleValue: COMMON_JS_APP_MESSAGE,
117 | testModule3Value: 'testModule3'
118 | };
119 |
120 | let dfd = this.async(DEFAULT_TIMEOUT);
121 |
122 | setErrorHandler(dfd);
123 |
124 | global.require(
125 | ['require', 'commonJs/testModule3'],
126 | dfd.callback(function(require: any) {
127 | let testModule3 = require('test/module3');
128 |
129 | assert.deepEqual(testModule3, expected, 'Test module and dependency should load');
130 | })
131 | );
132 | },
133 |
134 | 'CommonJS module without ID and dependency - id'(this: any) {
135 | const expected = {
136 | testModule1Value: 'testModule1',
137 | testModule2Value: 'testModule2'
138 | };
139 |
140 | let dfd = this.async(DEFAULT_TIMEOUT);
141 |
142 | setErrorHandler(dfd);
143 |
144 | // 'commonJs/testModule1.js' specifies its mid explicitly ('test/module1'), so we have to specify it by filepath
145 | // to get it load initially. 'commonJs/app1' specifies 'test/module1' as a dependency, so we need to ensure
146 | // 'commonJs/testModule1.js' has been loaded before we attempt to load 'commonJs/app1'
147 | global.require(['require', 'commonJs/testModule1'], function(require: any) {
148 | require(['commonJs/app1'], dfd.callback(function(app1: any) {
149 | assert.strictEqual(
150 | app1.getMessage(),
151 | expected.testModule1Value,
152 | 'Test module and dependency should load'
153 | );
154 | }));
155 | });
156 | },
157 |
158 | 'CommonJS module with circular dependency'(this: any) {
159 | let dfd = this.async(DEFAULT_TIMEOUT);
160 |
161 | setErrorHandler(dfd);
162 |
163 | global.require(
164 | ['commonJs/circular1'],
165 | dfd.callback(function(circular1: any) {
166 | assert.strictEqual(
167 | circular1.getMessage(),
168 | 'circular1',
169 | 'Circular dependency should be resolved'
170 | );
171 | assert.strictEqual(
172 | circular1.circular2Message(),
173 | 'circular2',
174 | 'Circular dependency should be resolved'
175 | );
176 | })
177 | );
178 | },
179 |
180 | 'CommonJS module with circular dependency 2'(this: any) {
181 | let dfd = this.async(DEFAULT_TIMEOUT);
182 |
183 | setErrorHandler(dfd);
184 |
185 | global.require(
186 | ['commonJs/circular2'],
187 | dfd.callback(function(circular2: any) {
188 | assert.strictEqual(
189 | circular2.getMessage(),
190 | 'circular2',
191 | 'Circular dependency should be resolved'
192 | );
193 | assert.strictEqual(
194 | circular2.circular1Message(),
195 | 'circular1',
196 | 'Circular dependency should be resolved'
197 | );
198 | })
199 | );
200 | },
201 |
202 | 'CommonJS module with circular dependency 3'(this: any) {
203 | let dfd = this.async(DEFAULT_TIMEOUT);
204 |
205 | setErrorHandler(dfd);
206 |
207 | global.require(
208 | ['commonJs/circular1', 'commonJs/circular2'],
209 | dfd.callback(function(circular1: any, circular2: any) {
210 | assert.strictEqual(
211 | circular1.getMessage(),
212 | 'circular1',
213 | 'Circular dependency should be resolved'
214 | );
215 | assert.strictEqual(
216 | circular1.circular2Message(),
217 | 'circular2',
218 | 'Circular dependency should be resolved'
219 | );
220 | assert.strictEqual(
221 | circular2.getMessage(),
222 | 'circular2',
223 | 'Circular dependency should be resolved'
224 | );
225 | assert.strictEqual(
226 | circular2.circular1Message(),
227 | 'circular1',
228 | 'Circular dependency should be resolved'
229 | );
230 | })
231 | );
232 | },
233 |
234 | 'CommonJS module with deep dependencies'(this: any) {
235 | const expected = {
236 | objectExport: 'objectExport'
237 | };
238 |
239 | let dfd = this.async(DEFAULT_TIMEOUT);
240 |
241 | setErrorHandler(dfd);
242 |
243 | global.require(
244 | ['commonJs/deep1'],
245 | dfd.callback(function(deep1: any) {
246 | let obj = deep1();
247 |
248 | assert.isObject(obj, 'deep1() should create an object');
249 | assert.deepEqual(obj.deep3(), expected, 'deep3() should create an object');
250 | })
251 | );
252 | }
253 | }
254 | };
255 | });
256 |
--------------------------------------------------------------------------------
/tests/unit/require.ts:
--------------------------------------------------------------------------------
1 | intern.getInterface('object').registerSuite('require', () => {
2 | const { assert } = intern.getPlugin('chai');
3 |
4 | const DEFAULT_TIMEOUT = 1000;
5 |
6 | let globalErrorHandler: any;
7 | let originalDefine: any;
8 | let originalRequire: any;
9 | let onErrorHandler: any;
10 |
11 | function setErrorHandler(dfd: any) {
12 | (process)._events.uncaughtException = function(error: Error) {
13 | dfd.reject(error);
14 | };
15 | }
16 |
17 | function reloadLoader() {
18 | let loaderPath = require.resolve('../../src/loader.js');
19 |
20 | global.define = null;
21 | global.require = null;
22 | delete require.cache[loaderPath];
23 | require(loaderPath);
24 | }
25 |
26 | return {
27 | before() {
28 | originalDefine = global.define;
29 | originalRequire = global.require;
30 | },
31 |
32 | after() {
33 | global.define = originalDefine;
34 | global.require = originalRequire;
35 | },
36 |
37 | beforeEach() {
38 | // Do this before each test to ensure a clean loader environment with empty cache
39 | reloadLoader();
40 |
41 | // Need to handle global errors to catch errors thrown by 'require' or 'define'
42 | // otherwise the whole test suite dies
43 | // Note: process.on('uncaughtException') does not work
44 | globalErrorHandler = (process)._events.uncaughtException;
45 | delete (process)._events.uncaughtException;
46 | },
47 |
48 | afterEach() {
49 | (process)._events.uncaughtException = globalErrorHandler;
50 | if (onErrorHandler) {
51 | onErrorHandler.remove();
52 | onErrorHandler = undefined;
53 | }
54 | },
55 |
56 | tests: {
57 | 'node modules'(this: any) {
58 | let dfd = this.async(DEFAULT_TIMEOUT);
59 |
60 | setErrorHandler(dfd);
61 |
62 | global.require(
63 | [
64 | // This module exists in the "node_modules" folder, so the loader will fail to locate it, but should
65 | // use the Node.js 'require' to load it, which should succeed (since Node.js automatically checks
66 | // the "node_modules" folder)
67 | 'grunt/lib/grunt/option',
68 | '_build/tests/common/app'
69 | ],
70 | dfd.callback(function(gruntOption: any, app: any) {
71 | assert.isFunction(gruntOption, '"grunt/option" module should load and be a function');
72 | assert.isFunction(gruntOption.init, '"grunt/option" module should load and be valid');
73 | assert.strictEqual(app, 'app', '"app" module should load');
74 | })
75 | );
76 | },
77 |
78 | 'node modules sync'() {
79 | const events: any = global.require('events');
80 | assert.isNotNull(events);
81 | assert.isNotNull(events.EventEmitter);
82 | },
83 |
84 | 'node modules sync multiples'() {
85 | const events: any = global.require('events');
86 | assert.isNotNull(events);
87 | assert.isNotNull(events.EventEmitter);
88 |
89 | const eventsAgain = global.require('events');
90 | assert.strictEqual(eventsAgain, events);
91 | },
92 |
93 | 'non-existent module'(this: any) {
94 | let dfd = this.async(DEFAULT_TIMEOUT);
95 |
96 | (process)._events.uncaughtException = function(error: Error) {
97 | if (error.message.indexOf('bad/module/id') === -1) {
98 | dfd.reject(error);
99 | } else {
100 | dfd.resolve();
101 | }
102 | };
103 |
104 | global.require(
105 | ['bad/module/id'],
106 | dfd.rejectOnError(function(gruntOption: any, app: any) {
107 | assert.fail(null, null, 'Dependency with bad module id should not be resolved');
108 | })
109 | );
110 | },
111 |
112 | 'non-existent module sync'() {
113 | assert.throws(function() {
114 | global.require('thisIsNotAValidNodeModule');
115 | });
116 | },
117 |
118 | 'non-existent module with on-error listener should not throw error'(this: any) {
119 | let dfd = this.async(DEFAULT_TIMEOUT);
120 | let badMid = 'bad/module/id';
121 |
122 | (process)._events.uncaughtException = function(error: Error) {
123 | if (error.message.indexOf(badMid) > -1) {
124 | dfd.reject(error);
125 | }
126 | };
127 |
128 | onErrorHandler = global.require.on(
129 | 'error',
130 | dfd.callback(function noop(error: DojoLoader.LoaderError) {})
131 | );
132 |
133 | global.require([badMid], function() {
134 | dfd.reject(new Error('Dependency with bad module id should not be resolved'));
135 | });
136 | },
137 |
138 | 'non-existent module with on-error listener should fire callback'(this: any) {
139 | let dfd = this.async(DEFAULT_TIMEOUT);
140 | let badMid = 'bad/module/id';
141 |
142 | onErrorHandler = global.require.on(
143 | 'error',
144 | dfd.callback(function(error: DojoLoader.LoaderError) {
145 | assert.isTrue(
146 | error.message.indexOf(badMid) > -1,
147 | 'Callback should fire and message should contain bad mid'
148 | );
149 | })
150 | );
151 |
152 | global.require([badMid], function() {
153 | dfd.reject(new Error('Dependency with bad module id should not be resolved'));
154 | });
155 | },
156 |
157 | 'non-existent module with on-error listener should provide info'(this: any) {
158 | let dfd = this.async(DEFAULT_TIMEOUT);
159 | let badMid = 'bad/module/id';
160 |
161 | onErrorHandler = global.require.on(
162 | 'error',
163 | dfd.callback(function(error: DojoLoader.LoaderError) {
164 | assert.strictEqual(error.src, 'dojo/loader', 'Error should be marked as from the loader');
165 | assert.isObject(error.info, 'Error should be supplemented with info');
166 | assert.strictEqual(error.info.module.mid, badMid, 'Error should be related to the bad module');
167 | assert.strictEqual(
168 | error.info.url,
169 | badMid + '.js',
170 | 'Error should contain the URL of the bad module'
171 | );
172 | })
173 | );
174 |
175 | global.require([badMid], function() {
176 | dfd.reject(new Error('Dependency with bad module id should not be resolved'));
177 | });
178 | },
179 |
180 | 'specific module errors are reported'(this: any) {
181 | let badMid = 'tests/unit/bad-module';
182 | let dfd = this.async();
183 |
184 | onErrorHandler = global.require.on(
185 | 'error',
186 | dfd.callback(function(error: DojoLoader.LoaderError) {
187 | assert.include(error.info.details || '', 'Unexpected token');
188 | })
189 | );
190 |
191 | global.require([badMid], function() {
192 | dfd.reject('Should not have resolved');
193 | });
194 | },
195 |
196 | 'missing module errors are reported'(this: any) {
197 | let badMid = 'bad/module/id';
198 | let dfd = this.async();
199 |
200 | onErrorHandler = global.require.on(
201 | 'error',
202 | dfd.callback(function(error: DojoLoader.LoaderError) {
203 | assert.include(error.info.details || '', 'Cannot find module');
204 | })
205 | );
206 |
207 | global.require([badMid], function() {
208 | dfd.reject('Should not have resolved');
209 | });
210 | },
211 |
212 | 'on-error listener should be removable'(this: any) {
213 | let dfd = this.async(DEFAULT_TIMEOUT);
214 | let badMid = 'bad/module/id';
215 |
216 | onErrorHandler = global.require.on(
217 | 'error',
218 | dfd.callback(function(error: DojoLoader.LoaderError) {
219 | assert.fail(null, null, 'on-error callback should not have fired');
220 | })
221 | );
222 | onErrorHandler.remove();
223 |
224 | (process)._events.uncaughtException = dfd.callback(function(error: DojoLoader.LoaderError) {
225 | assert.isTrue(error.message.indexOf(badMid) > -1, 'Error should be related to bad module');
226 | });
227 |
228 | global.require([badMid], function() {
229 | dfd.reject(new Error('Dependency with bad module id should not be resolved'));
230 | });
231 | },
232 |
233 | 'only factory AMD require'(this: any) {
234 | let dfd = this.async(DEFAULT_TIMEOUT);
235 |
236 | setErrorHandler(dfd);
237 |
238 | global.require(
239 | ['_build/tests/common/amd/onlyFactory'],
240 | dfd.callback(function(onlyFactory: any) {
241 | assert.strictEqual(
242 | onlyFactory.property,
243 | 'value',
244 | 'AMD module with no dependencies should load'
245 | );
246 | })
247 | );
248 | },
249 |
250 | config: {
251 | baseUrl: {
252 | default(this: any) {
253 | let dfd = this.async(DEFAULT_TIMEOUT);
254 |
255 | setErrorHandler(dfd);
256 |
257 | global.require(
258 | ['_build/tests/common/app'],
259 | dfd.callback(function(app: any) {
260 | assert.strictEqual(app, 'app', '"app" module should load');
261 | })
262 | );
263 | },
264 |
265 | explicit(this: any) {
266 | let dfd = this.async(DEFAULT_TIMEOUT);
267 |
268 | setErrorHandler(dfd);
269 |
270 | global.require.config({
271 | baseUrl: './_build/tests'
272 | });
273 |
274 | global.require(
275 | ['common/app'],
276 | dfd.callback(function(app: any) {
277 | assert.strictEqual(app, 'app', '"app" module should load');
278 | })
279 | );
280 | }
281 | },
282 |
283 | map: {
284 | star(this: any) {
285 | let dfd = this.async(DEFAULT_TIMEOUT);
286 |
287 | setErrorHandler(dfd);
288 |
289 | global.require.config({
290 | map: {
291 | '*': {
292 | mapped: './_build/tests/common'
293 | }
294 | }
295 | });
296 |
297 | global.require(
298 | ['mapped/app'],
299 | dfd.callback(function(app: any) {
300 | assert.strictEqual(app, 'app', '"app" module should load');
301 | })
302 | );
303 | },
304 |
305 | simple(this: any) {
306 | let dfd = this.async(DEFAULT_TIMEOUT);
307 |
308 | setErrorHandler(dfd);
309 |
310 | global.require.config({
311 | map: {
312 | common: {
313 | mapped: './_build/tests/common'
314 | }
315 | },
316 | packages: [
317 | {
318 | name: 'common',
319 | location: './_build/tests/common'
320 | }
321 | ]
322 | });
323 |
324 | global.require(
325 | ['common/map1'],
326 | dfd.callback(function(map1: any) {
327 | assert.strictEqual(map1.app, 'app', '"map1" module and dependency should load');
328 | })
329 | );
330 | },
331 |
332 | hierarchy(this: any) {
333 | let dfd = this.async(DEFAULT_TIMEOUT);
334 |
335 | setErrorHandler(dfd);
336 |
337 | global.require.config({
338 | map: {
339 | common: {
340 | mapped: './_build/tests/common'
341 | },
342 | 'common/a': {
343 | mapped: './_build/tests/common/a'
344 | }
345 | },
346 | packages: [
347 | {
348 | name: 'common',
349 | location: './_build/tests/common'
350 | }
351 | ]
352 | });
353 |
354 | global.require(
355 | ['common/a/map2'],
356 | dfd.callback(function(map2: any) {
357 | assert.strictEqual(map2.app, 'app A', '"map2" module and dependency should load');
358 | })
359 | );
360 | },
361 |
362 | merge(this: any) {
363 | let dfd = this.async(DEFAULT_TIMEOUT);
364 |
365 | setErrorHandler(dfd);
366 |
367 | global.require.config({
368 | map: {
369 | common: {
370 | mapped: './_build/tests/common'
371 | }
372 | },
373 | packages: [
374 | {
375 | name: 'common',
376 | location: './_build/tests/common'
377 | }
378 | ]
379 | });
380 |
381 | global.require.config({
382 | map: {
383 | 'common/a': {
384 | mapped: './_build/tests/common/a'
385 | }
386 | }
387 | });
388 |
389 | global.require(
390 | ['common/map1', 'common/a/map2'],
391 | dfd.callback(function(map1: any, map2: any) {
392 | assert.strictEqual(map1.app, 'app', '"map1" module and dependency should load');
393 | assert.strictEqual(map2.app, 'app A', '"map2" module and dependency should load');
394 | })
395 | );
396 | },
397 |
398 | relative(this: any) {
399 | let dfd = this.async(DEFAULT_TIMEOUT);
400 |
401 | setErrorHandler(dfd);
402 |
403 | global.require.config({
404 | map: {
405 | 'common/a': {
406 | 'common/a': './_build/tests/common'
407 | }
408 | },
409 | packages: [
410 | {
411 | name: 'common',
412 | location: './_build/tests/common'
413 | }
414 | ]
415 | });
416 |
417 | global.require(
418 | ['common/a/relative1'],
419 | dfd.callback(function(relative1: any) {
420 | assert.strictEqual(
421 | relative1.app,
422 | 'app',
423 | '"relative1" module and dependency "common/app" should load'
424 | );
425 | })
426 | );
427 | },
428 |
429 | nested(this: any) {
430 | let dfd = this.async(DEFAULT_TIMEOUT);
431 |
432 | setErrorHandler(dfd);
433 |
434 | global.require.config({
435 | map: {
436 | '*': {
437 | 'common/app': 'common/a/remappedApp'
438 | },
439 | 'common/a/remappedApp': {
440 | 'common/app': 'common/app'
441 | }
442 | },
443 | packages: [
444 | {
445 | name: 'common',
446 | location: './_build/tests/common'
447 | }
448 | ]
449 | });
450 |
451 | global.require(
452 | ['common/usesApp', 'common/a/remappedApp'],
453 | dfd.callback(function(app: any, remappedApp: any) {
454 | assert.strictEqual(
455 | app,
456 | 'remappedapp',
457 | '"usesApp" module should get remapped "a/remappedApp" module'
458 | );
459 | assert.strictEqual(
460 | remappedApp,
461 | 'remappedapp',
462 | '"remappedApp" module should get unmapped "app" module'
463 | );
464 | })
465 | );
466 | },
467 |
468 | plugin(this: any) {
469 | let dfd = this.async(DEFAULT_TIMEOUT);
470 |
471 | setErrorHandler(dfd);
472 |
473 | global.require.config({
474 | map: {
475 | '*': {
476 | plugin: 'common/plugin',
477 | plugin2: 'common/plugin!two'
478 | }
479 | },
480 | packages: [
481 | {
482 | name: 'common',
483 | location: './_build/tests/common'
484 | }
485 | ]
486 | });
487 |
488 | global.require(
489 | ['plugin!one', 'plugin2'],
490 | dfd.callback(function(plugin1: any, plugin2: any) {
491 | assert.strictEqual(plugin1, 'one', 'Plug-in module should load');
492 | assert.strictEqual(plugin2, 'two', 'Plug-in module should load');
493 | })
494 | );
495 | }
496 | },
497 |
498 | packages: {
499 | 'name and location'(this: any) {
500 | let dfd = this.async(DEFAULT_TIMEOUT);
501 |
502 | setErrorHandler(dfd);
503 |
504 | global.require.config({
505 | packages: [
506 | {
507 | name: 'common',
508 | location: './_build/tests/common'
509 | }
510 | ]
511 | });
512 |
513 | global.require(
514 | ['common/app'],
515 | dfd.callback(function(app: any) {
516 | assert.strictEqual(app, 'app', '"app" module should load');
517 | })
518 | );
519 | },
520 |
521 | 'name, location and main'(this: any) {
522 | let dfd = this.async(DEFAULT_TIMEOUT);
523 |
524 | setErrorHandler(dfd);
525 |
526 | global.require.config({
527 | packages: [
528 | {
529 | name: 'common',
530 | location: './_build/tests/common',
531 | main: 'app'
532 | }
533 | ]
534 | });
535 |
536 | global.require(
537 | ['common'],
538 | dfd.callback(function(app: any) {
539 | assert.strictEqual(app, 'app', '"app" module should load');
540 | })
541 | );
542 | },
543 | 'slashes in package name'(this: any) {
544 | let dfd = this.async(DEFAULT_TIMEOUT);
545 |
546 | setErrorHandler(dfd);
547 |
548 | global.require.config({
549 | packages: [
550 | {
551 | name: '@test/common',
552 | location: './_build/tests/common',
553 | main: 'app'
554 | }
555 | ]
556 | });
557 |
558 | global.require(
559 | ['@test/common'],
560 | dfd.callback(function(app: any) {
561 | assert.strictEqual(app, 'app', '"app" module should load');
562 | })
563 | );
564 | },
565 | 'single @ package'(this: any) {
566 | let dfd = this.async(DEFAULT_TIMEOUT);
567 |
568 | setErrorHandler(dfd);
569 |
570 | global.require.config({
571 | packages: [
572 | {
573 | name: '@test',
574 | location: './_build/tests',
575 | main: 'app'
576 | }
577 | ]
578 | });
579 |
580 | global.require(
581 | ['@test/common/app'],
582 | dfd.callback(function(app: any) {
583 | assert.strictEqual(app, 'app', '"app" module should load');
584 | })
585 | );
586 | }
587 | },
588 |
589 | paths: {
590 | simple(this: any) {
591 | let dfd = this.async(DEFAULT_TIMEOUT);
592 |
593 | setErrorHandler(dfd);
594 |
595 | global.require.config({
596 | paths: {
597 | common: '_build/tests/common'
598 | }
599 | });
600 |
601 | global.require(
602 | ['common/app'],
603 | dfd.callback(function(app: any) {
604 | assert.strictEqual(app, 'app', '"app" module should load');
605 | })
606 | );
607 | }
608 | }
609 | },
610 |
611 | has: {
612 | 'has API is available'() {
613 | assert.instanceOf(global.require.has, Function, "'require.has' should be a function");
614 | assert.instanceOf(global.require.has.add, Function, "'require.has.add' should be a function");
615 | },
616 |
617 | add() {
618 | global.require.has.add('test1', 'test1');
619 | assert.strictEqual(global.require.has('test1'), 'test1');
620 | assert.isUndefined(global.require.has('test2'), 'Undefined test should be undefined');
621 |
622 | global.require.has.add('test1', 'NEW VALUE');
623 | assert.strictEqual(global.require.has('test1'), 'test1', 'Re-adding same-name test should fail');
624 |
625 | global.require.has.add('test1', 'NEW VALUE', false, true);
626 | assert.strictEqual(
627 | global.require.has('test1'),
628 | 'NEW VALUE',
629 | 'Re-adding same-name test with force parameter should succeed'
630 | );
631 |
632 | let runCount = 0;
633 | global.require.has.add('test2', function() {
634 | runCount += 1;
635 | return runCount;
636 | });
637 | assert.strictEqual(runCount, 0, 'has test should not execute immediately');
638 |
639 | global.require.has.add(
640 | 'test3',
641 | function() {
642 | runCount += 1;
643 | return runCount;
644 | },
645 | true
646 | );
647 | assert.strictEqual(runCount, 1, "has test with 'now' parameter should execute immediately");
648 |
649 | assert.strictEqual(global.require.has('test2'), 2);
650 | assert.strictEqual(runCount, 2);
651 | assert.strictEqual(global.require.has('test3'), 1, 'Re-running has test should use cached value');
652 | assert.strictEqual(runCount, 2);
653 | }
654 | },
655 |
656 | nodeRequire() {
657 | assert.isFunction(global.require.nodeRequire, '"require.nodeRequire" should be a function');
658 | assert.isNotNull(
659 | (global.require('events')).EventEmitter,
660 | '"require.nodeRequire" should load module'
661 | );
662 | },
663 |
664 | toAbsMid(this: any) {
665 | let dfd = this.async(DEFAULT_TIMEOUT);
666 |
667 | setErrorHandler(dfd);
668 |
669 | // Put the test in its own module so we can use context require
670 | global.define(
671 | 'common/a/toAbsMidTest',
672 | ['require'],
673 | dfd.callback(function(contextRequire: any) {
674 | assert.strictEqual(global.require.toAbsMid('mid'), 'mid');
675 | assert.strictEqual(global.require.toAbsMid('./mid'), 'mid');
676 | assert.strictEqual(global.require.toAbsMid('common/mid'), 'common/mid');
677 |
678 | assert.strictEqual(contextRequire.toAbsMid('mid'), 'mid');
679 | assert.strictEqual(contextRequire.toAbsMid('./mid'), 'common/a/mid');
680 | assert.strictEqual(contextRequire.toAbsMid('../mid'), 'common/mid');
681 | assert.strictEqual(contextRequire.toAbsMid('package/mid'), 'package/mid');
682 | assert.strictEqual(contextRequire.toAbsMid('./package/mid'), 'common/a/package/mid');
683 | assert.strictEqual(contextRequire.toAbsMid('../package/mid'), 'common/package/mid');
684 | })
685 | );
686 |
687 | global.require.config({
688 | baseUrl: './_build/tests'
689 | });
690 |
691 | global.require(['common/a/toAbsMidTest'], () => {});
692 | },
693 |
694 | toUrl(this: any) {
695 | let dfd = this.async(DEFAULT_TIMEOUT);
696 |
697 | setErrorHandler(dfd);
698 |
699 | // Put the test in its own module so we can use context require
700 | global.define(
701 | 'common/a/toUrlTest',
702 | ['require'],
703 | dfd.callback(function(contextRequire: any) {
704 | assert.strictEqual(global.require.toUrl('mid'), '_build/tests/mid');
705 | assert.strictEqual(global.require.toUrl('./mid'), '_build/tests/mid');
706 | assert.strictEqual(global.require.toUrl('common/mid'), '_build/tests/common/mid');
707 |
708 | assert.strictEqual(contextRequire.toUrl('mid'), '_build/tests/mid');
709 | assert.strictEqual(contextRequire.toUrl('./mid'), '_build/tests/common/a/mid');
710 | assert.strictEqual(contextRequire.toUrl('../mid'), '_build/tests/common/mid');
711 | assert.strictEqual(contextRequire.toUrl('package/mid'), '_build/tests/package/mid');
712 | assert.strictEqual(contextRequire.toUrl('./package/mid'), '_build/tests/common/a/package/mid');
713 | assert.strictEqual(contextRequire.toUrl('../package/mid'), '_build/tests/common/package/mid');
714 | })
715 | );
716 |
717 | global.require.config({
718 | baseUrl: './_build/tests'
719 | });
720 |
721 | global.require(['common/a/toUrlTest'], () => {});
722 | },
723 |
724 | undef(this: any) {
725 | let dfd = this.async(DEFAULT_TIMEOUT);
726 |
727 | (process)._events.uncaughtException = function(error: Error) {
728 | if (error.message.indexOf('common/app') === -1) {
729 | dfd.reject(error);
730 | } else {
731 | dfd.resolve();
732 | }
733 | };
734 |
735 | global.require.config({
736 | packages: [
737 | {
738 | name: 'common',
739 | location: './_build/tests/common'
740 | }
741 | ]
742 | });
743 |
744 | global.require(['common/app'], function() {
745 | global.require.undef('common/app');
746 | global.require('common/app');
747 | dfd.reject('Loading undefined module should throw an error');
748 | });
749 | },
750 |
751 | 'recurisve undef': {
752 | 'dependencies are unloaded'(this: any) {
753 | let dfd = this.async(DEFAULT_TIMEOUT);
754 |
755 | global.require.config({
756 | packages: [
757 | {
758 | name: 'recursive',
759 | location: './_build/tests/common/recursive'
760 | }
761 | ]
762 | });
763 |
764 | function checkForUndef(mod: string): boolean {
765 | try {
766 | global.require(mod);
767 | } catch (error) {
768 | if (error.message.indexOf(mod) !== -1) {
769 | return true;
770 | }
771 | }
772 | return false;
773 | }
774 |
775 | global.require(['recursive/a'], function() {
776 | global.require.undef('recursive/a', true);
777 | const deps: string[] = [
778 | 'recursive/a',
779 | 'recursive/b',
780 | 'recursive/c',
781 | 'recursive/d',
782 | 'recursive/e'
783 | ];
784 | const passed: boolean = deps.every(function(mod: string) {
785 | return checkForUndef(mod);
786 | });
787 | if (passed) {
788 | dfd.resolve();
789 | } else {
790 | dfd.reject('not all dependencies were undefined');
791 | }
792 | });
793 | },
794 |
795 | 'modules without dependencies work as expected'() {
796 | global.require.undef('invalid-module', true);
797 | }
798 | },
799 |
800 | 'important modules are not undefined'(this: any) {
801 | let dfd = this.async(DEFAULT_TIMEOUT);
802 |
803 | global.define(
804 | 'undef-module',
805 | ['require', 'module', 'exports'],
806 | (require: any, module: any, exports: any) => {
807 | return {
808 | require,
809 | module,
810 | exports
811 | };
812 | }
813 | );
814 |
815 | global.require(['undef-module'], function() {
816 | global.require.undef('undef-module', true);
817 |
818 | global.define(
819 | 'undef-module-2',
820 | ['require', 'module', 'exports'],
821 | (require: any, module: any, exports: any) => {
822 | return {
823 | require,
824 | module,
825 | exports
826 | };
827 | }
828 | );
829 |
830 | assert.doesNotThrow(() => {
831 | global.require(
832 | ['undef-module-2'],
833 | dfd.callback((defs: any) => {
834 | assert.isTrue(defs.require !== undefined);
835 | assert.isTrue(defs.module !== undefined);
836 | assert.isTrue(defs.exports !== undefined);
837 | })
838 | );
839 | });
840 | });
841 | },
842 |
843 | 'circular dependencies are required'(this: any) {
844 | let dfd = this.async(DEFAULT_TIMEOUT);
845 |
846 | global.require.config({
847 | packages: [
848 | {
849 | name: 'recursive',
850 | location: './_build/tests/common/recursive'
851 | }
852 | ]
853 | });
854 |
855 | global.require(
856 | ['recursive/a'],
857 | dfd.callback(function(a: any) {
858 | assert.equal(a, 'a');
859 | })
860 | );
861 | },
862 |
863 | 'require.cache creates modules with only the cache call'(this: any) {
864 | let dfd = this.async(DEFAULT_TIMEOUT);
865 |
866 | global.require.config({
867 | packages: [
868 | {
869 | name: 'common',
870 | location: './_build/tests/common'
871 | }
872 | ]
873 | });
874 |
875 | global.require.cache({
876 | 'common/app'() {
877 | define([], () => {
878 | return 'mock';
879 | });
880 | }
881 | });
882 |
883 | assert.doesNotThrow(() => {
884 | global.require(
885 | ['common/app'],
886 | dfd.callback((app: any) => {
887 | assert.strictEqual(app, 'mock', 'should return cache factory value');
888 | })
889 | );
890 | });
891 | },
892 |
893 | 'cache injected module is properly undefined'(this: any) {
894 | let dfd = this.async(DEFAULT_TIMEOUT);
895 |
896 | global.require.config({
897 | packages: [
898 | {
899 | name: 'common',
900 | location: './_build/tests/common'
901 | }
902 | ]
903 | });
904 |
905 | global.require.cache({
906 | 'common/app'() {
907 | define([], () => {
908 | return 'mock';
909 | });
910 | }
911 | });
912 |
913 | global.require(
914 | ['common/app'],
915 | dfd.callback(function(app: any) {
916 | assert.strictEqual(app, 'mock', 'should return cache factory value');
917 | global.require.undef('common/app');
918 | assert.throws(
919 | () => {
920 | global.require('common/app');
921 | },
922 | Error,
923 | 'Attempt to require unloaded module'
924 | );
925 | })
926 | );
927 | },
928 |
929 | plugin: {
930 | load(this: any) {
931 | const dfd = this.async(DEFAULT_TIMEOUT);
932 |
933 | global.require.config({
934 | paths: {
935 | common: '_build/tests/common'
936 | }
937 | });
938 |
939 | global.require(
940 | ['common/plugin!one'],
941 | dfd.callback(function(pluginOne: any) {
942 | assert.strictEqual(pluginOne, 'one', 'Plugin should return one');
943 | })
944 | );
945 | },
946 |
947 | config(this: any) {
948 | const dfd = this.async(DEFAULT_TIMEOUT);
949 | const paths: { [path: string]: string } = {
950 | common: '_build/tests/common'
951 | };
952 |
953 | global.require.config({ paths });
954 |
955 | global.require(
956 | ['common/pluginConfig!one'],
957 | dfd.callback(function(pluginConfig: any) {
958 | assert.property(pluginConfig, 'baseUrl', 'Base URL should be present');
959 | assert.deepEqual(
960 | pluginConfig.paths,
961 | paths,
962 | 'Plugin should have received config param equal to require config'
963 | );
964 | })
965 | );
966 | },
967 |
968 | mergedConfig(this: any) {
969 | const dfd = this.async(DEFAULT_TIMEOUT);
970 | const paths: { [path: string]: string } = {
971 | common: '_build/tests/common'
972 | };
973 | const map: DojoLoader.ModuleMap = {
974 | foo: 'bar'
975 | };
976 |
977 | global.require.config({ paths });
978 | global.require.config({ map });
979 |
980 | global.require(
981 | ['common/pluginConfig!one'],
982 | dfd.callback(function(pluginConfig: any) {
983 | assert.deepEqual(pluginConfig.paths, paths, 'Paths should be equal');
984 | assert.deepEqual(pluginConfig.map, map, 'Map should be equal');
985 | })
986 | );
987 | },
988 |
989 | relativePluginPaths(this: any) {
990 | const dfd = this.async(DEFAULT_TIMEOUT);
991 |
992 | global.require.config({
993 | paths: {
994 | common: '_build/tests/common'
995 | }
996 | });
997 |
998 | global.require(
999 | ['common/plugin!../../location'],
1000 | dfd.callback(function(pluginLocation: any) {
1001 | assert.strictEqual(
1002 | pluginLocation,
1003 | '../../location',
1004 | 'Plugin should return location it was passed correctly'
1005 | );
1006 | })
1007 | );
1008 | }
1009 | }
1010 | }
1011 | };
1012 | });
1013 |
--------------------------------------------------------------------------------
/tests/unit/simpleTest.js:
--------------------------------------------------------------------------------
1 | require('./_build/loader.js');
2 |
3 | // this will be the return value from vm.runInContext
4 | x = 'y';
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "inlineSources": true,
5 | "lib": [
6 | "dom",
7 | "es5",
8 | "es2015.iterable",
9 | "es2015.promise",
10 | "es2015.symbol",
11 | "es2015.symbol.wellknown"
12 | ],
13 | "module": "commonjs",
14 | "moduleResolution": "node",
15 | "outDir": "_build/",
16 | "removeComments": false,
17 | "rootDir": ".",
18 | "sourceMap": true,
19 | "strict": true,
20 | "target": "es5",
21 | "types": [ "intern" ]
22 | },
23 | "include": [
24 | "./src/**/*.ts"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "align": false,
4 | "ban": [],
5 | "class-name": true,
6 | "comment-format": [ true, "check-space" ],
7 | "curly": true,
8 | "eofline": true,
9 | "forin": false,
10 | "indent": [ true, "tabs" ],
11 | "interface-name": [ true, "never-prefix" ],
12 | "jsdoc-format": true,
13 | "label-position": true,
14 | "max-line-length": 120,
15 | "member-access": false,
16 | "member-ordering": false,
17 | "no-any": false,
18 | "no-arg": true,
19 | "no-bitwise": false,
20 | "no-consecutive-blank-lines": true,
21 | "no-console": false,
22 | "no-construct": false,
23 | "no-debugger": true,
24 | "no-duplicate-variable": true,
25 | "no-empty": false,
26 | "no-eval": true,
27 | "no-inferrable-types": [ true, "ignore-params" ],
28 | "no-shadowed-variable": false,
29 | "no-string-literal": false,
30 | "no-switch-case-fall-through": false,
31 | "no-trailing-whitespace": true,
32 | "no-unused-expression": false,
33 | "no-use-before-declare": false,
34 | "no-var-keyword": true,
35 | "no-var-requires": false,
36 | "object-literal-sort-keys": false,
37 | "one-line": [ true, "check-open-brace", "check-whitespace" ],
38 | "radix": true,
39 | "trailing-comma": [ true, {
40 | "multiline": "never",
41 | "singleline": "never"
42 | } ],
43 | "triple-equals": [ true, "allow-null-check" ],
44 | "typedef": false,
45 | "typedef-whitespace": [ true, {
46 | "call-signature": "nospace",
47 | "index-signature": "nospace",
48 | "parameter": "nospace",
49 | "property-declaration": "nospace",
50 | "variable-declaration": "nospace"
51 | }, {
52 | "call-signature": "onespace",
53 | "index-signature": "onespace",
54 | "parameter": "onespace",
55 | "property-declaration": "onespace",
56 | "variable-declaration": "onespace"
57 | } ],
58 | "variable-name": [ true, "check-format", "allow-leading-underscore", "ban-keywords" ]
59 | }
60 | }
61 |
--------------------------------------------------------------------------------