I'm trying to test some Typescript modules that are basically global modules, they don't have any imports or exports, i.e something like this:
// module foo.ts
function foobar(): string {
return 'Hello world!';
}
I use the include property in the tsconfig.json file to include these files in the project, and Typescript will compile them so that the functions end up the global scope.
However, in Jest I don't seem to be able to use / import these methods / variables and can't test them.
I want to be able to unit test these global modules.
# content of ts-jest.log :
{"context":{"logLevel":20,"namespace":"Importer","package":"ts-jest","version":"23.10.2"},"message":"creating Importer singleton","sequence":1,"time":"2018-09-27T15:13:06.110Z"}
{"context":{"allowJs":false,"logLevel":20,"namespace":"jest-preset","package":"ts-jest","version":"23.10.2"},"message":"creating jest presets not handling JavaScript files","sequence":2,"time":"2018-09-27T15:13:06.116Z"}
{"context":{"actualVersion":"23.6.0","expectedVersion":">=22 <24","logLevel":20,"namespace":"versions","package":"ts-jest","version":"23.10.2"},"message":"checking version of jest: OK","sequence":3,"time":"2018-09-27T15:13:06.119Z"}
{"context":{"baseOptions":{},"logLevel":20,"namespace":"jest-transformer","package":"ts-jest","transformerId":1,"version":"23.10.2"},"message":"created new transformer","sequence":4,"time":"2018-09-27T15:13:06.119Z"}
{"context":{"fileName":"C:\\Users\\dealloc\\Desktop\\atavistic\\src\\foo.spec.ts","logLevel":20,"namespace":"jest-transformer","package":"ts-jest","transformOptions":{"instrument":false,"rootDir":"C:\\Users\\dealloc\\Desktop\\atavistic"},"transformerId":1,"version":"23.10.2"},"message":"computing cache key for C:\\Users\\dealloc\\Desktop\\atavistic\\src\\foo.spec.ts","sequence":5,"time":"2018-09-27T15:13:06.120Z"}
{"context":{"logLevel":30,"namespace":"jest-transformer","package":"ts-jest","transformerId":1,"version":"23.10.2"},"message":"no matching config-set found, creating a new one","sequence":6,"time":"2018-09-27T15:13:06.120Z"}
{"context":{"config":{"automock":false,"browser":false,"cache":true,"cacheDirectory":"C:\\Users\\dealloc\\AppData\\Local\\Temp\\jest","clearMocks":false,"coveragePathIgnorePatterns":["\\\\node_modules\\\\"],"cwd":"C:\\Users\\dealloc\\Desktop\\atavistic","detectLeaks":false,"detectOpenHandles":false,"errorOnDeprecated":false,"filter":null,"forceCoverageMatch":[],"globals":{"window":{}},"haste":{"providesModuleNodeModules":[]},"moduleDirectories":["node_modules"],"moduleFileExtensions":["ts","tsx","js","jsx","json","node"],"moduleNameMapper":{},"modulePathIgnorePatterns":[],"name":"e483f13e7f20d4de2bc75002922b4968","prettierPath":"C:\\Users\\dealloc\\Desktop\\atavistic\\node_modules\\prettier\\index.js","resetMocks":false,"resetModules":false,"resolver":null,"restoreMocks":false,"rootDir":"C:\\Users\\dealloc\\Desktop\\atavistic","roots":["C:\\Users\\dealloc\\Desktop\\atavistic\\src"],"runner":"jest-runner","setupFiles":[],"setupTestFrameworkScriptFile":"C:\\Users\\dealloc\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PhpStorm\\ch-0\\182.4323.68\\plugins\\JavaScriptLanguage\\helpers\\jest-intellij\\lib\\jest-intellij-jasmine.js","skipFilter":false,"snapshotSerializers":[],"testEnvironment":"jest-environment-jsdom","testEnvironmentOptions":{},"testLocationInResults":false,"testMatch":[],"testPathIgnorePatterns":["\\\\node_modules\\\\"],"testRegex":"(\\\\__tests__\\\\.*|(\\.|\\\\)(test|spec))\\.(tsx?|js)$","testRunner":"C:\\Users\\dealloc\\Desktop\\atavistic\\node_modules\\jest-jasmine2\\build\\index.js","testURL":"http://localhost","timers":"real","transform":[["^.+\\.tsx?$","C:\\Users\\dealloc\\Desktop\\atavistic\\node_modules\\ts-jest\\dist\\index.js"]],"transformIgnorePatterns":["\\\\node_modules\\\\","^C:\\\\Users\\\\dealloc\\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PhpStorm\\\\ch-0\\\\182\\.4323\\.68\\\\plugins\\\\JavaScriptLanguage\\\\helpers"],"unmockedModulePathPatterns":["^C:\\\\Users\\\\dealloc\\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PhpStorm\\\\ch-0\\\\182\\.4323\\.68\\\\plugins\\\\JavaScriptLanguage\\\\helpers"],"watchPathIgnorePatterns":[]},"logLevel":20,"namespace":"backports","package":"ts-jest","transformerId":1,"version":"23.10.2"},"message":"backporting config","sequence":7,"time":"2018-09-27T15:13:06.121Z"}
{"context":{"jestConfig":{"automock":false,"browser":false,"cache":true,"cacheDirectory":"C:\\Users\\dealloc\\AppData\\Local\\Temp\\jest","clearMocks":false,"coveragePathIgnorePatterns":["\\\\node_modules\\\\"],"cwd":"C:\\Users\\dealloc\\Desktop\\atavistic","detectLeaks":false,"detectOpenHandles":false,"errorOnDeprecated":false,"filter":null,"forceCoverageMatch":[],"globals":{"ts-jest":{},"window":{}},"haste":{"providesModuleNodeModules":[]},"moduleDirectories":["node_modules"],"moduleFileExtensions":["ts","tsx","js","jsx","json","node"],"moduleNameMapper":{},"modulePathIgnorePatterns":[],"name":"e483f13e7f20d4de2bc75002922b4968","prettierPath":"C:\\Users\\dealloc\\Desktop\\atavistic\\node_modules\\prettier\\index.js","resetMocks":false,"resetModules":false,"resolver":null,"restoreMocks":false,"rootDir":"C:\\Users\\dealloc\\Desktop\\atavistic","roots":["C:\\Users\\dealloc\\Desktop\\atavistic\\src"],"runner":"jest-runner","setupFiles":[],"setupTestFrameworkScriptFile":"C:\\Users\\dealloc\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PhpStorm\\ch-0\\182.4323.68\\plugins\\JavaScriptLanguage\\helpers\\jest-intellij\\lib\\jest-intellij-jasmine.js","skipFilter":false,"snapshotSerializers":[],"testEnvironment":"jest-environment-jsdom","testEnvironmentOptions":{},"testLocationInResults":false,"testMatch":[],"testPathIgnorePatterns":["\\\\node_modules\\\\"],"testRegex":"(\\\\__tests__\\\\.*|(\\.|\\\\)(test|spec))\\.(tsx?|js)$","testRunner":"C:\\Users\\dealloc\\Desktop\\atavistic\\node_modules\\jest-jasmine2\\build\\index.js","testURL":"http://localhost","timers":"real","transform":[["^.+\\.tsx?$","C:\\Users\\dealloc\\Desktop\\atavistic\\node_modules\\ts-jest\\dist\\index.js"]],"transformIgnorePatterns":["\\\\node_modules\\\\","^C:\\\\Users\\\\dealloc\\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PhpStorm\\\\ch-0\\\\182\\.4323\\.68\\\\plugins\\\\JavaScriptLanguage\\\\helpers"],"unmockedModulePathPatterns":["^C:\\\\Users\\\\dealloc\\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PhpStorm\\\\ch-0\\\\182\\.4323\\.68\\\\plugins\\\\JavaScriptLanguage\\\\helpers"],"watchPathIgnorePatterns":[]},"logLevel":20,"namespace":"config","package":"ts-jest","transformerId":1,"version":"23.10.2"},"message":"normalized jest config","sequence":8,"time":"2018-09-27T15:13:06.121Z"}
{"context":{"logLevel":20,"namespace":"config","package":"ts-jest","transformerId":1,"tsJestConfig":{"compiler":"typescript","diagnostics":{"ignoreCodes":[6059,18002,18003],"pretty":true,"throws":true},"isolatedModules":false,"transformers":[],"tsConfig":{"kind":"file"}},"version":"23.10.2"},"message":"normalized ts-jest config","sequence":9,"time":"2018-09-27T15:13:06.121Z"}
{"context":{"logLevel":20,"namespace":"config","package":"ts-jest","transformerId":1,"version":"23.10.2"},"message":"babel is disabled","sequence":10,"time":"2018-09-27T15:13:06.122Z"}
{"context":{"logLevel":20,"namespace":"Importer","package":"ts-jest","requireResult":{"exists":true,"given":"typescript","path":"C:\\Users\\dealloc\\Desktop\\atavistic\\node_modules\\typescript\\lib\\typescript.js"},"version":"23.10.2"},"message":"loaded module typescript","sequence":11,"time":"2018-09-27T15:13:06.293Z"}
{"context":{"logLevel":20,"namespace":"Importer","package":"ts-jest","version":"23.10.2"},"message":"patching typescript","sequence":12,"time":"2018-09-27T15:13:06.293Z"}
{"context":{"actualVersion":"3.0.3","expectedVersion":">=2.7 <4","logLevel":20,"namespace":"versions","package":"ts-jest","version":"23.10.2"},"message":"checking version of typescript: OK","sequence":13,"time":"2018-09-27T15:13:06.294Z"}
{"context":{"logLevel":20,"namespace":"config","package":"ts-jest","transformerId":1,"tsConfigFileName":"C:/Users/dealloc/Desktop/atavistic/tsconfig.json","version":"23.10.2"},"message":"readTsConfig(): reading C:/Users/dealloc/Desktop/atavistic/tsconfig.json","sequence":14,"time":"2018-09-27T15:13:06.294Z"}
{"context":{"logLevel":20,"namespace":"config","package":"ts-jest","transformerId":1,"tsconfig":{"input":{"compilerOptions":{"allowSyntheticDefaultImports":true,"alwaysStrict":true,"composite":true,"declaration":true,"emitDecoratorMetadata":true,"esModuleInterop":true,"experimentalDecorators":true,"importHelpers":false,"module":"amd","noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":true,"noImplicitThis":true,"noUnusedLocals":true,"noUnusedParameters":true,"outFile":"./dist/garbage.js","sourceMap":true,"strict":true,"strictFunctionTypes":true,"strictNullChecks":true,"strictPropertyInitialization":true,"target":"es3"},"exclude":["node_modules","**/*.spec.ts","**/*.spec.tsx","**/*.test.ts","**/*.test.tsx"],"include":["./src/loader/**/*","./src/**/*"]},"resolved":{"compileOnSave":false,"configFileSpecs":{"excludeSpecs":["node_modules","**/*.spec.ts","**/*.spec.tsx","**/*.test.ts","**/*.test.tsx"],"includeSpecs":["./src/loader/**/*","./src/**/*"],"validatedExcludeSpecs":["node_modules","**/*.spec.ts","**/*.spec.tsx","**/*.test.ts","**/*.test.tsx"],"validatedIncludeSpecs":["./src/loader/**/*","./src/**/*"],"wildcardDirectories":{"c:/users/dealloc/desktop/atavistic/src":1}},"errors":[],"fileNames":["C:/Users/dealloc/Desktop/atavistic/src/loader/define.ts","C:/Users/dealloc/Desktop/atavistic/src/loader/module.ts","C:/Users/dealloc/Desktop/atavistic/src/loader/require.ts","C:/Users/dealloc/Desktop/atavistic/src/foo.ts"],"options":{"allowSyntheticDefaultImports":true,"alwaysStrict":true,"configFilePath":"C:/Users/dealloc/Desktop/atavistic/tsconfig.json","declaration":false,"emitDecoratorMetadata":true,"esModuleInterop":true,"experimentalDecorators":true,"importHelpers":false,"inlineSourceMap":false,"inlineSources":true,"module":1,"noEmit":false,"noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":true,"noImplicitThis":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"$$ts-jest$$","removeComments":false,"sourceMap":true,"strict":true,"strictFunctionTypes":true,"strictNullChecks":true,"strictPropertyInitialization":true,"target":0},"raw":{"compileOnSave":false,"compilerOptions":{"allowSyntheticDefaultImports":true,"alwaysStrict":true,"composite":true,"declaration":true,"emitDecoratorMetadata":true,"esModuleInterop":true,"experimentalDecorators":true,"importHelpers":false,"module":"amd","noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":true,"noImplicitThis":true,"noUnusedLocals":true,"noUnusedParameters":true,"outFile":"./dist/garbage.js","sourceMap":true,"strict":true,"strictFunctionTypes":true,"strictNullChecks":true,"strictPropertyInitialization":true,"target":"es3"},"exclude":["node_modules","**/*.spec.ts","**/*.spec.tsx","**/*.test.ts","**/*.test.tsx"],"include":["./src/loader/**/*","./src/**/*"]},"typeAcquisition":{"enable":false,"exclude":[],"include":[]},"wildcardDirectories":{"c:/users/dealloc/desktop/atavistic/src":1}}},"version":"23.10.2"},"message":"normalized typescript config","sequence":15,"time":"2018-09-27T15:13:06.306Z"}
{"context":{"fileName":"C:\\Users\\dealloc\\Desktop\\atavistic\\src\\foo.ts","logLevel":20,"namespace":"jest-transformer","package":"ts-jest","transformOptions":{"instrument":false,"rootDir":"C:\\Users\\dealloc\\Desktop\\atavistic"},"transformerId":1,"version":"23.10.2"},"message":"computing cache key for C:\\Users\\dealloc\\Desktop\\atavistic\\src\\foo.ts","sequence":16,"time":"2018-09-27T15:13:06.312Z"}
@dealloc can you provide the link to a minimal repository please.
@huafu Sorry, I was writing this issue during a meeting, I'll update ASAP with a minimal reproduction
@huafu I think this more or less demonstrates what I try to achieve
@dealloc I'll look around, but I think you must export function xyz(... and package it using umd or so. What is the purpose of volatile functions? I might be wrong but I don't see today the goal except to copy/paste them in the browser's console, or in a script tag of a 90s' website 馃ぃ
Where/how are you going to use those functions?
@huafu I have to support IE6 for a project, I plan to use non-exported functions to polyfill module loading and some of the Typescript helper methods (such as __extend, ...)
However you can't have the code to load modules wrapped up in module code ;)
So I need them to be working without export
But UMD will work for you (I have some internet issues here, tryin to yarn install and it's telling me that I might have internet issues haha.... but I have some patch for your minimal repo)
I have to support IE6 for a project
OMG I'm sorry for you :D
Here is best option I think:
diff --git a/.gitignore b/.gitignore
index 40b878d..0bf769c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-node_modules/
+node_modules/
+dist
diff --git a/jest.config.js b/jest.config.js
index 93b656f..60151d2 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,20 +1,8 @@
module.exports = {
- 'roots': [
- '<rootDir>/src',
- ],
- 'transform': {
- '^.+\\.tsx?$': 'ts-jest',
+ preset: 'ts-jest',
+ globals: {
+ 'ts-jest': {
+ diagnostics: { ignoreCodes: [151001] },
+ },
},
- 'testRegex': '(/__tests__/.*|(\\.|/)(test|spec))\\.(tsx?|js)$',
- 'moduleFileExtensions': [
- 'ts',
- 'tsx',
- 'js',
- 'jsx',
- 'json',
- 'node',
- ],
- "globals": {
- "window": {}
- }
};
diff --git a/package.json b/package.json
index 0d8c987..5e0e5d9 100644
--- a/package.json
+++ b/package.json
@@ -6,11 +6,11 @@
"license": "MIT",
"private": true,
"scripts": {
- "test": "jest"
+ "test": "jest",
+ "build": "tsc -p tsconfig.build.json"
},
"devDependencies": {
"@types/jest": "^23.3.2",
- "@types/node": "^10.11.1",
"jest": "^23.6.0",
"ts-jest": "^23.10.2",
"typescript": "^3.1.1"
diff --git a/src/foo.spec.ts b/src/foo.spec.ts
index e03bc2e..4bac263 100644
--- a/src/foo.spec.ts
+++ b/src/foo.spec.ts
@@ -1,9 +1,9 @@
-require('./foo');
+import './foo'
test('"foobar" should be declared', function () {
- expect(foobar).not.toBeUndefined();
+ expect(window.foobar).not.toBeUndefined();
});
test('"foobar" should return "Hello world!"', function () {
- expect(foobar()).toBe('Hello world!');
+ expect(window.foobar()).toBe('Hello world!');
});
diff --git a/src/foo.ts b/src/foo.ts
index 818f578..077c147 100644
--- a/src/foo.ts
+++ b/src/foo.ts
@@ -1,3 +1,5 @@
-function foobar(): string {
- return 'Hello world!';
-}
+declare interface Window {
+ foobar: () => string
+}
+
+window.foobar = () => 'Hello world!'
diff --git a/tsconfig.build.json b/tsconfig.build.json
new file mode 100644
index 0000000..3dcc918
--- /dev/null
+++ b/tsconfig.build.json
@@ -0,0 +1,10 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "noEmit": false
+ },
+ "exclude": [
+ "**/*.spec.ts",
+ "node_modules"
+ ]
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..f4737cf
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "target": "es3",
+ "rootDir": "src",
+ "outDir": "dist",
+ "skipLibCheck": true,
+ "noEmit": true
+ }
+}
I'm closing this since the above fixes your issue. Feel free to re-open if needed.
@huafu using the UMD target produces code like the following:
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
exports.__esModule = true;
function foobar() {
return 'Hello world!';
}
exports.foobar = foobar;
});
//# sourceMappingURL=foo.js.map
As you can see, this code requires a define function and an AMD loader to be present.
The code that I wanted to test is exactly this; I'm writing a minimal, IE6 compatible AMD loader at this point and I wanted to test it.
The main problem is that if I use import/export Typescript will generate code that loads modules, while I'm trying to write the code to load modules; so I really can't use import/export in this code.
Another option is to not test the parts of the framework that require to be present globally, but that doesn't look like the right approach.
Use the diff I gave you @dealloc, it's not using UMD neither import/export
THe thing is that you want to be able to import a no module (ie not exportable) code, which is not possible.
@huafu I'll give it a spin tonight.
I figured it'd be a bit difficult, blame IE6 ;)