diff --git a/developer/src/kmc/src/commands/analyze.ts b/developer/src/kmc/src/commands/analyze.ts
index 0ee8149d0b..fd6314ec86 100644
--- a/developer/src/kmc/src/commands/analyze.ts
+++ b/developer/src/kmc/src/commands/analyze.ts
@@ -121,3 +121,10 @@ async function analyzeOskRewritePua(callbacks: CompilerCallbacks, filenames: str
return true;
});
}
+
+/**
+ * these are exported only for unit tests, do not use
+ */
+export const analyzeUnitTestEndpoints = {
+ analyzeOskCharUse
+};
\ No newline at end of file
diff --git a/developer/src/kmc/test/fixtures/analyze/error_unknown_file_format.xxx b/developer/src/kmc/test/fixtures/analyze/error_unknown_file_format.xxx
new file mode 100644
index 0000000000..5ae49a58cb
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/analyze/error_unknown_file_format.xxx
@@ -0,0 +1 @@
+This is a file used to test the unknown file format error (see test-infrastructureMessages.ts)
\ No newline at end of file
diff --git a/developer/src/kmc/test/fixtures/invalid-keyboards/error_file_type_not_recognized.xxx b/developer/src/kmc/test/fixtures/invalid-keyboards/error_file_type_not_recognized.xxx
new file mode 100644
index 0000000000..162d8d5f2e
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/invalid-keyboards/error_file_type_not_recognized.xxx
@@ -0,0 +1 @@
+This is a file used to test the unrecognised file type error (see test-infrastructureMessages.ts)
\ No newline at end of file
diff --git a/developer/src/kmc/test/fixtures/invalid-projects/build b/developer/src/kmc/test/fixtures/invalid-projects/build
new file mode 100644
index 0000000000..ce5a9fe3c0
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/invalid-projects/build
@@ -0,0 +1 @@
+This is a file used to test the cannot create folder error (see test-infrastructureMessages.ts)
\ No newline at end of file
diff --git a/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__keyboard.kpj b/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__keyboard.kpj
new file mode 100644
index 0000000000..c810dc7c33
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__keyboard.kpj
@@ -0,0 +1,24 @@
+
+
+
+ $PROJECTPATH
+ False
+ False
+ False
+ keyboard
+
+
+
+ error_file_type_not_found_kbd_1
+ error_file_type_not_found__keyboard.kmn
+ error_file_type_not_found__keyboard.kmn
+ 1.0
+ .kmn
+
+ error_file_type_not_found__keyboard
+ Copyright (C) Keyman Team
+
+
+
+
+
diff --git a/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__model_kps.kpj b/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__model_kps.kpj
new file mode 100644
index 0000000000..aa1e55d9ae
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__model_kps.kpj
@@ -0,0 +1,24 @@
+
+
+
+ $PROJECTPATH
+ False
+ False
+ False
+ lexicalmodel
+
+
+
+ error_file_type_not_found_mdl_kps_1
+ error_file_type_not_found__model_kps.model.ts
+ error_file_type_not_found__model_kps.model.ts
+
+ .model.ts
+
+ error_file_type_not_found__model_kps
+ Copyright (C) Keyman Team
+
+
+
+
+
diff --git a/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__model_ts.kpj b/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__model_ts.kpj
new file mode 100644
index 0000000000..3d69834913
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/invalid-projects/error_file_type_not_found__model_ts.kpj
@@ -0,0 +1,24 @@
+
+
+
+ $PROJECTPATH
+ False
+ False
+ False
+ lexicalmodel
+
+
+
+
+ error_file_type_not_found_mdl_mdl_2
+ error_file_type_not_found__model_ts.kps
+ error_file_type_not_found__model_ts.kps
+
+ .kps
+
+ error_file_type_not_found__model_ts
+ Copyright (C) Keyman Team
+
+
+
+
diff --git a/developer/src/kmc/test/fixtures/invalid-projects/error_invalid_project_file.kpj b/developer/src/kmc/test/fixtures/invalid-projects/error_invalid_project_file.kpj
new file mode 100644
index 0000000000..e01a746e66
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/invalid-projects/error_invalid_project_file.kpj
@@ -0,0 +1 @@
+This is a file used to test the invalid project file error (see test-infrastructureMessages.ts)
\ No newline at end of file
diff --git a/developer/src/kmc/test/fixtures/invalid-projects/error_not_a_project_file.xxx b/developer/src/kmc/test/fixtures/invalid-projects/error_not_a_project_file.xxx
new file mode 100644
index 0000000000..f7fff35790
--- /dev/null
+++ b/developer/src/kmc/test/fixtures/invalid-projects/error_not_a_project_file.xxx
@@ -0,0 +1 @@
+This is a file used to test the not a project file error (see test-infrastructureMessages.ts)
\ No newline at end of file
diff --git a/developer/src/kmc/test/fixtures/no-source-folder/.gitkeep b/developer/src/kmc/test/fixtures/no-source-folder/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/developer/src/kmc/test/test-infrastructureMessages.ts b/developer/src/kmc/test/test-infrastructureMessages.ts
index 2b481fe6c9..6d8da21b31 100644
--- a/developer/src/kmc/test/test-infrastructureMessages.ts
+++ b/developer/src/kmc/test/test-infrastructureMessages.ts
@@ -4,11 +4,15 @@ import { InfrastructureMessages } from '../src/messages/infrastructureMessages.j
import { verifyCompilerMessagesObject } from '@keymanapp/developer-test-helpers';
import { makePathToFixture } from './helpers/index.js';
import { NodeCompilerCallbacks } from '../src/util/NodeCompilerCallbacks.js';
-import { CompilerErrorNamespace, CompilerEvent } from '@keymanapp/common-types';
+import { CompilerErrorNamespace, CompilerEvent, KeymanFileTypes } from '@keymanapp/common-types';
import { unitTestEndpoints } from '../src/commands/build.js';
import { KmnCompilerMessages } from '@keymanapp/kmc-kmn';
import { clearOptions } from '@keymanapp/developer-utils';
import { loadProject } from '../src/util/projectLoader.js';
+import { defaultCompilerOptions, CompilerOptions} from '@keymanapp/common-types';
+import { analyzeUnitTestEndpoints } from '../src/commands/analyze.js';
+import { BuildKeyboardInfo } from '../src/commands/buildClasses/BuildKeyboardInfo.js';
+import { BuildModelInfo } from '../src/commands/buildClasses/BuildModelInfo.js';
describe('InfrastructureMessages', function () {
@@ -36,34 +40,47 @@ describe('InfrastructureMessages', function () {
assert.instanceOf(ncb.messages[0].exceptionVar, Error);
});
-/*
// ERROR_FileDoesNotExist
it('should generate ERROR_FileDoesNotExist if a file does not exist', async function() {
- await testForMessage(this, ['invalid-keyboards', 'error_file_does_not_exist.kmn'], CompilerMessages.ERROR_FileDoesNotExist);
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ await unitTestEndpoints.build(makePathToFixture('invalid-keyboards', 'Error_File_Does_Not_Exist.kmn'), '', ncb, {});
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_FileDoesNotExist),
+ 'ERROR_FileDoesNotExist not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
});
// ERROR_FileTypeNotRecognized
it('should generate ERROR_FileTypeNotRecognized if a file is not a recognized type', async function() {
- await testForMessage(this, ['invalid-keyboards', 'error_file_type_not_recognized.xxx'], CompilerMessages.ERROR_FileTypeNotRecognized);
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ await unitTestEndpoints.build(makePathToFixture('invalid-keyboards', 'error_file_type_not_recognized.xxx'), '', ncb, {});
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_FileTypeNotRecognized),
+ 'ERROR_FileTypeNotRecognized not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
});
// ERROR_OutFileNotValidForProjects
it('should generate ERROR_OutFileNotValidForProjects if an output file is specified for a project build', async function() {
- await testForMessage(this, ['invalid-keyboards', 'error_out_file_not_valid_for_projects.kpj'], CompilerMessages.ERROR_OutFileNotValidForProjects);
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ const projectPath = makePathToFixture('kpj-2.0/khmer_angkor', 'khmer_angkor.kpj');
+ const outFilePath = makePathToFixture('kpj-2.0/khmer_angkor', 'khmer_angkor.kmx');
+ const options: CompilerOptions = {...defaultCompilerOptions};
+ await unitTestEndpoints.build(projectPath, outFilePath, ncb, options);
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_OutFileNotValidForProjects),
+ 'ERROR_OutFileNotValidForProjects not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
});
// ERROR_InvalidProjectFile
it('should generate ERROR_InvalidProjectFile if a project file is invalid', async function() {
- await testForMessage(this, ['invalid-keyboards', 'error_invalid_project_file.kpj'], CompilerMessages.ERROR_InvalidProjectFile);
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ await unitTestEndpoints.build(makePathToFixture('invalid-projects', 'error_invalid_project_file.kpj'), '', ncb, {});
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_InvalidProjectFile),
+ 'ERROR_InvalidProjectFile not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
});
- */
// ERROR_InvalidProjectFolder (invalid source folder)
-
+
it('should generate ERROR_InvalidProjectFolder if there are no valid file types in the source folder when generating a default project file', async function() {
const projectPath = makePathToFixture('invalid-source-folder', 'error_invalid_project_folder.kpj')
const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
@@ -72,6 +89,93 @@ describe('InfrastructureMessages', function () {
`ERROR_FileTypeNotFound not generated, instead got: `+JSON.stringify(ncb.messages,null,2));
});
+ // ERROR_NotAProjectFile
+
+ it('should generate ERROR_NotAProjectFile if a project file is not the correct type', async function() {
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ const projectPath = makePathToFixture('invalid-projects', 'error_not_a_project_file.xxx')
+ loadProject(projectPath, ncb);
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_NotAProjectFile),
+ 'ERROR_NotAProjectFile not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ });
+
+ // ERROR_UnknownFileFormat
+
+ it('should generate ERROR_UnknownFileFormat if an analyze osk-char-use mapping file is not the correct type', async function() {
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ const options = {mappingFile: makePathToFixture('analyze', 'error_unknown_file_format.xxx')};
+ await analyzeUnitTestEndpoints.analyzeOskCharUse(ncb, [], options);
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_UnknownFileFormat),
+ 'ERROR_UnknownFileFormat not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ });
+
+ // ERROR_FileTypeNotFound (BuildKeyboardInfo)
+
+ it('should generate ERROR_FileTypeNotFound if a project file does not contain a .kps file entry (BuildKeyboardInfo)', async function() {
+ const buildKeyboardInfo = new BuildKeyboardInfo();
+ const projectPath = makePathToFixture('invalid-projects', 'error_file_type_not_found__keyboard.kpj')
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ await buildKeyboardInfo.build(projectPath, '', ncb, {});
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_FileTypeNotFound),
+ 'ERROR_FileTypeNotFound not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ });
+
+ // ERROR_FileTypeNotFound (BuildModelInfo; .model.ts)
+
+ it('should generate ERROR_FileTypeNotFound if a project file does not contain a .model.ts file entry (BuildModelInfo)', async function() {
+ const buildModelInfo = new BuildModelInfo();
+ const projectPath = makePathToFixture('invalid-projects', 'error_file_type_not_found__model_ts.kpj')
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ await buildModelInfo.build(projectPath, '', ncb, {});
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_FileTypeNotFound),
+ 'ERROR_FileTypeNotFound not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ assert.isTrue(nodeCompilerMessage(ncb, InfrastructureMessages.ERROR_FileTypeNotFound).includes(KeymanFileTypes.Source.Model),
+ KeymanFileTypes.Source.Model+' not found in the message');
+ });
+
+ // ERROR_FileTypeNotFound (BuildModelInfo; .kps)
+
+ it('should generate ERROR_FileTypeNotFound if a project file does not contain a .kps file entry (BuildModelInfo)', async function() {
+ const buildModelInfo = new BuildModelInfo();
+ const projectPath = makePathToFixture('invalid-projects', 'error_file_type_not_found__model_kps.kpj')
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ await buildModelInfo.build(projectPath, '', ncb, {});
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_FileTypeNotFound),
+ 'ERROR_FileTypeNotFound not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ assert.isTrue(nodeCompilerMessage(ncb, InfrastructureMessages.ERROR_FileTypeNotFound).includes(KeymanFileTypes.Source.Package),
+ KeymanFileTypes.Source.Package+' not found in the message');
+ });
+
+ // ERROR_InvalidProjectFolder (no source folder)
+ it('should generate ERROR_InvalidProjectFolder if there is no source folder when generating a default project file', async function() {
+ const projectPath = makePathToFixture('no-source-folder', 'error_invalid_project_folder.kpj')
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ loadProject(projectPath, ncb);
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_InvalidProjectFolder),
+ 'ERROR_InvalidProjectFolder not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ });
+
+ // ERROR_InvalidProjectFolder (invalid source folder)
+
+ it('should generate ERROR_InvalidProjectFolder if there are no valid file types in the source folder when generating a default project file', async function() {
+ const projectPath = makePathToFixture('invalid-source-folder', 'error_invalid_project_folder.kpj')
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ loadProject(projectPath, ncb);
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_InvalidProjectFolder),
+ 'ERROR_InvalidProjectFolder not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ });
+
+ // ERROR_CannotCreateFolder
+
+ it('should generate ERROR_CannotCreateFolder if the output folder cannot be created', async function() {
+ const buildKeyboardInfo = new BuildKeyboardInfo();
+ const targetFilename = makePathToFixture('invalid-projects', 'build', 'error_cannot_create_folder.xxx')
+ const ncb = new NodeCompilerCallbacks({logLevel: 'silent'});
+ buildKeyboardInfo['createOutputFolder'](targetFilename, ncb); // call private method
+ assert.isTrue(ncb.hasMessage(InfrastructureMessages.ERROR_CannotCreateFolder),
+ 'ERROR_CannotCreateFolder not generated, instead got: '+JSON.stringify(ncb.messages,null,2));
+ });
+
// HINT_FilenameHasDifferingCase
it('should generate HINT_FilenameHasDifferingCase if a referenced file has differing case', async function() {
@@ -117,4 +221,8 @@ function assertMessagesEqual(actualMessages: CompilerEvent[], expectedMessages:
assert.deepEqual(actualMessages.map(m => m.code), expectedMessages,
`actual callbacks.messages:\n${JSON.stringify(actualMessages,null,2)}\n\n`+
`did not match expected:\n${JSON.stringify(expectedMessages,null,2)}\n\n`);
+}
+
+function nodeCompilerMessage(ncb: NodeCompilerCallbacks, code: number): string {
+ return ncb.messages.find((item) => item.code == code).message ?? '';
}
\ No newline at end of file