diff --git a/README.md b/README.md index e8f62b68..382421f7 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ ngx-translate-extract [options] Output --format, -f Format [string] [choices: "json", "namespaced-json", "pot"] [default: "json"] --format-indentation, --fi Format indentation (JSON/Namedspaced JSON) [string] [default: " "] - --sort, -s Sort strings in alphabetical order [boolean] + --sort, -s Sort strings in alphabetical order [string] [choices: "", "case-insensitive"] --clean, -c Remove obsolete strings after merge [boolean] --replace, -r Replace the contents of output file if it exists (Merges by default) [boolean] diff --git a/src/cli/cli.ts b/src/cli/cli.ts index d3df4b37..d28b1ed9 100755 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -8,7 +8,7 @@ import { DirectiveParser } from '../parsers/directive.parser'; import { ServiceParser } from '../parsers/service.parser'; import { MarkerParser } from '../parsers/marker.parser'; import { PostProcessorInterface } from '../post-processors/post-processor.interface'; -import { SortByKeyPostProcessor } from '../post-processors/sort-by-key.post-processor'; +import { SortByKeyPostProcessor, SortOptions } from '../post-processors/sort-by-key.post-processor'; import { KeyAsDefaultValuePostProcessor } from '../post-processors/key-as-default-value.post-processor'; import { NullAsDefaultValuePostProcessor } from '../post-processors/null-as-default-value.post-processor'; import { StringAsDefaultValuePostProcessor } from '../post-processors/string-as-default-value.post-processor'; @@ -79,7 +79,8 @@ export const cli = y .option('sort', { alias: 's', describe: 'Sort strings in alphabetical order', - type: 'boolean' + type: 'string', + choices: ['', 'case-insensitive'] }) .option('clean', { alias: 'c', @@ -138,8 +139,8 @@ if (cli.keyAsDefaultValue) { postProcessors.push(new StringAsDefaultValuePostProcessor({ defaultValue: cli.stringAsDefaultValue as string })); } -if (cli.sort) { - postProcessors.push(new SortByKeyPostProcessor()); +if (typeof cli.sort !== 'undefined') { + postProcessors.push(new SortByKeyPostProcessor(cli.sort as SortOptions)); } extractTask.setPostProcessors(postProcessors); diff --git a/src/post-processors/sort-by-key.post-processor.ts b/src/post-processors/sort-by-key.post-processor.ts index df4f50a8..6b1ae2bf 100644 --- a/src/post-processors/sort-by-key.post-processor.ts +++ b/src/post-processors/sort-by-key.post-processor.ts @@ -1,10 +1,21 @@ import { TranslationCollection } from '../utils/translation.collection'; import { PostProcessorInterface } from './post-processor.interface'; +export type SortOptions = '' | 'case-insensitive'; + export class SortByKeyPostProcessor implements PostProcessorInterface { public name: string = 'SortByKey'; + constructor(private sortOptions: SortOptions) { } + public process(draft: TranslationCollection, extracted: TranslationCollection, existing: TranslationCollection): TranslationCollection { - return draft.sort(); + if (this.sortOptions === 'case-insensitive') { + return draft.sort((a, b) => { + return a.toLowerCase().localeCompare(b.toLowerCase()); + }); + } else { + return draft.sort(); + } } } + diff --git a/tests/post-processors/sort-by-key.post-processor.spec.ts b/tests/post-processors/sort-by-key.post-processor.spec.ts index b1a33ea9..4eb75489 100644 --- a/tests/post-processors/sort-by-key.post-processor.spec.ts +++ b/tests/post-processors/sort-by-key.post-processor.spec.ts @@ -4,28 +4,51 @@ import { PostProcessorInterface } from '../../src/post-processors/post-processor import { SortByKeyPostProcessor } from '../../src/post-processors/sort-by-key.post-processor'; import { TranslationCollection } from '../../src/utils/translation.collection'; +const mock = { + ZZ: 'last value', + a: 'a value', + '9': 'a numeric key', + b: 'another value' +}; + + describe('SortByKeyPostProcessor', () => { let processor: PostProcessorInterface; + let collection: TranslationCollection; + let extracted: TranslationCollection; + let existing: TranslationCollection; beforeEach(() => { - processor = new SortByKeyPostProcessor(); + collection = new TranslationCollection(mock); + extracted = new TranslationCollection(); + existing = new TranslationCollection(); }); - it('should sort keys alphanumerically', () => { - const collection = new TranslationCollection({ - z: 'last value', - a: 'a value', + it('should sort keys alphanumerically (case sensitive)', () => { + processor = new SortByKeyPostProcessor(''); + const sorted = processor.process(collection, extracted, existing).values; + + const sortedOutput = { '9': 'a numeric key', + ZZ: 'last value', + a: 'a value', b: 'another value' - }); - const extracted = new TranslationCollection(); - const existing = new TranslationCollection(); + }; - expect(processor.process(collection, extracted, existing).values).to.deep.equal({ + expect(JSON.stringify(sorted)).to.deep.equal(JSON.stringify(sortedOutput)); + }); + + it('should sort keys alphanumerically (case insensitive)', () => { + processor = new SortByKeyPostProcessor('case-insensitive'); + const sorted = processor.process(collection, extracted, existing).values; + + const sortedOutput = { '9': 'a numeric key', a: 'a value', b: 'another value', - z: 'last value' - }); + ZZ: 'last value' + }; + + expect(JSON.stringify(sorted)).to.deep.equal(JSON.stringify(sortedOutput)); }); });