From 4db660ecf6834fd79c8438b0d8c9e4724d86746b Mon Sep 17 00:00:00 2001 From: Gregor Biswanger Date: Sat, 4 Apr 2020 18:07:00 +0200 Subject: [PATCH] implement update translation files support --- src/assets/i18n/de.json | 37 ++++++++++++++++++++++++++++++ src/assets/i18n/en.json | 37 ++++++++++++++++++++++++++++++ src/exercise/index.ts | 22 +++++++++++++++++- src/spec/index.spec.ts | 24 +++++++++++++++++-- src/spec/stubs/assets/i18n/de.json | 37 ++++++++++++++++++++++++++++++ src/spec/stubs/assets/i18n/en.json | 37 ++++++++++++++++++++++++++++++ 6 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 src/assets/i18n/de.json create mode 100644 src/assets/i18n/en.json create mode 100644 src/spec/stubs/assets/i18n/de.json create mode 100644 src/spec/stubs/assets/i18n/en.json diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json new file mode 100644 index 0000000..1a19ef3 --- /dev/null +++ b/src/assets/i18n/de.json @@ -0,0 +1,37 @@ +{ + "APP": { + "FRUITS": { + "APPLE": "Apfel", + "BANANA": "Banane", + "CHERRY": "Kirsche" + }, + "ISTOMUCHFRUITS": "❌ Mehr Früchte als im Rezept angegeben sind!", + "LABELLEVEL": " von ", + "LABELRESET": "Zurücksetzen", + "NEXTBUTTON": "Weiter", + "OUTPUT": "Es gab einen Fehler mit deinem Code. Bitte mit F12 die Ausgabe in der Console überprüfen.", + "RECIPETITLE": "Rezept", + "STARTBUTTON": "Start" + }, + "EXERCISES": { + "DISTINCT": { + "RECIPEDESCRIPTION": "Es soll jede Frucht nur einmal gemixt werden. (Hinweis: Verwende distinct)" + }, + "EXERCISETITLE": "Übung", + "FILTER": { + "RECIPEDESCRIPTION": "Es sollen alle frischen Äpfel und Bananen gemixt werden. (Hinweis: Verwende filter)" + }, + "MAP": { + "RECIPEDESCRIPTION": "Es sollen alle Äpfel und Bananen vom dreck befreit werden. (Hinweis: Verwende map)" + }, + "SUBSCRIBE": { + "RECIPEDESCRIPTION": "" + }, + "SUBSCRIBE-NEXT": { + "RECIPEDESCRIPTION": "Es soll jede Frucht gemixt werden. (Hinweis: subscribe mit next)" + }, + "TAKE": { + "RECIPEDESCRIPTION": "Es sollen nur zwei Bananen gemixt werden. (Hinweis: Verwende take)" + } + } +} \ No newline at end of file diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json new file mode 100644 index 0000000..7411e39 --- /dev/null +++ b/src/assets/i18n/en.json @@ -0,0 +1,37 @@ +{ + "APP": { + "FRUITS": { + "APPLE": "Apple", + "BANANA": "Banana", + "CHERRY": "Cherry" + }, + "ISTOMUCHFRUITS": "❌ More fruits than specified in the recipe!", + "LABELLEVEL": " of ", + "LABELRESET": "Reset", + "NEXTBUTTON": "Next", + "OUTPUT": "There was an error with your code. Please use F12 to check the output in the console.", + "RECIPETITLE": "Recipe", + "STARTBUTTON": "Play" + }, + "EXERCISES": { + "DISTINCT": { + "RECIPEDESCRIPTION": "Each fruit should only be mixed once. (Note: use distinct)" + }, + "EXERCISETITLE": "Exercise", + "FILTER": { + "RECIPEDESCRIPTION": "All fresh apples and bananas should be mixed. (Note: use filter)" + }, + "MAP": { + "RECIPEDESCRIPTION": "All apples and bananas should be cleared of dirt. (Note: use map)" + }, + "SUBSCRIBE": { + "RECIPEDESCRIPTION": "" + }, + "SUBSCRIBE-NEXT": { + "RECIPEDESCRIPTION": "Every fruit should be mixed. (Note: subscribe with next)" + }, + "TAKE": { + "RECIPEDESCRIPTION": "Only two bananas should be mixed. (Note: use take)" + } + } +} \ No newline at end of file diff --git a/src/exercise/index.ts b/src/exercise/index.ts index 525cc6e..5e6d7c8 100644 --- a/src/exercise/index.ts +++ b/src/exercise/index.ts @@ -10,6 +10,7 @@ export function exercise(_options: Options): Rule { const chainedRule = chain([ createNewLevelEntry(_options), + createNewTranslationEntries(_options), createExerciseFiles(_options), createCypressIntegrationTest(_options), updateAppRoutingModule(_options) @@ -23,7 +24,7 @@ function detectNewLevelVersion(tree: Tree): number { const levelsPath = 'src/app/exercises/levels.json'; const levels: Level[] = JSON.parse(tree.read(levelsPath)?.toString() || ''); - const lastLevel: Level = [...levels].pop() || { title: '', number: 0, solved: false, urlPath: ''}; + const lastLevel: Level = [...levels].pop() || { title: '', number: 0, solved: false, urlPath: '' }; return lastLevel.number + 1 || 1; } @@ -46,6 +47,25 @@ function createNewLevelEntry(_options: Options): Rule { } } +function createNewTranslationEntries(_options: Options): Rule { + return (tree: Tree, _context: SchematicContext) => { + const i18nPath = 'src/assets/i18n'; + const subfiles = tree.getDir(i18nPath).subfiles; + + subfiles.forEach(fileName => { + const filePath = normalize(i18nPath + '/' + fileName); + const translationFile = JSON.parse(tree.read(filePath)?.toString() || ''); + translationFile.EXERCISES[strings.dasherize(_options.name).toUpperCase()] = { + "RECIPEDESCRIPTION": "lorem ipsum." + } + + tree.overwrite(filePath, JSON.stringify(translationFile)); + }); + + return tree; + } +} + function createExerciseFiles(_options: Options): Rule { const exercisePath = normalize('src' + '/' + 'app' + '/' + 'exercises' + '/' + _options.name); let exerciseFiles = url('./files/exercises/template'); diff --git a/src/spec/index.spec.ts b/src/spec/index.spec.ts index e33b462..4d81881 100644 --- a/src/spec/index.spec.ts +++ b/src/spec/index.spec.ts @@ -12,6 +12,8 @@ describe('rxjs-fruits-schematics - exercise command', () => { testTree = Tree.empty(); testTree.create('./src/app/app-routing.module.ts', fs.readFileSync('./src/spec/stubs/app/app-routing.module.ts', 'utf8')); testTree.create('./src/app/exercises/levels.json', fs.readFileSync('./src/spec/stubs/app/exercises/levels.json', 'utf8')); + testTree.create('./src/assets/i18n/de.json', fs.readFileSync('./src/spec/stubs/assets/i18n/de.json', 'utf8')); + testTree.create('./src/assets/i18n/en.json', fs.readFileSync('./src/spec/stubs/assets/i18n/en.json', 'utf8')); }); describe('when creating files', () => { @@ -19,7 +21,7 @@ describe('rxjs-fruits-schematics - exercise command', () => { const runner = new SchematicTestRunner('schematics', collectionPath); const tree = runner.runSchematic('exercise', { name: 'test' }, testTree); - expect(tree.files.length).toEqual(9); + expect(tree.files.length).toEqual(11); }); it('gives files the correct names.', () => { @@ -35,7 +37,9 @@ describe('rxjs-fruits-schematics - exercise command', () => { expect(tree.files[5]).toBe(`/src/app/exercises/${name}/${name}.component.scss`); expect(tree.files[6]).toBe(`/src/app/exercises/${name}/${name}.component.ts`); expect(tree.files[7]).toBe(`/src/app/exercises/${name}/${name}.module.ts`); - expect(tree.files[8]).toBe(`/cypress/integration/07_${name}.spec.ts`); + expect(tree.files[8]).toBe(`/src/assets/i18n/de.json`); + expect(tree.files[9]).toBe(`/src/assets/i18n/en.json`); + expect(tree.files[10]).toBe(`/cypress/integration/07_${name}.spec.ts`); }); }); @@ -69,6 +73,22 @@ describe('rxjs-fruits-schematics - exercise command', () => { "solved": false }); }); + + it('should create a new translation entry in de.json', () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = runner.runSchematic('exercise', { name: 'test' }, testTree); + const levelsContent = JSON.parse(tree.read('./src/assets/i18n/de.json')?.toString() || ''); + + expect(levelsContent.EXERCISES.TEST.RECIPEDESCRIPTION).toEqual("lorem ipsum."); + }); + + it('should create a new translation entry in en.json', () => { + const runner = new SchematicTestRunner('schematics', collectionPath); + const tree = runner.runSchematic('exercise', { name: 'test' }, testTree); + const levelsContent = JSON.parse(tree.read('./src/assets/i18n/en.json')?.toString() || ''); + + expect(levelsContent.EXERCISES.TEST.RECIPEDESCRIPTION).toEqual("lorem ipsum."); + }); }); }); diff --git a/src/spec/stubs/assets/i18n/de.json b/src/spec/stubs/assets/i18n/de.json new file mode 100644 index 0000000..f2374e3 --- /dev/null +++ b/src/spec/stubs/assets/i18n/de.json @@ -0,0 +1,37 @@ +{ + "APP": { + "FRUITS": { + "APPLE": "Apfel", + "BANANA": "Banane", + "CHERRY": "Kirsche" + }, + "ISTOMUCHFRUITS": "❌ Mehr Früchte als im Rezept angegeben sind!", + "LABELLEVEL": " von ", + "LABELRESET": "Zurücksetzen", + "NEXTBUTTON": "Weiter", + "OUTPUT": "Es gab einen Fehler mit deinem Code. Bitte mit F12 die Ausgabe in der Console überprüfen.", + "RECIPETITLE": "Rezept", + "STARTBUTTON": "Start" + }, + "EXERCISES": { + "DISTINCT": { + "RECIPEDESCRIPTION": "Es soll jede Frucht nur einmal gemixt werden. (Hinweis: Verwende distinct)" + }, + "EXERCISETITLE": "Übung", + "FILTER": { + "RECIPEDESCRIPTION": "Es sollen alle frischen Äpfel und Bananen gemixt werden. (Hinweis: Verwende filter)" + }, + "MAP": { + "RECIPEDESCRIPTION": "Es sollen alle Äpfel und Bananen vom dreck befreit werden. (Hinweis: Verwende map)" + }, + "SUBSCRIBE": { + "RECIPEDESCRIPTION": "" + }, + "SUBSCRIBE-NEXT": { + "RECIPEDESCRIPTION": "Es soll jede Frucht gemixt werden. (Hinweis: subscribe mit next)" + }, + "TAKE": { + "RECIPEDESCRIPTION": "Es sollen nur zwei Bananen gemixt werden. (Hinweis: Verwende take)" + } + } +} diff --git a/src/spec/stubs/assets/i18n/en.json b/src/spec/stubs/assets/i18n/en.json new file mode 100644 index 0000000..6c3cf09 --- /dev/null +++ b/src/spec/stubs/assets/i18n/en.json @@ -0,0 +1,37 @@ +{ + "APP": { + "FRUITS": { + "APPLE": "Apple", + "BANANA": "Banana", + "CHERRY": "Cherry" + }, + "ISTOMUCHFRUITS": "❌ More fruits than specified in the recipe!", + "LABELLEVEL": " of ", + "LABELRESET": "Reset", + "NEXTBUTTON": "Next", + "OUTPUT": "There was an error with your code. Please use F12 to check the output in the console.", + "RECIPETITLE": "Recipe", + "STARTBUTTON": "Play" + }, + "EXERCISES": { + "DISTINCT": { + "RECIPEDESCRIPTION": "Each fruit should only be mixed once. (Note: use distinct)" + }, + "EXERCISETITLE": "Exercise", + "FILTER": { + "RECIPEDESCRIPTION": "All fresh apples and bananas should be mixed. (Note: use filter)" + }, + "MAP": { + "RECIPEDESCRIPTION": "All apples and bananas should be cleared of dirt. (Note: use map)" + }, + "SUBSCRIBE": { + "RECIPEDESCRIPTION": "" + }, + "SUBSCRIBE-NEXT": { + "RECIPEDESCRIPTION": "Every fruit should be mixed. (Note: subscribe with next)" + }, + "TAKE": { + "RECIPEDESCRIPTION": "Only two bananas should be mixed. (Note: use take)" + } + } +}