Add StringCollection to make it easier to work with strings
This commit is contained in:
		| @@ -34,10 +34,10 @@ var destination = path.join(options.output, filename); | |||||||
|  |  | ||||||
| try { | try { | ||||||
| 	var extractor = new Extractor(serializer); | 	var extractor = new Extractor(serializer); | ||||||
| 	var messages = extractor.extract(options.dir); | 	var collection = extractor.process(options.dir); | ||||||
| 	if (messages.length > 0) { | 	if (collection.count() > 0) { | ||||||
| 		extractor.save(destination); | 		extractor.save(destination); | ||||||
| 		cli.ok(`Extracted ${messages.length} strings: '${destination}'`); | 		cli.ok(`Extracted ${collection.count()} strings: '${destination}'`); | ||||||
| 	} else { | 	} else { | ||||||
| 		cli.info(`Found no extractable strings in the supplied directory path: '${options.dir}'`); | 		cli.info(`Found no extractable strings in the supplied directory path: '${options.dir}'`); | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -46,7 +46,6 @@ | |||||||
|     "@types/chai": "^3.4.34", |     "@types/chai": "^3.4.34", | ||||||
|     "@types/cheerio": "^0.17.31", |     "@types/cheerio": "^0.17.31", | ||||||
|     "@types/glob": "^5.0.30", |     "@types/glob": "^5.0.30", | ||||||
|     "@types/lodash": "^4.14.41", |  | ||||||
|     "@types/mocha": "^2.2.33", |     "@types/mocha": "^2.2.33", | ||||||
|     "chai": "^3.5.0", |     "chai": "^3.5.0", | ||||||
|     "mocha": "^3.2.0", |     "mocha": "^3.2.0", | ||||||
| @@ -60,7 +59,6 @@ | |||||||
|     "cli": "^1.0.1", |     "cli": "^1.0.1", | ||||||
|     "fs": "0.0.1-security", |     "fs": "0.0.1-security", | ||||||
|     "glob": "^7.1.1", |     "glob": "^7.1.1", | ||||||
|     "lodash": "^4.17.2", |  | ||||||
|     "path": "^0.12.7" |     "path": "^0.12.7" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,17 +1,17 @@ | |||||||
| import { Extractor } from './extractor'; | import { Extractor } from './extractor'; | ||||||
| import { JsonSerializer } from './serializers/json.serializer'; | import { JsonSerializer } from './serializers/json.serializer'; | ||||||
|  | import { StringCollection } from './utils/string.collection'; | ||||||
|  |  | ||||||
| const serializer = new JsonSerializer(); | const serializer = new JsonSerializer(); | ||||||
| // Or const serializer = new PotSerializer(); |  | ||||||
| const extractor = new Extractor(serializer); | const extractor = new Extractor(serializer); | ||||||
|  |  | ||||||
| const src = '/your/project'; | const src = '/your/project'; | ||||||
| const dest = '/your/project/template.json'; | const dest = '/your/project/template.json'; | ||||||
|  |  | ||||||
| try { | try { | ||||||
| 	const messages: string[] = extractor.extract(src); | 	const collection: StringCollection = extractor.process(src); | ||||||
| 	const output: string = extractor.save(dest); | 	const output: string = extractor.save(dest); | ||||||
| 	console.log({ messages, output }); | 	console.log({ strings: collection.keys(), output: output }); | ||||||
| } catch (e) { | } catch (e) { | ||||||
| 	console.log(`Something went wrong: ${e.toString()}`); | 	console.log(`Something went wrong: ${e.toString()}`); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,8 +3,8 @@ import { PipeParser } from './parsers/pipe.parser'; | |||||||
| import { DirectiveParser } from './parsers/directive.parser'; | import { DirectiveParser } from './parsers/directive.parser'; | ||||||
| import { ServiceParser } from './parsers/service.parser'; | import { ServiceParser } from './parsers/service.parser'; | ||||||
| import { SerializerInterface } from './serializers/serializer.interface'; | import { SerializerInterface } from './serializers/serializer.interface'; | ||||||
|  | import { StringCollection } from './utils/string.collection'; | ||||||
|  |  | ||||||
| import * as lodash from 'lodash'; |  | ||||||
| import * as glob from 'glob'; | import * as glob from 'glob'; | ||||||
| import * as fs from 'fs'; | import * as fs from 'fs'; | ||||||
|  |  | ||||||
| @@ -16,35 +16,35 @@ export class Extractor { | |||||||
| 		new ServiceParser() | 		new ServiceParser() | ||||||
| 	]; | 	]; | ||||||
|  |  | ||||||
| 	public globPatterns: string[] = [ | 	public find: string[] = [ | ||||||
| 		'/**/*.html', | 		'/**/*.html', | ||||||
| 		'/**/*.ts', | 		'/**/*.ts', | ||||||
| 		'/**/*.js' | 		'/**/*.js' | ||||||
| 	]; | 	]; | ||||||
|  |  | ||||||
| 	public messages: string[] = []; | 	public collection: StringCollection = new StringCollection(); | ||||||
|  |  | ||||||
| 	public constructor(public serializer: SerializerInterface) { } | 	public constructor(public serializer: SerializerInterface) { } | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Extracts messages from paths | 	 * Process dir | ||||||
| 	 */ | 	 */ | ||||||
| 	public extract(dir: string): string[] { | 	public process(dir: string): StringCollection { | ||||||
| 		let messages = []; | 		this._getFiles(dir).forEach(path => { | ||||||
|  | 			const contents: string = fs.readFileSync(path, 'utf-8'); | ||||||
| 		this._getFiles(dir).forEach(filePath => { | 			this.parsers.forEach((parser: ParserInterface) => { | ||||||
| 			const result = this._extractMessages(filePath); | 				this.collection.merge(parser.extract(contents, path)); | ||||||
| 			messages = [...messages, ...result]; | 			}); | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		return this.messages = lodash.uniq(messages); | 		return this.collection; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| 	 * Serialize and return output | 	 * Serialize and return output | ||||||
| 	 */ | 	 */ | ||||||
| 	public serialize(): string { | 	public serialize(): string { | ||||||
| 		return this.serializer.serialize(this.messages); | 		return this.serializer.serialize(this.collection); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
| @@ -62,10 +62,10 @@ export class Extractor { | |||||||
| 	protected _getFiles(dir: string): string[] { | 	protected _getFiles(dir: string): string[] { | ||||||
| 		let results: string[] = []; | 		let results: string[] = []; | ||||||
|  |  | ||||||
| 		this.globPatterns.forEach(globPattern => { | 		this.find.forEach(pattern => { | ||||||
| 			const files = glob | 			const files = glob | ||||||
| 				.sync(dir + globPattern) | 				.sync(dir + pattern) | ||||||
| 				.filter(filePath => fs.statSync(filePath).isFile()); | 				.filter(path => fs.statSync(path).isFile()); | ||||||
|  |  | ||||||
| 			results = [...results, ...files]; | 			results = [...results, ...files]; | ||||||
| 		}); | 		}); | ||||||
| @@ -73,18 +73,4 @@ export class Extractor { | |||||||
| 		return results; | 		return results; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** |  | ||||||
| 	 * Extract messages from file using parser |  | ||||||
| 	 */ |  | ||||||
| 	protected _extractMessages(filePath: string): string[] { |  | ||||||
| 		let results: string[] = []; |  | ||||||
|  |  | ||||||
| 		const contents: string = fs.readFileSync(filePath, 'utf-8'); |  | ||||||
| 		this.parsers.forEach((parser: ParserInterface) => { |  | ||||||
| 			results = [...results, ...parser.process(filePath, contents)]; |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		return results; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ export abstract class AbstractTemplateParser { | |||||||
| 	 * Checks if file is of type javascript or typescript and | 	 * Checks if file is of type javascript or typescript and | ||||||
| 	 * makes the assumption that it is an Angular Component | 	 * makes the assumption that it is an Angular Component | ||||||
| 	 */ | 	 */ | ||||||
| 	protected _isAngularComponent(filePath: string): boolean { | 	protected _isAngularComponent(path: string): boolean { | ||||||
| 		return new RegExp(/\.(ts|js)$/, 'i').test(filePath); | 		return new RegExp(/\.(ts|js)$/, 'i').test(path); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
|   | |||||||
| @@ -1,20 +1,21 @@ | |||||||
| import { ParserInterface } from './parser.interface'; | import { ParserInterface } from './parser.interface'; | ||||||
| import { AbstractTemplateParser } from './abstract-template.parser'; | import { AbstractTemplateParser } from './abstract-template.parser'; | ||||||
|  | import { StringCollection } from '../utils/string.collection'; | ||||||
|  |  | ||||||
| import * as $ from 'cheerio'; | import * as $ from 'cheerio'; | ||||||
|  |  | ||||||
| export class DirectiveParser extends AbstractTemplateParser implements ParserInterface { | export class DirectiveParser extends AbstractTemplateParser implements ParserInterface { | ||||||
|  |  | ||||||
| 	public process(filePath: string, contents: string): string[] { | 	public extract(contents: string, path?: string): StringCollection { | ||||||
| 		if (this._isAngularComponent(filePath)) { | 		if (path && this._isAngularComponent(path)) { | ||||||
| 			contents = this._extractInlineTemplate(contents); | 			contents = this._extractInlineTemplate(contents); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return this._parseTemplate(contents); | 		return this._parseTemplate(contents); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	protected _parseTemplate(template: string): string[] { | 	protected _parseTemplate(template: string): StringCollection { | ||||||
| 		let results: string[] = []; | 		const collection = new StringCollection(); | ||||||
|  |  | ||||||
| 		template = this._normalizeTemplateAttributes(template); | 		template = this._normalizeTemplateAttributes(template); | ||||||
| 		$(template) | 		$(template) | ||||||
| @@ -25,7 +26,7 @@ export class DirectiveParser extends AbstractTemplateParser implements ParserInt | |||||||
| 				const attr = $element.attr('translate') || $element.attr('ng2-translate'); | 				const attr = $element.attr('translate') || $element.attr('ng2-translate'); | ||||||
|  |  | ||||||
| 				if (attr) { | 				if (attr) { | ||||||
| 					results.push(attr); | 					collection.add(attr); | ||||||
| 				} else { | 				} else { | ||||||
| 					$element | 					$element | ||||||
| 						.contents() | 						.contents() | ||||||
| @@ -33,11 +34,11 @@ export class DirectiveParser extends AbstractTemplateParser implements ParserInt | |||||||
| 						.filter(textNode => textNode.type === 'text') | 						.filter(textNode => textNode.type === 'text') | ||||||
| 						.map(textNode => textNode.nodeValue.trim()) | 						.map(textNode => textNode.nodeValue.trim()) | ||||||
| 						.filter(text => text.length > 0) | 						.filter(text => text.length > 0) | ||||||
| 						.forEach(text => results.push(text)); | 						.forEach(text => collection.add(text)); | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
|  |  | ||||||
| 		return results; | 		return collection; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
|  | import { StringCollection } from '../utils/string.collection'; | ||||||
|  |  | ||||||
| export interface ParserInterface { | export interface ParserInterface { | ||||||
|  |  | ||||||
| 	process(filePath: string, contents: string): string[]; | 	extract(contents: string, path?: string): StringCollection; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,27 +1,28 @@ | |||||||
| import { ParserInterface } from './parser.interface'; | import { ParserInterface } from './parser.interface'; | ||||||
| import { AbstractTemplateParser } from './abstract-template.parser'; | import { AbstractTemplateParser } from './abstract-template.parser'; | ||||||
|  | import { StringCollection } from '../utils/string.collection'; | ||||||
|  |  | ||||||
| export class PipeParser extends AbstractTemplateParser implements ParserInterface { | export class PipeParser extends AbstractTemplateParser implements ParserInterface { | ||||||
|  |  | ||||||
| 	public process(filePath: string, contents: string): string[] { | 	public extract(contents: string, path?: string): StringCollection { | ||||||
| 		if (this._isAngularComponent(filePath)) { | 		if (path && this._isAngularComponent(path)) { | ||||||
| 			contents = this._extractInlineTemplate(contents); | 			contents = this._extractInlineTemplate(contents); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return this._parseTemplate(contents); | 		return this._parseTemplate(contents); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	protected _parseTemplate(template: string): string[] { | 	protected _parseTemplate(template: string): StringCollection { | ||||||
| 		let results: string[] = []; | 		const collection = new StringCollection(); | ||||||
|  |  | ||||||
| 		const regExp = new RegExp(/([\'"`])([^\1\r\n]*)\1\s+\|\s*translate(:.*?)?/, 'g'); | 		const regExp = new RegExp(/([\'"`])([^\1\r\n]*)\1\s+\|\s*translate(:.*?)?/, 'g'); | ||||||
|  |  | ||||||
| 		let matches; | 		let matches; | ||||||
| 		while (matches = regExp.exec(template)) { | 		while (matches = regExp.exec(template)) { | ||||||
| 			results.push(matches[2]); | 			collection.add(matches[2]); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return results; | 		return collection; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,13 +1,14 @@ | |||||||
| import { ParserInterface } from './parser.interface'; | import { ParserInterface } from './parser.interface'; | ||||||
|  | import { StringCollection } from '../utils/string.collection'; | ||||||
|  |  | ||||||
| export class ServiceParser implements ParserInterface { | export class ServiceParser implements ParserInterface { | ||||||
|  |  | ||||||
| 	public process(filePath: string, contents: string): string[] { | 	public extract(contents: string, path?: string): StringCollection { | ||||||
| 		let results: string[] = []; | 		const collection = new StringCollection(); | ||||||
|  |  | ||||||
| 		const translateServiceVar = this._extractTranslateServiceVar(contents); | 		const translateServiceVar = this._extractTranslateServiceVar(contents); | ||||||
| 		if (!translateServiceVar) { | 		if (!translateServiceVar) { | ||||||
| 			return results; | 			return collection; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		const methodRegExp: RegExp = new RegExp(/(?:get|instant)\s*\(\s*(\[?([\'"`])([^\1\r\n]+)\2\]?)/); | 		const methodRegExp: RegExp = new RegExp(/(?:get|instant)\s*\(\s*(\[?([\'"`])([^\1\r\n]+)\2\]?)/); | ||||||
| @@ -16,13 +17,13 @@ export class ServiceParser implements ParserInterface { | |||||||
| 		let matches; | 		let matches; | ||||||
| 		while (matches = regExp.exec(contents)) { | 		while (matches = regExp.exec(contents)) { | ||||||
| 			if (this._stringContainsArray(matches[1])) { | 			if (this._stringContainsArray(matches[1])) { | ||||||
| 				results.push(...this._stringToArray(matches[1])); | 				collection.add(this._stringToArray(matches[1])); | ||||||
| 			} else { | 			} else { | ||||||
| 				results.push(matches[3]); | 				collection.add(matches[3]); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return results; | 		return collection; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/** | 	/** | ||||||
|   | |||||||
| @@ -1,14 +1,10 @@ | |||||||
| import { SerializerInterface } from './serializer.interface'; | import { SerializerInterface } from './serializer.interface'; | ||||||
|  | import { StringCollection } from '../utils/string.collection'; | ||||||
|  |  | ||||||
| export class JsonSerializer implements SerializerInterface { | export class JsonSerializer implements SerializerInterface { | ||||||
|  |  | ||||||
| 	public serialize(messages: string[]): string { | 	public serialize(collection: StringCollection): string { | ||||||
| 		let result = {}; | 		return JSON.stringify(collection.values, null, '\t'); | ||||||
| 		messages.forEach(message => { |  | ||||||
| 			result[message] = ''; |  | ||||||
| 		}); |  | ||||||
|  |  | ||||||
| 		return JSON.stringify(result, null, '\t'); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| import { SerializerInterface } from './serializer.interface'; | import { SerializerInterface } from './serializer.interface'; | ||||||
|  | import { StringCollection } from '../utils/string.collection'; | ||||||
|  |  | ||||||
| export class PotSerializer implements SerializerInterface { | export class PotSerializer implements SerializerInterface { | ||||||
|  |  | ||||||
| @@ -9,10 +10,10 @@ export class PotSerializer implements SerializerInterface { | |||||||
|  |  | ||||||
| 	protected _buffer: string[] = []; | 	protected _buffer: string[] = []; | ||||||
|  |  | ||||||
| 	public serialize(messages: string[]): string { | 	public serialize(collection: StringCollection): string { | ||||||
| 		this._reset(); | 		this._reset(); | ||||||
| 		this._addHeader(this._headers); | 		this._addHeader(this._headers); | ||||||
| 		this._addMessages(messages); | 		this._addMessages(collection); | ||||||
|  |  | ||||||
| 		return this._buffer.join('\n'); | 		return this._buffer.join('\n'); | ||||||
| 	} | 	} | ||||||
| @@ -25,10 +26,10 @@ export class PotSerializer implements SerializerInterface { | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	protected _addMessages(messages: string[]): void { | 	protected _addMessages(collection: StringCollection): void { | ||||||
| 		messages.forEach(message => { | 		Object.keys(collection.values).forEach(key => { | ||||||
| 			this._add('msgid', message); | 			this._add('msgid', key); | ||||||
| 			this._add('msgstr', ''); | 			this._add('msgstr', collection.get(key)); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
|  | import { StringCollection } from '../utils/string.collection'; | ||||||
|  |  | ||||||
| export interface SerializerInterface { | export interface SerializerInterface { | ||||||
|  |  | ||||||
| 	serialize(messages: string[]): string; | 	serialize(collection: StringCollection): string; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										51
									
								
								src/utils/string.collection.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/utils/string.collection.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | export interface StringType { | ||||||
|  | 	[key: string]: string | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export class StringCollection { | ||||||
|  |  | ||||||
|  | 	public values: StringType = {}; | ||||||
|  |  | ||||||
|  | 	public static fromObject(values: StringType): StringCollection { | ||||||
|  | 		const collection = new StringCollection(); | ||||||
|  | 		Object.keys(values).forEach(key => collection.add(key, values[key])); | ||||||
|  | 		return collection; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public static fromArray(keys: string[]): StringCollection { | ||||||
|  | 		const collection = new StringCollection(); | ||||||
|  | 		keys.forEach(key => collection.add(key)); | ||||||
|  | 		return collection; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public add(keys: string | string[], val: string = ''): StringCollection { | ||||||
|  | 		if (!Array.isArray(keys)) { | ||||||
|  | 			keys = [keys]; | ||||||
|  | 		} | ||||||
|  | 		keys.forEach(key => this.values[key] = val); | ||||||
|  | 		return this; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public remove(key: string): StringCollection { | ||||||
|  | 		delete this.values[key]; | ||||||
|  | 		return this; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public merge(collection: StringCollection): StringCollection { | ||||||
|  | 		this.values = Object.assign({}, this.values, collection.values); | ||||||
|  | 		return this; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public get(key: string): string { | ||||||
|  | 		return this.values[key]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public keys(): string[] { | ||||||
|  | 		return Object.keys(this.values); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	public count(): number { | ||||||
|  | 		return Object.keys(this.values).length; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -15,20 +15,20 @@ describe('DirectiveParser', () => { | |||||||
|  |  | ||||||
| 	it('should extract contents when no translate attribute value is provided', () => { | 	it('should extract contents when no translate attribute value is provided', () => { | ||||||
| 		const contents = '<div translate>Hello World</div>'; | 		const contents = '<div translate>Hello World</div>'; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World']); | 		expect(keys).to.deep.equal(['Hello World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract translate attribute if provided', () => { | 	it('should extract translate attribute if provided', () => { | ||||||
| 		const contents = '<div translate="KEY">Hello World<div>'; | 		const contents = '<div translate="KEY">Hello World<div>'; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['KEY']); | 		expect(keys).to.deep.equal(['KEY']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract bound translate attribute as key if provided', () => { | 	it('should extract bound translate attribute as key if provided', () => { | ||||||
| 		const contents = `<div [translate]="'KEY'">Hello World<div>`; | 		const contents = `<div [translate]="'KEY'">Hello World<div>`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['KEY']); | 		expect(keys).to.deep.equal(['KEY']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract direct text nodes when no translate attribute value is provided', () => { | 	it('should extract direct text nodes when no translate attribute value is provided', () => { | ||||||
| @@ -39,8 +39,8 @@ describe('DirectiveParser', () => { | |||||||
| 				Hi <em>there</em> | 				Hi <em>there</em> | ||||||
| 			</div> | 			</div> | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello', 'Hi']); | 		expect(keys).to.deep.equal(['Hello', 'Hi']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract direct text nodes of tags with a translate attribute', () => { | 	it('should extract direct text nodes of tags with a translate attribute', () => { | ||||||
| @@ -51,8 +51,8 @@ describe('DirectiveParser', () => { | |||||||
| 				<div translate>Hi there</div> | 				<div translate>Hi there</div> | ||||||
| 			</div> | 			</div> | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World', 'Hi there']); | 		expect(keys).to.deep.equal(['Hello World', 'Hi there']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract translate attribute if provided or direct text nodes if not', () => { | 	it('should extract translate attribute if provided or direct text nodes if not', () => { | ||||||
| @@ -64,8 +64,8 @@ describe('DirectiveParser', () => { | |||||||
| 				<p [translate]="'OTHER_KEY'">Lorem Ipsum</p> | 				<p [translate]="'OTHER_KEY'">Lorem Ipsum</p> | ||||||
| 			</div> | 			</div> | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['KEY', 'Hi there', 'OTHER_KEY']); | 		expect(keys).to.deep.equal(['KEY', 'Hi there', 'OTHER_KEY']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract and parse inline template', () => { | 	it('should extract and parse inline template', () => { | ||||||
| @@ -76,26 +76,26 @@ describe('DirectiveParser', () => { | |||||||
| 			}) | 			}) | ||||||
| 			export class TestComponent { } | 			export class TestComponent { } | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(componentFilename, contents); | 		const keys = parser.extract(contents, componentFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World']); | 		expect(keys).to.deep.equal(['Hello World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract contents when no ng2-translate attribute value is provided', () => { | 	it('should extract contents when no ng2-translate attribute value is provided', () => { | ||||||
| 		const contents = '<div ng2-translate>Hello World</div>'; | 		const contents = '<div ng2-translate>Hello World</div>'; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World']); | 		expect(keys).to.deep.equal(['Hello World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract ng2-translate attribute if provided', () => { | 	it('should extract ng2-translate attribute if provided', () => { | ||||||
| 		const contents = '<div ng2-translate="KEY">Hello World<div>'; | 		const contents = '<div ng2-translate="KEY">Hello World<div>'; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['KEY']); | 		expect(keys).to.deep.equal(['KEY']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract bound ng2-translate attribute as key if provided', () => { | 	it('should extract bound ng2-translate attribute as key if provided', () => { | ||||||
| 		const contents = `<div [ng2-translate]="'KEY'">Hello World<div>`; | 		const contents = `<div [ng2-translate]="'KEY'">Hello World<div>`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['KEY']); | 		expect(keys).to.deep.equal(['KEY']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -14,20 +14,20 @@ describe('PipeParser', () => { | |||||||
|  |  | ||||||
| 	it('should extract interpolated strings using translate pipe', () => { | 	it('should extract interpolated strings using translate pipe', () => { | ||||||
| 		const contents = `Hello {{ 'World' | translate }}`; | 		const contents = `Hello {{ 'World' | translate }}`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['World']); | 		expect(keys).to.deep.equal(['World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract interpolated strings using translate pipe in attributes', () => { | 	it('should extract interpolated strings using translate pipe in attributes', () => { | ||||||
| 		const contents = `<span attr="{{ 'Hello World' | translate }}"></span>`; | 		const contents = `<span attr="{{ 'Hello World' | translate }}"></span>`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World']); | 		expect(keys).to.deep.equal(['Hello World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract bound strings using translate pipe in attributes', () => { | 	it('should extract bound strings using translate pipe in attributes', () => { | ||||||
| 		const contents = `<span [attr]="'Hello World' | translate"></span>`; | 		const contents = `<span [attr]="'Hello World' | translate"></span>`; | ||||||
| 		const messages = parser.process(templateFilename, contents); | 		const keys = parser.extract(contents, templateFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World']); | 		expect(keys).to.deep.equal(['Hello World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| }); | }); | ||||||
|   | |||||||
| @@ -30,8 +30,8 @@ describe('ServiceParser', () => { | |||||||
| 					protected _translateService: TranslateService | 					protected _translateService: TranslateService | ||||||
| 			) { } | 			) { } | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.extractTranslateServiceVar(contents); | 		const name = parser.extractTranslateServiceVar(contents); | ||||||
| 		expect(messages).to.equal('_translateService'); | 		expect(name).to.equal('_translateService'); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract strings in TranslateService\'s get() method', () => { | 	it('should extract strings in TranslateService\'s get() method', () => { | ||||||
| @@ -43,8 +43,8 @@ describe('ServiceParser', () => { | |||||||
| 					this._translateService.get('Hello World'); | 					this._translateService.get('Hello World'); | ||||||
| 				} | 				} | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(componentFilename, contents); | 		const keys = parser.extract(contents, componentFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World']); | 		expect(keys).to.deep.equal(['Hello World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract strings in TranslateService\'s instant() method', () => { | 	it('should extract strings in TranslateService\'s instant() method', () => { | ||||||
| @@ -56,8 +56,8 @@ describe('ServiceParser', () => { | |||||||
| 					this._translateService.instant('Hello World'); | 					this._translateService.instant('Hello World'); | ||||||
| 				} | 				} | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(componentFilename, contents); | 		const keys = parser.extract(contents, componentFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello World']); | 		expect(keys).to.deep.equal(['Hello World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract array of strings in TranslateService\'s get() method', () => { | 	it('should extract array of strings in TranslateService\'s get() method', () => { | ||||||
| @@ -69,8 +69,8 @@ describe('ServiceParser', () => { | |||||||
| 					this._translateService.get(['Hello', 'World']); | 					this._translateService.get(['Hello', 'World']); | ||||||
| 				} | 				} | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(componentFilename, contents); | 		const keys = parser.extract(contents, componentFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello', 'World']); | 		expect(keys).to.deep.equal(['Hello', 'World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should extract array of strings in TranslateService\'s instant() method', () => { | 	it('should extract array of strings in TranslateService\'s instant() method', () => { | ||||||
| @@ -82,8 +82,8 @@ describe('ServiceParser', () => { | |||||||
| 					this._translateService.instant(['Hello', 'World']); | 					this._translateService.instant(['Hello', 'World']); | ||||||
| 				} | 				} | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(componentFilename, contents); | 		const key = parser.extract(contents, componentFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal(['Hello', 'World']); | 		expect(key).to.deep.equal(['Hello', 'World']); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| 	it('should not extract strings in get()/instant() methods of other services', () => { | 	it('should not extract strings in get()/instant() methods of other services', () => { | ||||||
| @@ -99,8 +99,8 @@ describe('ServiceParser', () => { | |||||||
| 					this._otherService.instant('Hi there'); | 					this._otherService.instant('Hi there'); | ||||||
| 				} | 				} | ||||||
| 		`; | 		`; | ||||||
| 		const messages = parser.process(componentFilename, contents); | 		const keys = parser.extract(contents, componentFilename).keys(); | ||||||
| 		expect(messages).to.deep.equal([]); | 		expect(keys).to.deep.equal([]); | ||||||
| 	}); | 	}); | ||||||
|  |  | ||||||
| }); | }); | ||||||
|   | |||||||
							
								
								
									
										54
									
								
								tests/utils/string.collection.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tests/utils/string.collection.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | import { expect } from 'chai'; | ||||||
|  |  | ||||||
|  | import { StringCollection } from '../../src/utils/string.collection'; | ||||||
|  |  | ||||||
|  | describe('StringCollection', () => { | ||||||
|  |  | ||||||
|  | 	let collection: StringCollection; | ||||||
|  |  | ||||||
|  | 	beforeEach(() => { | ||||||
|  | 		collection = new StringCollection(); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should add item with value', () => { | ||||||
|  | 		collection.add('key', 'translation'); | ||||||
|  | 		expect(collection.get('key')).to.equal('translation'); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should add item with default value', () => { | ||||||
|  | 		collection.add('key'); | ||||||
|  | 		expect(collection.get('key')).to.equal(''); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should add array of items with default values', () => { | ||||||
|  | 		collection.add(['key', 'key2']); | ||||||
|  | 		expect(collection.count()).to.equal(2); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should remove item', () => { | ||||||
|  | 		collection.add('key1').add('key2').remove('key1'); | ||||||
|  | 		expect(collection.count()).to.equal(1); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should return number of items', () => { | ||||||
|  | 		collection.add('key1').add('key2'); | ||||||
|  | 		expect(collection.count()).to.equal(2); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should initialize with array of keys', () => { | ||||||
|  | 		const newCollection = StringCollection.fromArray(['Hello', 'World']); | ||||||
|  | 		expect(newCollection.count()).to.equal(2); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should initialize with key/value pairs', () => { | ||||||
|  | 		const newCollection = StringCollection.fromObject({'key': 'translation'}); | ||||||
|  | 		expect(newCollection.get('key')).to.equal('translation'); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | 	it('should merge with other collection', () => { | ||||||
|  | 		collection.add('Hello'); | ||||||
|  | 		const newCollection = StringCollection.fromArray(['World']); | ||||||
|  | 		expect(collection.merge(newCollection).count()).to.equal(2); | ||||||
|  | 	}); | ||||||
|  |  | ||||||
|  | }); | ||||||
		Reference in New Issue
	
	Block a user