diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 299cc20e11..1ba9ecb5d2 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -45,7 +45,7 @@ npm run test-coverage
While developing you can run a single test group and use [grep](https://mochajs.org/#-g---grep-pattern) to filter the tests:
```
-npm run mocha -- --grep=lifecycle
+npm test -- --grep=lifecycle
```
### Adding tests
@@ -89,7 +89,7 @@ Expected failures won't cause [Travis CI](https://travis-ci.org/marko-js/marko)
If you need to dig a bit deeper into a failing test, use the `--inspect-brk` flag, open Chrome DevTools, and click on the green nodejs icon (
) to start debugging. Learn more about [debugging node](https://www.youtube.com/watch?v=Xb_0awoShR8&t=103s) from this video.
```
-npm run mocha -- --grep=test-name --inspect-brk
+npm test -- --grep=test-name --inspect-brk
```
In addition to [setting breakpoints](https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints), you can also add [`debugger;`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger) statements in both your JavaScript files and Marko templates:
@@ -106,7 +106,7 @@ A number of the test suites make use snapshot comparisons. For example, the `ren
To update a snapshot, you can copy the contents from the `actual` file to the `expected` file in the fixture directory. You can also use the `UPDATE_EXPECTATIONS` env variable to cause the test runner to update the `expected` file for all currently failing tests in a suite:
```
-UPDATE_EXPECTATIONS=1 npm run mocha
+UPDATE_EXPECTATIONS=1 npm test
```
## Tackling an existing issue
diff --git a/package-lock.json b/package-lock.json
index 4cbd8fe159..702ac76a3d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -215,20 +215,12 @@
"dev": true
},
"acorn-globals": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
- "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz",
+ "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==",
"dev": true,
"requires": {
- "acorn": "^4.0.4"
- },
- "dependencies": {
- "acorn": {
- "version": "4.0.13",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
- "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
- "dev": true
- }
+ "acorn": "^5.0.0"
}
},
"acorn-jsx": {
@@ -443,6 +435,12 @@
"integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
"dev": true
},
+ "async-limiter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+ "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
+ "dev": true
+ },
"async-writer": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/async-writer/-/async-writer-2.1.3.tgz",
@@ -849,6 +847,12 @@
"repeat-element": "^1.1.2"
}
},
+ "browser-process-hrtime": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz",
+ "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=",
+ "dev": true
+ },
"browser-refresh-client": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/browser-refresh-client/-/browser-refresh-client-1.1.4.tgz",
@@ -1209,11 +1213,14 @@
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
"dev": true
},
- "content-type-parser": {
+ "context-require": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz",
- "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==",
- "dev": true
+ "resolved": "https://registry.npmjs.org/context-require/-/context-require-1.0.2.tgz",
+ "integrity": "sha512-7wbTXL0EOXAIZkssBZ3XV4DB0VUvTHYKlFKNXmTYKGMSXedz9N330J/JhXGWRiOSjcr81gAzL60TUu3TV7Ta0Q==",
+ "dev": true,
+ "requires": {
+ "builtins": "^2.0.0"
+ }
},
"convert-source-map": {
"version": "1.5.1",
@@ -1313,9 +1320,9 @@
"dev": true
},
"cssstyle": {
- "version": "0.2.37",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
- "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.3.1.tgz",
+ "integrity": "sha512-tNvaxM5blOnxanyxI6panOsnfiyLRj3HV4qjqqS45WPNS1usdYWRUQjqTEEELK73lpeP/1KoIGYUwrBn/VcECA==",
"dev": true,
"requires": {
"cssom": "0.3.x"
@@ -1347,6 +1354,17 @@
}
}
},
+ "data-urls": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz",
+ "integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==",
+ "dev": true,
+ "requires": {
+ "abab": "^1.0.4",
+ "whatwg-mimetype": "^2.0.0",
+ "whatwg-url": "^6.4.0"
+ }
+ },
"date-fns": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
@@ -1560,6 +1578,15 @@
"integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
"dev": true
},
+ "domexception": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+ "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+ "dev": true,
+ "requires": {
+ "webidl-conversions": "^4.0.2"
+ }
+ },
"domhandler": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
@@ -3569,38 +3596,48 @@
"optional": true
},
"jsdom": {
- "version": "9.12.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.12.0.tgz",
- "integrity": "sha1-6MVG//ywbADUgzyoRBD+1/igl9Q=",
+ "version": "11.11.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.11.0.tgz",
+ "integrity": "sha512-ou1VyfjwsSuWkudGxb03FotDajxAto6USAlmMZjE2lc0jCznt7sBWkhfRBRaWwbnmDqdMSTKTLT5d9sBFkkM7A==",
"dev": true,
"requires": {
- "abab": "^1.0.3",
- "acorn": "^4.0.4",
- "acorn-globals": "^3.1.0",
+ "abab": "^1.0.4",
+ "acorn": "^5.3.0",
+ "acorn-globals": "^4.1.0",
"array-equal": "^1.0.0",
- "content-type-parser": "^1.0.1",
"cssom": ">= 0.3.2 < 0.4.0",
- "cssstyle": ">= 0.2.37 < 0.3.0",
- "escodegen": "^1.6.1",
- "html-encoding-sniffer": "^1.0.1",
- "nwmatcher": ">= 1.3.9 < 2.0.0",
- "parse5": "^1.5.1",
- "request": "^2.79.0",
- "sax": "^1.2.1",
- "symbol-tree": "^3.2.1",
- "tough-cookie": "^2.3.2",
- "webidl-conversions": "^4.0.0",
- "whatwg-encoding": "^1.0.1",
- "whatwg-url": "^4.3.0",
- "xml-name-validator": "^2.0.1"
- },
- "dependencies": {
- "acorn": {
- "version": "4.0.13",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
- "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
- "dev": true
- }
+ "cssstyle": ">= 0.3.1 < 0.4.0",
+ "data-urls": "^1.0.0",
+ "domexception": "^1.0.0",
+ "escodegen": "^1.9.0",
+ "html-encoding-sniffer": "^1.0.2",
+ "left-pad": "^1.2.0",
+ "nwsapi": "^2.0.0",
+ "parse5": "4.0.0",
+ "pn": "^1.1.0",
+ "request": "^2.83.0",
+ "request-promise-native": "^1.0.5",
+ "sax": "^1.2.4",
+ "symbol-tree": "^3.2.2",
+ "tough-cookie": "^2.3.3",
+ "w3c-hr-time": "^1.0.1",
+ "webidl-conversions": "^4.0.2",
+ "whatwg-encoding": "^1.0.3",
+ "whatwg-mimetype": "^2.1.0",
+ "whatwg-url": "^6.4.1",
+ "ws": "^4.0.0",
+ "xml-name-validator": "^3.0.0"
+ }
+ },
+ "jsdom-context-require": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/jsdom-context-require/-/jsdom-context-require-1.0.1.tgz",
+ "integrity": "sha512-D35Rt4xFnjCUAmt1Fz+8QXECyY3CsMyT1UqFgGG24C6qT0FAhrGjQY/v3rOvBXNb8w0u6f9paM8eVe+VaKOtZw==",
+ "dev": true,
+ "requires": {
+ "context-require": "^1.0.1",
+ "jsdom": "^11.6.2",
+ "lasso-resolve-from": "^1.2.0"
}
},
"jsesc": {
@@ -3734,6 +3771,12 @@
"integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
"dev": true
},
+ "left-pad": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
+ "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
+ "dev": true
+ },
"leven": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
@@ -4025,6 +4068,12 @@
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
"dev": true
},
+ "lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+ "dev": true
+ },
"log-driver": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
@@ -4743,10 +4792,10 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
- "nwmatcher": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
- "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==",
+ "nwsapi": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.4.tgz",
+ "integrity": "sha512-Zt6HRR6RcJkuj5/N9zeE7FN6YitRW//hK2wTOwX274IBphbY3Zf5+yn5mZ9v/SzAOTMjQNxZf9KkmPLWn0cV4g==",
"dev": true
},
"nyc": {
@@ -6098,9 +6147,9 @@
}
},
"parse5": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
- "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+ "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
"dev": true
},
"parseurl": {
@@ -6213,6 +6262,12 @@
"integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
"dev": true
},
+ "pn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+ "dev": true
+ },
"posix-character-classes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
@@ -6730,6 +6785,26 @@
}
}
},
+ "request-promise-core": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
+ "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.13.1"
+ }
+ },
+ "request-promise-native": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
+ "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
+ "dev": true,
+ "requires": {
+ "request-promise-core": "1.1.1",
+ "stealthy-require": "^1.1.0",
+ "tough-cookie": ">=2.3.3"
+ }
+ },
"require-uncached": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
@@ -7279,6 +7354,12 @@
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
"dev": true
},
+ "stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+ "dev": true
+ },
"string-argv": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz",
@@ -7533,10 +7614,21 @@
}
},
"tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
- "dev": true
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
+ }
},
"trim-newlines": {
"version": "1.0.0",
@@ -7787,6 +7879,15 @@
}
}
},
+ "w3c-hr-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
+ "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
+ "dev": true,
+ "requires": {
+ "browser-process-hrtime": "^0.1.2"
+ }
+ },
"warp10": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/warp10/-/warp10-1.3.6.tgz",
@@ -7815,22 +7916,21 @@
}
}
},
+ "whatwg-mimetype": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz",
+ "integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==",
+ "dev": true
+ },
"whatwg-url": {
- "version": "4.8.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz",
- "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+ "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
"dev": true,
"requires": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- },
- "dependencies": {
- "webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=",
- "dev": true
- }
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
}
},
"which": {
@@ -7862,10 +7962,20 @@
"mkdirp": "^0.5.1"
}
},
+ "ws": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
+ "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0",
+ "safe-buffer": "~5.1.0"
+ }
+ },
"xml-name-validator": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
- "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true
},
"xtend": {
diff --git a/package.json b/package.json
index f53c5cebc0..9d2a382733 100644
--- a/package.json
+++ b/package.json
@@ -8,9 +8,8 @@
"build-src": "node scripts/build.js src",
"prepublish": "npm run build-src",
"precommit": "lint-staged",
- "test": "npm run lint -s && npm run mocha -s",
- "test-ci": "npm run check-format && npm run test-generate-coverage",
- "mocha": "mocha --timeout 10000 --max-old-space-size=768 ./test/*/*.test.js",
+ "test": "mocha --timeout 10000 ./test/*/*.test.js",
+ "test-ci": "npm run lint && npm run check-format && npm run test-generate-coverage",
"test-coverage": "npm run test-generate-coverage && nyc report --reporter=html && opn ./coverage/index.html",
"test-generate-coverage": "nyc -asc npm test",
"lint": "eslint .",
@@ -82,7 +81,7 @@
"istanbul-lib-instrument": "^1.8.0",
"it-fails": "^1.0.0",
"jquery": "^3.1.1",
- "jsdom": "^9.12.0",
+ "jsdom-context-require": "^1.0.1",
"lasso-resolve-from": "^1.2.0",
"lint-staged": "^7.0.0",
"marko-widgets": "^7.0.1",
diff --git a/test/__util__/BrowserHelpers.js b/test/__util__/BrowserHelpers.js
index 41bee56ac2..4db7602804 100644
--- a/test/__util__/BrowserHelpers.js
+++ b/test/__util__/BrowserHelpers.js
@@ -113,7 +113,7 @@ BrowserHelpers.prototype = {
},
cleanPath: function(path) {
- return path.replace(/\.\d+\.in-module-context$/, "");
+ return path.replace(/\.\d+\.in-context$/, "");
}
};
diff --git a/test/__util__/create-context-module.js b/test/__util__/create-context-module.js
deleted file mode 100644
index 6f5ed3ce94..0000000000
--- a/test/__util__/create-context-module.js
+++ /dev/null
@@ -1,187 +0,0 @@
-"use strict";
-
-// Someday this will become a separate package.
-const vm = require("vm");
-const path = require("path");
-const Module = require("module");
-const builtinModules = require("builtins")();
-const originalCompile = Module.prototype._compile;
-const originalResolve = Module._resolveFilename;
-const S_POSTFIX = Symbol("postfix");
-const S_CONTEXT = Symbol("context");
-const S_RESOLVE = Symbol("resolve");
-const S_HOOKS = Symbol("hooks");
-const EXT_NAME = ".in-module-context";
-let moduleId = 0;
-
-class ContextModule extends Module {
- /**
- * Custom nodejs Module implementation which uses a provided
- * resolver, require hooks, and context.
- */
- constructor(options) {
- const postfix = "." + moduleId++ + EXT_NAME;
- const filename = path.join(options.dir, "index" + postfix);
- super(filename);
-
- this.filename = filename;
- this[S_POSTFIX] = postfix;
- this[S_CONTEXT] = options.context;
- this[S_RESOLVE] = options.resolve;
- this[S_HOOKS] = options.extensions;
- }
-}
-
-/**
- * Patch nodejs module system to support context,
- * compilation and module resolution overrides.
- */
-require.extensions[EXT_NAME] = requireHook;
-Module._resolveFilename = resolveFileHook;
-Module.prototype._compile = compileHook;
-
-// Expose main util.
-exports.createModule = createContextModule;
-
-/**
- * Creates a custom Module object which runs all required scripts in a provided vm context.
- *
- * @param {object} config Config for the module.
- * @param {string} config.dir The directory from which to resolve requires for this module.
- * @param {*|JSDOM} config.context A vm context which will be used as the context for any required modules.
- * @param {function} [config.resolve] A function to which will override the native module resolution.
- * @param {Object.} [config.extensions] An object containing any context specific require hooks to be used in this module.
- * @return {ContextModule}
- */
-function createContextModule(options) {
- return new ContextModule(options);
-}
-
-/**
- * Hijack native file resolution using closest custom resolver.
- *
- * @param {string} request The file to resolve.
- * @param {Module} parentModule The module requiring this file.
- * @return {string}
- */
-function resolveFileHook(request, parentModule) {
- const isNotBuiltin = builtinModules.indexOf(request) === -1;
- const contextModule =
- isNotBuiltin && findNearestContextModule(parentModule);
-
- if (contextModule) {
- const resolver = contextModule[S_RESOLVE];
- if (resolver) {
- const dir = path.dirname(parentModule.filename);
- const postfix = contextModule[S_POSTFIX];
-
- if (request.endsWith(postfix)) {
- return request;
- }
-
- if (path.isAbsolute(request)) {
- request = path.relative(dir, request);
- if (request[0] !== ".") {
- request = "./" + request;
- }
- }
-
- return resolver(dir, request) + postfix;
- }
- }
-
- return originalResolve(request, parentModule);
-}
-
-/**
- * Require hook which removes module postfix and uses custom extensions if provided.
- *
- * @param {Module} module
- * @param {string} filename
- */
-function requireHook(module, filename) {
- const contextModule = findNearestContextModule(module);
- const postfix = contextModule[S_POSTFIX];
- const extensions = contextModule[S_HOOKS];
- filename = filename.slice(0, -postfix.length);
- const ext = path.extname(filename);
- const compiler =
- (extensions && extensions[ext]) ||
- require.extensions[ext] ||
- require.extensions[".js"];
- return compiler(module, filename);
-}
-
-/**
- * This overrides script compilation to ensure the nearest context module is used.
- *
- * @param {string} content The file contents of the script.
- * @param {string} filename The filename for the script.
- */
-function compileHook(content, filename) {
- const contextModule = findNearestContextModule(this);
-
- if (contextModule) {
- const context = contextModule[S_CONTEXT];
- const script = new vm.Script(Module.wrap(content), {
- filename: filename,
- lineOffset: 0,
- displayErrors: true
- });
-
- return runScript(context, script).call(
- this.exports,
- this.exports,
- createRequire(this),
- this,
- filename,
- path.dirname(filename)
- );
- }
-
- return originalCompile.apply(this, arguments);
-}
-
-/**
- * Walks up a module tree to find the nearest context module.
- *
- * @param {Module} cur The starting module.
- * @return {Module?}
- */
-function findNearestContextModule(cur) {
- do {
- if (cur instanceof ContextModule) {
- return cur;
- }
- } while ((cur = cur.parent));
-}
-
-/**
- * Helper which will run a vm script in a context.
- * Special case for JSDOM where `runVMScript` is used.
- *
- * @param {*} context The vm context to run the script in (or a jsdom instance).
- * @param {Script} script The vm script to run.
- * @return {object}
- */
-function runScript(context, script) {
- return context.runVMScript
- ? context.runVMScript(script)
- : script.runInContext(context);
-}
-
-/**
- * Creates a require function bound to a module
- * and adds a `resolve` function the same as nodejs.
- *
- * @param {Module} module The module to create a require function for.
- * @return {function}
- */
-function createRequire(module) {
- const require = module.require.bind(module);
- require.resolve = function(request) {
- return resolveFileHook(request, module);
- };
-
- return require;
-}
diff --git a/test/__util__/create-jsdom-module.js b/test/__util__/create-jsdom-module.js
deleted file mode 100644
index a49c0ef680..0000000000
--- a/test/__util__/create-jsdom-module.js
+++ /dev/null
@@ -1,107 +0,0 @@
-"use strict";
-
-// Someday this will become a separate package.
-const fs = require("fs");
-const path = require("path");
-const jsdom = require("jsdom");
-// const JSDOM = require('jsdom').JSDOM; // JSDOM 10+
-const browserResolve = require("lasso-resolve-from");
-const createContextModule = require("./create-context-module").createModule;
-const remapCache = Object.create(null);
-
-/**
- * Creates a custom Module object which runs all required scripts
- * in a new jsdom instance.
- *
- * @param {object} config Config for the module.
- * @param {string} config.dir The directory from which to resolve requires for this module.
- * @param {string} config.html The initial html to parse with jsdom.
- * @param {function} config.beforeParse A function called with the window, and the module, before parsing html.
- * @param {Object.} [config.extensions] An object containing any browser specific require hooks to be used in this module.
- * @return {JSDOM}
- */
-module.exports = function(options) {
- const html = options.html;
- const dir = options.dir;
- const extensions = options.extensions;
- const beforeParse = options.beforeParse;
- options.html = options.dir = options.extensions = options.beforeParse = undefined;
- const window = jsdom.jsdom("", options).defaultView;
- const context = {
- window: window,
- runVMScript(script) {
- return jsdom.evalVMScript(window, script);
- }
- };
-
- // const context = new JSDOM('', options); // JSDOM 10+
- // const window = context.window; // JSDOM 10+
-
- const resolveConfig = {
- remaps: loadRemaps,
- extensions:
- extensions &&
- []
- .concat(Object.keys(require.extensions))
- .concat(Object.keys(extensions))
- .filter(unique)
- };
- const module = createContextModule({
- dir: dir,
- context: context,
- resolve: resolve,
- extensions: extensions
- });
-
- context.require = module.require.bind(module);
- beforeParse && beforeParse(window, context);
- window.document.open();
- window.document.write(html);
-
- return context;
-
- /**
- * A function to resolve modules in the browser using the provided config.
- *
- * @param {string} from The file being resolved from.
- * @param {string} request The requested path to resolve.
- * @return {string}
- */
- function resolve(from, request) {
- return browserResolve(from, request, resolveConfig).path;
- }
-};
-
-/**
- * Array filter for uniqueness.
- */
-function unique(item, i, list) {
- return list.indexOf(item) === i;
-}
-
-/**
- * Loads browser.json remaps.
- *
- * @param {string} dir
- * @return {object|void}
- */
-function loadRemaps(dir) {
- const file = path.join(dir, "browser.json");
-
- if (file in remapCache) {
- return remapCache[file];
- }
-
- let result;
- const remaps = fs.existsSync(file) && require(file).requireRemap;
-
- if (remaps) {
- result = {};
- for (const remap of remaps) {
- result[path.join(dir, remap.from)] = path.join(dir, remap.to);
- }
- }
-
- remapCache[file] = result;
- return result;
-}
diff --git a/test/__util__/create-marko-jsdom-module.js b/test/__util__/create-marko-jsdom-module.js
index cab6dae387..1fef3890ad 100644
--- a/test/__util__/create-marko-jsdom-module.js
+++ b/test/__util__/create-marko-jsdom-module.js
@@ -1,7 +1,7 @@
"use strict";
const jQuery = require("jquery");
-const createJSDOMModule = require("./create-jsdom-module");
+const createBrowser = require("jsdom-context-require");
const compiler = require("../../compiler");
const noop = function() {};
const globals = [
@@ -32,7 +32,7 @@ const browserExtensions = {
module.exports = function(dir, html, options) {
options = options || {};
- return createJSDOMModule({
+ return createBrowser({
dir: dir,
html: html,
extensions: browserExtensions,
diff --git a/test/__util__/runRenderTest.js b/test/__util__/runRenderTest.js
index a797f58f74..6c9aff2e19 100644
--- a/test/__util__/runRenderTest.js
+++ b/test/__util__/runRenderTest.js
@@ -1,7 +1,7 @@
"use strict";
-const createJSDOMModule = require("../__util__/create-jsdom-module");
-const defaultDocument = createJSDOMModule({
+const createBrowser = require("jsdom-context-require");
+const defaultDocument = createBrowser({
dir: __dirname,
html: ""
}).window.document;
@@ -182,7 +182,7 @@ module.exports = function runRenderTest(dir, snapshot, done, options) {
let expectedHtmlPath = path.join(dir, "expected.html");
let html = fs.readFileSync(expectedHtmlPath, "utf-8");
- let browser = createJSDOMModule({
+ let browser = createBrowser({
dir: __dirname,
html: "" + html + ""
});
@@ -216,7 +216,7 @@ module.exports = function runRenderTest(dir, snapshot, done, options) {
let vdomHtml = domToHTML(actualNode);
- let browser = createJSDOMModule({
+ let browser = createBrowser({
dir: __dirname,
html: "" + vdomHtml + ""
});
diff --git a/test/components-browser/index.test.js b/test/components-browser/index.test.js
index 6bd69fa076..c42aaa4a26 100644
--- a/test/components-browser/index.test.js
+++ b/test/components-browser/index.test.js
@@ -2,12 +2,12 @@
require("../__util__/test-init");
var autotest = require("../autotest");
-var createJSDOMModule = require("../__util__/create-marko-jsdom-module");
+var createBrowserWithMarko = require("../__util__/create-marko-jsdom-module");
var ssrTemplate = require("./template.marko");
var hydrateComponentPath = require.resolve("./template.component-browser.js");
var browserHelpersPath = require.resolve("../__util__/BrowserHelpers");
var testTargetHTML = '';
-var browser = createJSDOMModule(__dirname, testTargetHTML);
+var browser = createBrowserWithMarko(__dirname, testTargetHTML);
var BrowserHelpers = browser.require(browserHelpersPath);
autotest("fixtures", {
@@ -62,7 +62,7 @@ function runHydrateTest(fixture) {
ssrTemplate
.render({ components: components, $global: $global })
.then(function(html) {
- var browser = createJSDOMModule(__dirname, String(html), {
+ var browser = createBrowserWithMarko(__dirname, String(html), {
beforeParse(window, browser) {
var marko = browser.require("marko/components");
var legacy = browser.require("marko/legacy-components");
diff --git a/test/components-pages/index.test.js b/test/components-pages/index.test.js
index d42c08a8dd..09cd5ae105 100644
--- a/test/components-pages/index.test.js
+++ b/test/components-pages/index.test.js
@@ -4,7 +4,7 @@ require("../__util__/test-init");
var autotest = require("../autotest");
var asyncTestSuite = require("../__util__/async-test-suite");
-var createJSDOMModule = require("../__util__/create-marko-jsdom-module");
+var createBrowserWithMarko = require("../__util__/create-marko-jsdom-module");
autotest("fixtures", run);
autotest("fixtures-deprecated", run);
@@ -19,7 +19,7 @@ function run(fixture) {
var templateFile = resolve("template.marko");
var template = require(templateFile);
return template.render({}).then(function(html) {
- var browser = createJSDOMModule(__dirname, String(html), {
+ var browser = createBrowserWithMarko(__dirname, String(html), {
beforeParse(window, browser) {
browser.require("../../components");
browser.require(templateFile);
diff --git a/test/morphdom/index.test.js b/test/morphdom/index.test.js
index 8265661dad..be10c1fa72 100644
--- a/test/morphdom/index.test.js
+++ b/test/morphdom/index.test.js
@@ -8,7 +8,7 @@ chai.config.includeStack = true;
var autotest = require("../autotest");
const fs = require("fs");
const morphdom = require("marko/morphdom");
-const createJSDOMModule = require("../__util__/create-jsdom-module");
+const createBrowser = require("jsdom-context-require");
autotest("fixtures", fixture => {
let test = fixture.test;
@@ -22,11 +22,11 @@ autotest("fixtures", fixture => {
encoding: "utf8"
});
- let fromDocument = createJSDOMModule({
+ let fromDocument = createBrowser({
dir: __dirname,
html: "" + fromHTML + ""
}).window.document;
- let toDocument = createJSDOMModule({
+ let toDocument = createBrowser({
dir: __dirname,
html: "" + toHTML + ""
}).window.document;
diff --git a/test/vdom-create/index.test.js b/test/vdom-create/index.test.js
index 5b01b327ba..9d42e703c0 100644
--- a/test/vdom-create/index.test.js
+++ b/test/vdom-create/index.test.js
@@ -4,10 +4,10 @@ require("../__util__/test-init");
var fs = require("fs");
var domToString = require("../__util__/domToString");
-var createJSDOMModule = require("../__util__/create-jsdom-module");
+var createBrowser = require("jsdom-context-require");
var autotest = require("../autotest");
-var document = createJSDOMModule({
+var document = createBrowser({
dir: __dirname,
html: ""
}).window.document;
diff --git a/test/vdom-virtualize/index.test.js b/test/vdom-virtualize/index.test.js
index 67949a9abb..6be1c5f689 100644
--- a/test/vdom-virtualize/index.test.js
+++ b/test/vdom-virtualize/index.test.js
@@ -4,7 +4,7 @@ require("../__util__/test-init");
var virtualize = require("marko/runtime/vdom/vdom").___virtualize;
var fs = require("fs");
var toHTML = require("../__util__/toHTML");
-var createJSDOMModule = require("../__util__/create-jsdom-module");
+var createBrowser = require("jsdom-context-require");
var autotest = require("../autotest");
autotest("fixtures", fixture => {
@@ -16,7 +16,7 @@ autotest("fixtures", fixture => {
if (fs.existsSync(inputPath)) {
var inputHtml = fs.readFileSync(inputPath, { encoding: "utf8" });
- var document = createJSDOMModule({
+ var document = createBrowser({
dir: __dirname,
html: "" + inputHtml + ""
}).window.document;