Tests about support of HTML tags in translations keys with GetText (#172)
- Verify that html tags are supported in translation keys - Add typed support of gettext-parser
This commit is contained in:
		| @@ -100,3 +100,7 @@ Examples: | ||||
|   ngx-translate-extract -i './src/**/*.{ts,tsx,html}' -o strings.json     Extract from ts, tsx and html | ||||
|   ngx-translate-extract -i './src/**/!(*.spec).{ts,html}' -o              Extract from ts, html, excluding files with ".spec" | ||||
|   strings.json | ||||
|  | ||||
| ## Note for GetText users | ||||
|  | ||||
| Please pay attention of which version of `gettext-parser` you actually use in your project. For instance, `gettext-parser:1.2.2` does not support HTML tags in translation keys. | ||||
							
								
								
									
										9
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -136,6 +136,15 @@ | ||||
|       "integrity": "sha512-GcgAp7RXXGmA61spVEKZYpIy3/iV6GHbTW9f9kaKwHVQgnWitt6X026e+3N6j8ep1bkIWj83qPHQ3Y9Ft8FqiQ==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/gettext-parser": { | ||||
|       "version": "4.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/@types/gettext-parser/-/gettext-parser-4.0.0.tgz", | ||||
|       "integrity": "sha512-I/wvhr+l5M7IwBF1ADBfNQ6qGfUg85UTjj/AZWn09Y+POqyLe1cfbdJSMWzCobiJ3EJNY23MQCbP6jxQT81OTQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@types/node": "*" | ||||
|       } | ||||
|     }, | ||||
|     "@types/glob": { | ||||
|       "version": "7.1.1", | ||||
|       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", | ||||
|   | ||||
| @@ -69,6 +69,7 @@ | ||||
|     "@types/mocha": "^7.0.2", | ||||
|     "@types/node": "^12.12.31", | ||||
|     "@types/yargs": "^15.0.4", | ||||
|     "@types/gettext-parser": "4.0.0", | ||||
|     "braces": "^3.0.2", | ||||
|     "chai": "^4.2.0", | ||||
|     "husky": "^4.2.3", | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import { CompilerInterface } from './compiler.interface'; | ||||
| import { TranslationCollection, TranslationType } from '../utils/translation.collection'; | ||||
|  | ||||
| import * as gettext from 'gettext-parser'; | ||||
| import { po } from 'gettext-parser'; | ||||
|  | ||||
| export class PoCompiler implements CompilerInterface { | ||||
| 	public extension: string = 'po'; | ||||
| @@ -34,23 +34,24 @@ export class PoCompiler implements CompilerInterface { | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 		return gettext.po.compile(data); | ||||
| 		return po.compile(data).toString('utf8'); | ||||
| 	} | ||||
|  | ||||
| 	public parse(contents: string): TranslationCollection { | ||||
| 		const collection = new TranslationCollection(); | ||||
|  | ||||
| 		const po = gettext.po.parse(contents, 'utf8'); | ||||
| 		if (!po.translations.hasOwnProperty(this.domain)) { | ||||
| 		const parsedPo = po.parse(contents, 'utf8'); | ||||
|  | ||||
| 		if (!parsedPo.translations.hasOwnProperty(this.domain)) { | ||||
| 			return collection; | ||||
| 		} | ||||
|  | ||||
| 		const values = Object.keys(po.translations[this.domain]) | ||||
| 		const values = Object.keys(parsedPo.translations[this.domain]) | ||||
| 			.filter((key) => key.length > 0) | ||||
| 			.reduce((result, key) => { | ||||
| 				return { | ||||
| 					...result, | ||||
| 					[key]: po.translations[this.domain][key].msgstr.pop() | ||||
| 					[key]: parsedPo.translations[this.domain][key].msgstr.pop() | ||||
| 				}; | ||||
| 			}, {} as TranslationType); | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/declarations.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/declarations.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -1 +0,0 @@ | ||||
| declare module 'gettext-parser'; | ||||
							
								
								
									
										24
									
								
								tests/compilers/po.compiler.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								tests/compilers/po.compiler.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| import { expect } from 'chai'; | ||||
|  | ||||
| import { TranslationCollection } from '../../src/utils/translation.collection'; | ||||
| import { PoCompiler } from '../../src/compilers/po.compiler'; | ||||
|  | ||||
| describe('PoCompiler', () => { | ||||
| 	let compiler: PoCompiler; | ||||
|  | ||||
| 	beforeEach(() => { | ||||
| 		compiler = new PoCompiler(); | ||||
| 	}); | ||||
|  | ||||
| 	it('should still include html ', () => { | ||||
| 		const collection = new TranslationCollection({ | ||||
| 			'A <strong>test</strong>': 'Un <strong>test</strong>', | ||||
| 			'With a lot of <em>html</em> included': 'Avec beaucoup d\'<em>html</em> inclus' | ||||
| 		}); | ||||
| 		const result: Buffer = Buffer.from(compiler.compile(collection)); | ||||
| 		expect(result.toString('utf8')).to.equal('msgid ""\nmsgstr ""\n"mime-version: 1.0\\n"\n"Content-Type: text/plain; charset=utf-8\\n"\n"Content-Transfer-Encoding: 8bit\\n"\n\nmsgid "A <strong>test</strong>"\nmsgstr "Un <strong>test</strong>"\n\nmsgid "With a lot of <em>html</em> included"\nmsgstr "Avec beaucoup d\'<em>html</em> inclus"'); | ||||
| 	}); | ||||
| }); | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -36,6 +36,12 @@ describe('DirectiveParser', () => { | ||||
| 		expect(keys).to.deep.equal(['Hello <strong translate>World</strong>']); | ||||
| 	}); | ||||
|  | ||||
| 	it('should not exclude html tags in children', () => { | ||||
| 		const contents = `<div translate>Hello <strong>World</strong></div>`; | ||||
| 		const keys = parser.extract(contents, templateFilename).keys(); | ||||
| 		expect(keys).to.deep.equal(['Hello <strong>World</strong>']); | ||||
| 	}); | ||||
|  | ||||
| 	it('should extract and parse inline template', () => { | ||||
| 		const contents = ` | ||||
| 			@Component({ | ||||
|   | ||||
| @@ -36,6 +36,17 @@ describe('MarkerParser', () => { | ||||
| 		expect(keys).to.deep.equal(['Hello world', 'This is a very very very very long line.', 'Mix of different types']); | ||||
| 	}); | ||||
|  | ||||
| 	it('should extract split strings while keeping html tags', () => { | ||||
| 		const contents = ` | ||||
| 			import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; | ||||
| 			_('Hello ' + 'world'); | ||||
| 			_('This <em>is</em> a ' + 'very ' + 'very ' + 'very ' + 'very ' + 'long line.'); | ||||
| 			_('Mix ' + \`of \` + 'different ' + \`types\`); | ||||
| 		`; | ||||
| 		const keys = parser.extract(contents, componentFilename).keys(); | ||||
| 		expect(keys).to.deep.equal(['Hello world', 'This <em>is</em> a very very very very long line.', 'Mix of different types']); | ||||
| 	}); | ||||
|  | ||||
| 	it('should extract the strings', () => { | ||||
| 		const contents = ` | ||||
| 		import { marker } from '@biesbjerg/ngx-translate-extract-marker'; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user