From fa114cf3b67bb0e3044241a3599bc1cf8671535b Mon Sep 17 00:00:00 2001
From: Susanne Moog <susanne.moog@typo3.com>
Date: Sun, 18 Jun 2017 11:53:00 +0200
Subject: [PATCH] [FEATURE] Add possibility to write tests in TypeScript

Adjust grunt and tsconfig to allow writing unit tests
in TypeScript. Test example is included.

Additionally configuration was adjusted to allow running
grunt tasks on windows and linux.

Change-Id: Ibeb0c501242afbbe796726a85329d14257acfd1c
Resolves: #81601
Releases: master
Reviewed-on: https://review.typo3.org/53248
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
---
 Build/Gruntfile.js                            | 14 ++--
 Build/tsconfig.json                           | 81 ++++++++++++-------
 .../Tests/JavaScript/BackendExceptionTest.js  | 14 ++++
 .../Tests/TypeScript/BackendExceptionTest.ts  | 26 ++++++
 ...AddPossibilityToWriteTestsInTypeScript.rst | 22 +++++
 5 files changed, 125 insertions(+), 32 deletions(-)
 create mode 100644 typo3/sysext/backend/Tests/JavaScript/BackendExceptionTest.js
 create mode 100644 typo3/sysext/backend/Tests/TypeScript/BackendExceptionTest.ts
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Feature-81601-AddPossibilityToWriteTestsInTypeScript.rst

diff --git a/Build/Gruntfile.js b/Build/Gruntfile.js
index c69a22d2a9e9..29345ec4aa69 100644
--- a/Build/Gruntfile.js
+++ b/Build/Gruntfile.js
@@ -193,7 +193,7 @@ module.exports = function (grunt) {
 			}
 		},
 		exec: {
-			ts: './node_modules/.bin/tsc --project tsconfig.json'
+			ts: ((process.platform === 'win32') ? 'node_modules\\.bin\\tsc.cmd' : './node_modules/.bin/tsc') + ' --project tsconfig.json'
 		},
 		tslint: {
 			options: {
@@ -202,6 +202,7 @@ module.exports = function (grunt) {
 			},
 			files: {
 				src: [
+					'<%= paths.sysext %>*/Tests/TypeScript/**/*.ts',
 					'<%= paths.sysext %>*/Resources/Private/TypeScript/**/*.ts',
 					'./types/**/*.ts'
 				]
@@ -216,7 +217,7 @@ module.exports = function (grunt) {
 				tasks: 'css'
 			},
 			ts: {
-				files: '<%= paths.sysext %>*/Resources/Private/TypeScript/**/*.ts',
+				files: '<%= paths.sysext %>*/**/TypeScript/**/*.ts',
 				tasks: 'scripts'
 			}
 		},
@@ -231,7 +232,9 @@ module.exports = function (grunt) {
 					src: ['**/*.js', '**/*.js.map'],
 					dest: '<%= paths.sysext %>',
 					rename: function (dest, src) {
-						return dest + src.replace('Resources/Private/TypeScript', 'Resources/Public/JavaScript');
+						var srccleaned = src.replace('Resources/Private/TypeScript', 'Resources/Public/JavaScript');
+						srccleaned = srccleaned.replace('Tests/TypeScript', 'Tests/JavaScript');
+						return dest + srccleaned;
 					}
 				}]
 			},
@@ -597,8 +600,9 @@ module.exports = function (grunt) {
 					return match.charAt(1).toUpperCase();
 				});
 			var namespace = 'TYPO3/CMS/' + extname + '/*',
-				path = dir + "/*";
-			config.compilerOptions.paths[namespace] = [path];
+				path = dir + "/*",
+				typescriptPath = path.replace('Public/JavaScript', 'Private/TypeScript');
+			config.compilerOptions.paths[namespace] = [path, typescriptPath];
 		});
 
 		grunt.file.write('tsconfig.json', JSON.stringify(config, null, 4));
diff --git a/Build/tsconfig.json b/Build/tsconfig.json
index 9f2409d38e6f..ae6415721b73 100644
--- a/Build/tsconfig.json
+++ b/Build/tsconfig.json
@@ -15,82 +15,108 @@
         "rootDir": "../",
         "paths": {
             "TYPO3/CMS/Backend/*": [
-                "../typo3/sysext/backend/Resources/Public/JavaScript/*"
+                "../typo3/sysext/backend/Resources/Public/JavaScript/*",
+                "../typo3/sysext/backend/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Beuser/*": [
-                "../typo3/sysext/beuser/Resources/Public/JavaScript/*"
+                "../typo3/sysext/beuser/Resources/Public/JavaScript/*",
+                "../typo3/sysext/beuser/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Core/*": [
-                "../typo3/sysext/core/Resources/Public/JavaScript/*"
+                "../typo3/sysext/core/Resources/Public/JavaScript/*",
+                "../typo3/sysext/core/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Documentation/*": [
-                "../typo3/sysext/documentation/Resources/Public/JavaScript/*"
+                "../typo3/sysext/documentation/Resources/Public/JavaScript/*",
+                "../typo3/sysext/documentation/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Extensionmanager/*": [
-                "../typo3/sysext/extensionmanager/Resources/Public/JavaScript/*"
+                "../typo3/sysext/extensionmanager/Resources/Public/JavaScript/*",
+                "../typo3/sysext/extensionmanager/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Filelist/*": [
-                "../typo3/sysext/filelist/Resources/Public/JavaScript/*"
+                "../typo3/sysext/filelist/Resources/Public/JavaScript/*",
+                "../typo3/sysext/filelist/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Form/*": [
-                "../typo3/sysext/form/Resources/Public/JavaScript/*"
+                "../typo3/sysext/form/Resources/Public/JavaScript/*",
+                "../typo3/sysext/form/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Frontend/*": [
-                "../typo3/sysext/frontend/Resources/Public/JavaScript/*"
+                "../typo3/sysext/frontend/Resources/Public/JavaScript/*",
+                "../typo3/sysext/frontend/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Impexp/*": [
-                "../typo3/sysext/impexp/Resources/Public/JavaScript/*"
+                "../typo3/sysext/impexp/Resources/Public/JavaScript/*",
+                "../typo3/sysext/impexp/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Install/*": [
-                "../typo3/sysext/install/Resources/Public/JavaScript/*"
+                "../typo3/sysext/install/Resources/Public/JavaScript/*",
+                "../typo3/sysext/install/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Lang/*": [
-                "../typo3/sysext/lang/Resources/Public/JavaScript/*"
+                "../typo3/sysext/lang/Resources/Public/JavaScript/*",
+                "../typo3/sysext/lang/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Linkvalidator/*": [
-                "../typo3/sysext/linkvalidator/Resources/Public/JavaScript/*"
+                "../typo3/sysext/linkvalidator/Resources/Public/JavaScript/*",
+                "../typo3/sysext/linkvalidator/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Lowlevel/*": [
-                "../typo3/sysext/lowlevel/Resources/Public/JavaScript/*"
+                "../typo3/sysext/lowlevel/Resources/Public/JavaScript/*",
+                "../typo3/sysext/lowlevel/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Opendocs/*": [
-                "../typo3/sysext/opendocs/Resources/Public/JavaScript/*"
+                "../typo3/sysext/opendocs/Resources/Public/JavaScript/*",
+                "../typo3/sysext/opendocs/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Recordlist/*": [
-                "../typo3/sysext/recordlist/Resources/Public/JavaScript/*"
+                "../typo3/sysext/recordlist/Resources/Public/JavaScript/*",
+                "../typo3/sysext/recordlist/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Recycler/*": [
-                "../typo3/sysext/recycler/Resources/Public/JavaScript/*"
+                "../typo3/sysext/recycler/Resources/Public/JavaScript/*",
+                "../typo3/sysext/recycler/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Rsaauth/*": [
-                "../typo3/sysext/rsaauth/Resources/Public/JavaScript/*"
+                "../typo3/sysext/rsaauth/Resources/Public/JavaScript/*",
+                "../typo3/sysext/rsaauth/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/RteCkeditor/*": [
-                "../typo3/sysext/rte_ckeditor/Resources/Public/JavaScript/*"
+                "../typo3/sysext/rte_ckeditor/Resources/Public/JavaScript/*",
+                "../typo3/sysext/rte_ckeditor/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Scheduler/*": [
-                "../typo3/sysext/scheduler/Resources/Public/JavaScript/*"
+                "../typo3/sysext/scheduler/Resources/Public/JavaScript/*",
+                "../typo3/sysext/scheduler/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/SysAction/*": [
-                "../typo3/sysext/sys_action/Resources/Public/JavaScript/*"
+                "../typo3/sysext/sys_action/Resources/Public/JavaScript/*",
+                "../typo3/sysext/sys_action/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/T3editor/*": [
-                "../typo3/sysext/t3editor/Resources/Public/JavaScript/*"
+                "../typo3/sysext/t3editor/Resources/Public/JavaScript/*",
+                "../typo3/sysext/t3editor/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Taskcenter/*": [
-                "../typo3/sysext/taskcenter/Resources/Public/JavaScript/*"
+                "../typo3/sysext/taskcenter/Resources/Public/JavaScript/*",
+                "../typo3/sysext/taskcenter/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Tstemplate/*": [
-                "../typo3/sysext/tstemplate/Resources/Public/JavaScript/*"
+                "../typo3/sysext/tstemplate/Resources/Public/JavaScript/*",
+                "../typo3/sysext/tstemplate/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Viewpage/*": [
-                "../typo3/sysext/viewpage/Resources/Public/JavaScript/*"
+                "../typo3/sysext/viewpage/Resources/Public/JavaScript/*",
+                "../typo3/sysext/viewpage/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/WizardCrpages/*": [
-                "../typo3/sysext/wizard_crpages/Resources/Public/JavaScript/*"
+                "../typo3/sysext/wizard_crpages/Resources/Public/JavaScript/*",
+                "../typo3/sysext/wizard_crpages/Resources/Private/TypeScript/*"
             ],
             "TYPO3/CMS/Workspaces/*": [
-                "../typo3/sysext/workspaces/Resources/Public/JavaScript/*"
+                "../typo3/sysext/workspaces/Resources/Public/JavaScript/*",
+                "../typo3/sysext/workspaces/Resources/Private/TypeScript/*"
             ]
         },
         "outDir": "./JavaScript/",
@@ -100,6 +126,7 @@
         ]
     },
     "include": [
-        "../typo3/sysext/*/Resources/Private/TypeScript/**/*.ts"
+        "../typo3/sysext/*/Resources/Private/TypeScript/**/*.ts",
+        "../typo3/sysext/*/Tests/TypeScript/**/*.ts"
     ]
 }
\ No newline at end of file
diff --git a/typo3/sysext/backend/Tests/JavaScript/BackendExceptionTest.js b/typo3/sysext/backend/Tests/JavaScript/BackendExceptionTest.js
new file mode 100644
index 000000000000..fdc67ac6dd35
--- /dev/null
+++ b/typo3/sysext/backend/Tests/JavaScript/BackendExceptionTest.js
@@ -0,0 +1,14 @@
+define(["require", "exports", "TYPO3/CMS/Backend/BackendException"], function (require, exports, BackendException_1) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    describe('TYPO3/CMS/Backend/BackendException', function () {
+        it('sets exception message', function () {
+            var backendException = new BackendException_1.BackendException('some message');
+            expect(backendException.message).toBe('some message');
+        });
+        it('sets exception code', function () {
+            var backendException = new BackendException_1.BackendException('', 12345);
+            expect(backendException.code).toBe(12345);
+        });
+    });
+});
diff --git a/typo3/sysext/backend/Tests/TypeScript/BackendExceptionTest.ts b/typo3/sysext/backend/Tests/TypeScript/BackendExceptionTest.ts
new file mode 100644
index 000000000000..dd16731e9a15
--- /dev/null
+++ b/typo3/sysext/backend/Tests/TypeScript/BackendExceptionTest.ts
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+import {BackendException} from 'TYPO3/CMS/Backend/BackendException';
+
+describe('TYPO3/CMS/Backend/BackendException', () => {
+    it('sets exception message', () => {
+        const backendException = new BackendException('some message');
+        expect(backendException.message).toBe('some message');
+    });
+
+    it('sets exception code', () => {
+        const backendException = new BackendException('', 12345);
+        expect(backendException.code).toBe(12345);
+    });
+});
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-81601-AddPossibilityToWriteTestsInTypeScript.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-81601-AddPossibilityToWriteTestsInTypeScript.rst
new file mode 100644
index 000000000000..ab938e8cf103
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-81601-AddPossibilityToWriteTestsInTypeScript.rst
@@ -0,0 +1,22 @@
+.. include:: ../../Includes.txt
+
+==============================================================
+Feature: #81601 - Add possibility to write tests in typeScript
+==============================================================
+
+See :issue:`81601`
+
+Description
+===========
+
+The core is using TypeScript as language already - now writing unit tests in TypeScript is also possible. 
+The tsconfig.json now contains both JavaScript and TypeScript module path mappings, the grunt file will take care of adjusting the paths for TypeScript as well.
+
+
+Impact
+======
+
+Tests can now be written directly in TypeScript, making it easier to test TypeScript components, having auto-completion and IDE support.
+Tests written in TypeScript will be converted to JavaScript via the grunt task `scripts` and executed via the existing karma configuration.
+
+.. index:: Backend, JavaScript
\ No newline at end of file
-- 
GitLab