From 22731a7588d771ac2fe5f351007e1939b61ff7fc Mon Sep 17 00:00:00 2001 From: Olivier Combe Date: Thu, 19 Jul 2018 11:02:22 +0200 Subject: [PATCH] refactor(ivy): split i18nInterpolation into 8 functions (#24805) PR Close #24805 --- .../core/src/core_render3_private_export.ts | 9 +- packages/core/src/render3/i18n.ts | 372 +++++++++++++++--- packages/core/src/render3/index.ts | 11 +- packages/core/src/render3/instructions.ts | 2 +- .../render3/compiler_canonical/i18n_spec.ts | 2 +- packages/core/test/render3/i18n_spec.ts | 320 +++++++++++++-- 6 files changed, 614 insertions(+), 102 deletions(-) diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index c88234bda0..8107ad315f 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -94,7 +94,14 @@ export { whenRendered as ɵwhenRendered, iA as ɵiA, iEM as ɵiEM, - iI as ɵiI, + iI1 as ɵiI1, + iI2 as ɵiI2, + iI3 as ɵiI3, + iI4 as ɵiI4, + iI5 as ɵiI5, + iI6 as ɵiI6, + iI7 as ɵiI7, + iI8 as ɵiI8, iIV as ɵIV, iM as ɵiM, I18nInstruction as ɵI18nInstruction, diff --git a/packages/core/src/render3/i18n.ts b/packages/core/src/render3/i18n.ts index 279c8d5b37..6c64793290 100644 --- a/packages/core/src/render3/i18n.ts +++ b/packages/core/src/render3/i18n.ts @@ -7,7 +7,7 @@ */ import {assertEqual, assertLessThan} from './assert'; -import {NO_CHANGE, bindingUpdated, createLNode, getPreviousOrParentNode, getRenderer, getViewData, load, resetApplicationState} from './instructions'; +import {NO_CHANGE, bindingUpdated, bindingUpdated2, bindingUpdated4, createLNode, getPreviousOrParentNode, getRenderer, getViewData, load, resetApplicationState} from './instructions'; import {RENDER_PARENT} from './interfaces/container'; import {LContainerNode, LNode, TContainerNode, TElementNode, TNodeType} from './interfaces/node'; import {BINDING_INDEX, HEADER_OFFSET, TVIEW} from './interfaces/view'; @@ -369,43 +369,16 @@ export function i18nExpMapping( } /** - * Checks if the value of up to 8 expressions have changed and replaces them by their values in a - * translation, or returns NO_CHANGE. + * Checks if the value of an expression has changed and replaces it by its value in a translation, + * or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. * * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. */ -export function i18nInterpolation( - instructions: I18nExpInstruction[], numberOfExp: number, v0: any, v1?: any, v2?: any, v3?: any, - v4?: any, v5?: any, v6?: any, v7?: any): string|NO_CHANGE { - let different = bindingUpdated(v0); - - if (numberOfExp > 1) { - different = bindingUpdated(v1) || different; - - if (numberOfExp > 2) { - different = bindingUpdated(v2) || different; - - if (numberOfExp > 3) { - different = bindingUpdated(v3) || different; - - if (numberOfExp > 4) { - different = bindingUpdated(v4) || different; - - if (numberOfExp > 5) { - different = bindingUpdated(v5) || different; - - if (numberOfExp > 6) { - different = bindingUpdated(v6) || different; - - if (numberOfExp > 7) { - different = bindingUpdated(v7) || different; - } - } - } - } - } - } - } +export function i18nInterpolation1(instructions: I18nExpInstruction[], v0: any): string|NO_CHANGE { + const different = bindingUpdated(v0); if (!different) { return NO_CHANGE; @@ -413,35 +386,308 @@ export function i18nInterpolation( let res = ''; for (let i = 0; i < instructions.length; i++) { - let value: any; - // Odd indexes are placeholders + // Odd indexes are bindings if (i & 1) { - switch (instructions[i]) { - case 0: - value = v0; - break; - case 1: - value = v1; - break; - case 2: - value = v2; - break; - case 3: - value = v3; - break; - case 4: - value = v4; - break; - case 5: - value = v5; - break; - case 6: - value = v6; - break; - case 7: - value = v7; - break; - } + res += stringify(v0); + } else { + res += instructions[i]; + } + } + + return res; +} + +/** + * Checks if the values of up to 2 expressions have changed and replaces them by their values in a + * translation, or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. + * @param v1 value checked for change. + * + * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. + */ +export function i18nInterpolation2(instructions: I18nExpInstruction[], v0: any, v1: any): string| + NO_CHANGE { + const different = bindingUpdated2(v0, v1); + + if (!different) { + return NO_CHANGE; + } + + let res = ''; + for (let i = 0; i < instructions.length; i++) { + // Odd indexes are bindings + if (i & 1) { + // Extract bits + const idx = instructions[i] as number; + const b1 = idx & 1; + // Get the value from the argument vx where x = idx + const value = b1 ? v1 : v0; + + res += stringify(value); + } else { + res += instructions[i]; + } + } + + return res; +} + +/** + * Checks if the values of up to 3 expressions have changed and replaces them by their values in a + * translation, or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. + * @param v1 value checked for change. + * @param v2 value checked for change. + * + * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. + */ +export function i18nInterpolation3( + instructions: I18nExpInstruction[], v0: any, v1: any, v2: any): string|NO_CHANGE { + let different = bindingUpdated2(v0, v1); + different = bindingUpdated(v2) || different; + + if (!different) { + return NO_CHANGE; + } + + let res = ''; + for (let i = 0; i < instructions.length; i++) { + // Odd indexes are bindings + if (i & 1) { + // Extract bits + const idx = instructions[i] as number; + const b2 = idx & 2; + const b1 = idx & 1; + // Get the value from the argument vx where x = idx + const value = b2 ? v2 : (b1 ? v1 : v0); + + res += stringify(value); + } else { + res += instructions[i]; + } + } + + return res; +} + +/** + * Checks if the values of up to 4 expressions have changed and replaces them by their values in a + * translation, or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. + * @param v1 value checked for change. + * @param v2 value checked for change. + * @param v3 value checked for change. + * + * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. + */ +export function i18nInterpolation4( + instructions: I18nExpInstruction[], v0: any, v1: any, v2: any, v3: any): string|NO_CHANGE { + const different = bindingUpdated4(v0, v1, v2, v3); + + if (!different) { + return NO_CHANGE; + } + + let res = ''; + for (let i = 0; i < instructions.length; i++) { + // Odd indexes are bindings + if (i & 1) { + // Extract bits + const idx = instructions[i] as number; + const b2 = idx & 2; + const b1 = idx & 1; + // Get the value from the argument vx where x = idx + const value = b2 ? (b1 ? v3 : v2) : (b1 ? v1 : v0); + + res += stringify(value); + } else { + res += instructions[i]; + } + } + + return res; +} + +/** + * Checks if the values of up to 5 expressions have changed and replaces them by their values in a + * translation, or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. + * @param v1 value checked for change. + * @param v2 value checked for change. + * @param v3 value checked for change. + * @param v4 value checked for change. + * + * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. + */ +export function i18nInterpolation5( + instructions: I18nExpInstruction[], v0: any, v1: any, v2: any, v3: any, v4: any): string| + NO_CHANGE { + let different = bindingUpdated4(v0, v1, v2, v3); + different = bindingUpdated(v4) || different; + + if (!different) { + return NO_CHANGE; + } + + let res = ''; + for (let i = 0; i < instructions.length; i++) { + // Odd indexes are bindings + if (i & 1) { + // Extract bits + const idx = instructions[i] as number; + const b4 = idx & 4; + const b2 = idx & 2; + const b1 = idx & 1; + // Get the value from the argument vx where x = idx + const value = b4 ? v4 : (b2 ? (b1 ? v3 : v2) : (b1 ? v1 : v0)); + + res += stringify(value); + } else { + res += instructions[i]; + } + } + + return res; +} + +/** + * Checks if the values of up to 6 expressions have changed and replaces them by their values in a + * translation, or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. + * @param v1 value checked for change. + * @param v2 value checked for change. + * @param v3 value checked for change. + * @param v4 value checked for change. + * @param v5 value checked for change. + * + * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. + */ export function +i18nInterpolation6( + instructions: I18nExpInstruction[], v0: any, v1: any, v2: any, v3: any, v4: any, v5: any): + string|NO_CHANGE { + let different = bindingUpdated4(v0, v1, v2, v3); + different = bindingUpdated2(v4, v5) || different; + + if (!different) { + return NO_CHANGE; + } + + let res = ''; + for (let i = 0; i < instructions.length; i++) { + // Odd indexes are bindings + if (i & 1) { + // Extract bits + const idx = instructions[i] as number; + const b4 = idx & 4; + const b2 = idx & 2; + const b1 = idx & 1; + // Get the value from the argument vx where x = idx + const value = b4 ? (b1 ? v5 : v4) : (b2 ? (b1 ? v3 : v2) : (b1 ? v1 : v0)); + + res += stringify(value); + } else { + res += instructions[i]; + } + } + + return res; +} + +/** + * Checks if the values of up to 7 expressions have changed and replaces them by their values in a + * translation, or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. + * @param v1 value checked for change. + * @param v2 value checked for change. + * @param v3 value checked for change. + * @param v4 value checked for change. + * @param v5 value checked for change. + * @param v6 value checked for change. + * + * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. + */ +export function i18nInterpolation7( + instructions: I18nExpInstruction[], v0: any, v1: any, v2: any, v3: any, v4: any, v5: any, + v6: any): string|NO_CHANGE { + let different = bindingUpdated4(v0, v1, v2, v3); + different = bindingUpdated2(v4, v5) || different; + different = bindingUpdated(v6) || different; + + if (!different) { + return NO_CHANGE; + } + + let res = ''; + for (let i = 0; i < instructions.length; i++) { + // Odd indexes are bindings + if (i & 1) { + // Extract bits + const idx = instructions[i] as number; + const b4 = idx & 4; + const b2 = idx & 2; + const b1 = idx & 1; + // Get the value from the argument vx where x = idx + const value = b4 ? (b2 ? v6 : (b1 ? v5 : v4)) : (b2 ? (b1 ? v3 : v2) : (b1 ? v1 : v0)); + + res += stringify(value); + } else { + res += instructions[i]; + } + } + + return res; +} + +/** + * Checks if the values of up to 8 expressions have changed and replaces them by their values in a + * translation, or returns NO_CHANGE. + * + * @param instructions A list of instructions that will be used to translate an attribute. + * @param v0 value checked for change. + * @param v1 value checked for change. + * @param v2 value checked for change. + * @param v3 value checked for change. + * @param v4 value checked for change. + * @param v5 value checked for change. + * @param v6 value checked for change. + * @param v7 value checked for change. + * + * @returns The concatenated string when any of the arguments changes, `NO_CHANGE` otherwise. + */ +export function i18nInterpolation8( + instructions: I18nExpInstruction[], v0: any, v1: any, v2: any, v3: any, v4: any, v5: any, + v6: any, v7: any): string|NO_CHANGE { + let different = bindingUpdated4(v0, v1, v2, v3); + different = bindingUpdated4(v4, v5, v6, v7) || different; + + if (!different) { + return NO_CHANGE; + } + + let res = ''; + for (let i = 0; i < instructions.length; i++) { + // Odd indexes are bindings + if (i & 1) { + // Extract bits + const idx = instructions[i] as number; + const b4 = idx & 4; + const b2 = idx & 2; + const b1 = idx & 1; + // Get the value from the argument vx where x = idx + const value = + b4 ? (b2 ? (b1 ? v7 : v6) : (b1 ? v5 : v4)) : (b2 ? (b1 ? v3 : v2) : (b1 ? v1 : v0)); res += stringify(value); } else { diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index 014a092e66..70ba550eb3 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -11,7 +11,7 @@ import {defineComponent, defineDirective, defineNgModule, definePipe} from './de import {InheritDefinitionFeature} from './features/inherit_definition_feature'; import {NgOnChangesFeature} from './features/ng_onchanges_feature'; import {PublicFeature} from './features/public_feature'; -import {I18nExpInstruction, I18nInstruction, i18nExpMapping, i18nInterpolation, i18nInterpolationV} from './i18n'; +import {I18nExpInstruction, I18nInstruction, i18nExpMapping, i18nInterpolation1, i18nInterpolation2, i18nInterpolation3, i18nInterpolation4, i18nInterpolation5, i18nInterpolation6, i18nInterpolation7, i18nInterpolation8, i18nInterpolationV} from './i18n'; import {ComponentDef, ComponentDefInternal, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveDefInternal, DirectiveType, PipeDef} from './interfaces/definition'; export {ComponentFactory, ComponentFactoryResolver, ComponentRef} from './component_ref'; @@ -88,7 +88,14 @@ export { export { i18nApply as iA, i18nMapping as iM, - i18nInterpolation as iI, + i18nInterpolation1 as iI1, + i18nInterpolation2 as iI2, + i18nInterpolation3 as iI3, + i18nInterpolation4 as iI4, + i18nInterpolation5 as iI5, + i18nInterpolation6 as iI6, + i18nInterpolation7 as iI7, + i18nInterpolation8 as iI8, i18nInterpolationV as iIV, i18nExpMapping as iEM, I18nInstruction, diff --git a/packages/core/src/render3/instructions.ts b/packages/core/src/render3/instructions.ts index 3b27b0d5d8..f99b34be06 100644 --- a/packages/core/src/render3/instructions.ts +++ b/packages/core/src/render3/instructions.ts @@ -2454,7 +2454,7 @@ export function interpolation2( return different ? prefix + stringify(v0) + i0 + stringify(v1) + suffix : NO_CHANGE; } -/** Creates an interpolation bindings with 3 expressions. */ +/** Creates an interpolation binding with 3 expressions. */ export function interpolation3( prefix: string, v0: any, i0: string, v1: any, i1: string, v2: any, suffix: string): string| NO_CHANGE { diff --git a/packages/core/test/render3/compiler_canonical/i18n_spec.ts b/packages/core/test/render3/compiler_canonical/i18n_spec.ts index 3811eb5c18..a27ddb89d2 100644 --- a/packages/core/test/render3/compiler_canonical/i18n_spec.ts +++ b/packages/core/test/render3/compiler_canonical/i18n_spec.ts @@ -86,7 +86,7 @@ describe('i18n', () => { $r3$.ɵe(); } if (rf & 2) { - $r3$.ɵp(0, 'title', $r3$.ɵiI($i18n_1$, 2, ctx.exp1)); + $r3$.ɵp(0, 'title', $r3$.ɵiI1($i18n_1$, ctx.exp1)); } } }); diff --git a/packages/core/test/render3/i18n_spec.ts b/packages/core/test/render3/i18n_spec.ts index d5709c2bd4..d185583385 100644 --- a/packages/core/test/render3/i18n_spec.ts +++ b/packages/core/test/render3/i18n_spec.ts @@ -9,7 +9,7 @@ import {NgForOfContext} from '@angular/common'; import {Component} from '../../src/core'; import {defineComponent} from '../../src/render3/definition'; -import {I18nExpInstruction, I18nInstruction, i18nApply, i18nExpMapping, i18nInterpolation, i18nInterpolationV, i18nMapping} from '../../src/render3/i18n'; +import {I18nExpInstruction, I18nInstruction, i18nApply, i18nExpMapping, i18nInterpolation1, i18nInterpolation2, i18nInterpolation3, i18nInterpolation4, i18nInterpolation5, i18nInterpolation6, i18nInterpolation7, i18nInterpolation8, i18nInterpolationV, i18nMapping} from '../../src/render3/i18n'; import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, projection, projectionDef, text, textBinding} from '../../src/render3/instructions'; import {RenderFlags} from '../../src/render3/interfaces/definition'; import {NgForOf} from './common_with_def'; @@ -201,7 +201,7 @@ describe('Runtime i18n', () => { element(0, 'div'); // translated section 1 } if (rf & RenderFlags.Update) { - elementProperty(0, 'title', i18nInterpolation(i18n_1, 2, ctx.exp1, ctx.exp2)); + elementProperty(0, 'title', i18nInterpolation2(i18n_1, ctx.exp1, ctx.exp2)); } } }); @@ -295,7 +295,7 @@ describe('Runtime i18n', () => { textBinding(1, bind(ctx.exp1)); textBinding(6, bind(ctx.exp2)); textBinding(7, bind(ctx.exp3)); - elementProperty(0, 'title', i18nInterpolation(i18n_2, 2, ctx.exp1, ctx.exp2)); + elementProperty(0, 'title', i18nInterpolation2(i18n_2, ctx.exp1, ctx.exp2)); } } }); @@ -389,7 +389,7 @@ describe('Runtime i18n', () => { } if (rf & RenderFlags.Update) { textBinding(2, bind(ctx.exp1)); - elementProperty(4, 'title', i18nInterpolation(i18n_3, 2, ctx.exp1, ctx.exp2)); + elementProperty(4, 'title', i18nInterpolation2(i18n_3, ctx.exp1, ctx.exp2)); } } }); @@ -1097,7 +1097,7 @@ describe('Runtime i18n', () => { i18nApply(1, i18n_1[0]); } if (rf & RenderFlags.Update) { - elementProperty(2, 'title', i18nInterpolation(i18n_2, 1, cmp.name)); + elementProperty(2, 'title', i18nInterpolation1(i18n_2, cmp.name)); textBinding(3, bind(cmp.name)); } } @@ -1184,7 +1184,7 @@ describe('Runtime i18n', () => { i18nApply(4, i18n_1[0]); } if (rf & RenderFlags.Update) { - elementProperty(3, 'title', i18nInterpolation(i18n_2, 1, cmp.name)); + elementProperty(3, 'title', i18nInterpolation1(i18n_2, cmp.name)); textBinding(4, bind(cmp.name)); } } @@ -1340,40 +1340,292 @@ describe('Runtime i18n', () => { }); }); - it('i18nInterpolation should return the same value as i18nInterpolationV', () => { - const MSG_DIV_SECTION_1 = `start {$EXP_2} middle {$EXP_1} end`; - const i18n_1 = i18nExpMapping(MSG_DIV_SECTION_1, {'EXP_1': 0, 'EXP_2': 1}); - let interpolation; - let interpolationV; + describe('i18nInterpolation', () => { + it('i18nInterpolation should return the same value as i18nInterpolationV', () => { + const MSG_DIV_SECTION_1 = `start {$EXP_2} middle {$EXP_1} end`; + const i18n_1 = i18nExpMapping(MSG_DIV_SECTION_1, {'EXP_1': 0, 'EXP_2': 1}); + let interpolation; + let interpolationV; - class MyApp { - exp1: any = '1'; - exp2: any = '2'; + class MyApp { + exp1: any = '1'; + exp2: any = '2'; - static ngComponentDef = defineComponent({ - type: MyApp, - factory: () => new MyApp(), - selectors: [['my-app']], - // Initial template: - //
+ static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + // Initial template: + //
- // Translated to: - //
- template: (rf: RenderFlags, ctx: MyApp) => { - if (rf & RenderFlags.Create) { - element(0, 'div'); // translated section 1 + // Translated to: + //
+ template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { + element(0, 'div'); // translated section 1 + } + if (rf & RenderFlags.Update) { + interpolation = i18nInterpolation2(i18n_1, ctx.exp1, ctx.exp2); + interpolationV = i18nInterpolationV(i18n_1, [ctx.exp1, ctx.exp2]); + elementProperty(0, 'title', interpolation); + } } - if (rf & RenderFlags.Update) { - interpolation = i18nInterpolation(i18n_1, 2, ctx.exp1, ctx.exp2); - interpolationV = i18nInterpolationV(i18n_1, [ctx.exp1, ctx.exp2]); - elementProperty(0, 'title', interpolation); + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(interpolation).toBeDefined(); + expect(interpolation).toEqual(interpolationV); + }); + + it('i18nInterpolation3 should work', () => { + const MSG_DIV_SECTION_1 = `start {$EXP_1} _ {$EXP_2} _ {$EXP_3} end`; + const i18n_1 = i18nExpMapping(MSG_DIV_SECTION_1, {'EXP_1': 0, 'EXP_2': 1, 'EXP_3': 2}); + + class MyApp { + exp1: any = '1'; + exp2: any = '2'; + exp3: any = '3'; + + static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + // Initial template: + //
+ + // Translated to: + //
+ template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { + element(0, 'div'); // translated section 1 + } + if (rf & RenderFlags.Update) { + elementProperty(0, 'title', i18nInterpolation3(i18n_1, ctx.exp1, ctx.exp2, ctx.exp3)); + } } - } + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(fixture.html).toEqual('
'); + }); + + it('i18nInterpolation4 should work', () => { + const MSG_DIV_SECTION_1 = `start {$EXP_1} _ {$EXP_2} _ {$EXP_3} _ {$EXP_4} end`; + const i18n_1 = + i18nExpMapping(MSG_DIV_SECTION_1, {'EXP_1': 0, 'EXP_2': 1, 'EXP_3': 2, 'EXP_4': 3}); + + class MyApp { + exp1: any = '1'; + exp2: any = '2'; + exp3: any = '3'; + exp4: any = '4'; + + static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + // Initial template: + //
+ + // Translated to: + //
+ template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { + element(0, 'div'); // translated section 1 + } + if (rf & RenderFlags.Update) { + elementProperty( + 0, 'title', i18nInterpolation4(i18n_1, ctx.exp1, ctx.exp2, ctx.exp3, ctx.exp4)); + } + } + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(fixture.html).toEqual('
'); + }); + + it('i18nInterpolation5 should work', () => { + const MSG_DIV_SECTION_1 = `start {$EXP_1} _ {$EXP_2} _ {$EXP_3} _ {$EXP_4} _ {$EXP_5} end`; + const i18n_1 = i18nExpMapping( + MSG_DIV_SECTION_1, {'EXP_1': 0, 'EXP_2': 1, 'EXP_3': 2, 'EXP_4': 3, 'EXP_5': 4}); + + class MyApp { + exp1: any = '1'; + exp2: any = '2'; + exp3: any = '3'; + exp4: any = '4'; + exp5: any = '5'; + + static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + // Initial template: + //
+ + // Translated to: + //
+ template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { + element(0, 'div'); // translated section 1 + } + if (rf & RenderFlags.Update) { + elementProperty( + 0, 'title', + i18nInterpolation5(i18n_1, ctx.exp1, ctx.exp2, ctx.exp3, ctx.exp4, ctx.exp5)); + } + } + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(fixture.html).toEqual('
'); + }); + + it('i18nInterpolation6 should work', () => { + const MSG_DIV_SECTION_1 = + `start {$EXP_1} _ {$EXP_2} _ {$EXP_3} _ {$EXP_4} _ {$EXP_5} _ {$EXP_6} end`; + const i18n_1 = i18nExpMapping( + MSG_DIV_SECTION_1, + {'EXP_1': 0, 'EXP_2': 1, 'EXP_3': 2, 'EXP_4': 3, 'EXP_5': 4, 'EXP_6': 5}); + + class MyApp { + exp1: any = '1'; + exp2: any = '2'; + exp3: any = '3'; + exp4: any = '4'; + exp5: any = '5'; + exp6: any = '6'; + + static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + // Initial template: + //
+ + // Translated to: + //
+ template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { + element(0, 'div'); // translated section 1 + } + if (rf & RenderFlags.Update) { + elementProperty( + 0, 'title', + i18nInterpolation6( + i18n_1, ctx.exp1, ctx.exp2, ctx.exp3, ctx.exp4, ctx.exp5, ctx.exp6)); + } + } + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(fixture.html).toEqual('
'); + }); + + it('i18nInterpolation7 should work', () => { + const MSG_DIV_SECTION_1 = + `start {$EXP_1} _ {$EXP_2} _ {$EXP_3} _ {$EXP_4} _ {$EXP_5} _ {$EXP_6} _ {$EXP_7} end`; + const i18n_1 = i18nExpMapping( + MSG_DIV_SECTION_1, + {'EXP_1': 0, 'EXP_2': 1, 'EXP_3': 2, 'EXP_4': 3, 'EXP_5': 4, 'EXP_6': 5, 'EXP_7': 6}); + + class MyApp { + exp1: any = '1'; + exp2: any = '2'; + exp3: any = '3'; + exp4: any = '4'; + exp5: any = '5'; + exp6: any = '6'; + exp7: any = '7'; + + static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + // Initial template: + //
+ + // Translated to: + //
+ template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { + element(0, 'div'); // translated section 1 + } + if (rf & RenderFlags.Update) { + elementProperty( + 0, 'title', i18nInterpolation7( + i18n_1, ctx.exp1, ctx.exp2, ctx.exp3, ctx.exp4, ctx.exp5, + ctx.exp6, ctx.exp7)); + } + } + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(fixture.html).toEqual('
'); + }); + + it('i18nInterpolation8 should work', () => { + const MSG_DIV_SECTION_1 = + `start {$EXP_1} _ {$EXP_2} _ {$EXP_3} _ {$EXP_4} _ {$EXP_5} _ {$EXP_6} _ {$EXP_7} _ {$EXP_8} end`; + const i18n_1 = i18nExpMapping(MSG_DIV_SECTION_1, { + 'EXP_1': 0, + 'EXP_2': 1, + 'EXP_3': 2, + 'EXP_4': 3, + 'EXP_5': 4, + 'EXP_6': 5, + 'EXP_7': 6, + 'EXP_8': 7 }); - } - const fixture = new ComponentFixture(MyApp); - expect(interpolation).toBeDefined(); - expect(interpolation).toEqual(interpolationV); + class MyApp { + exp1: any = '1'; + exp2: any = '2'; + exp3: any = '3'; + exp4: any = '4'; + exp5: any = '5'; + exp6: any = '6'; + exp7: any = '7'; + exp8: any = '8'; + + static ngComponentDef = defineComponent({ + type: MyApp, + factory: () => new MyApp(), + selectors: [['my-app']], + // Initial template: + //
+ + // Translated to: + //
+ template: (rf: RenderFlags, ctx: MyApp) => { + if (rf & RenderFlags.Create) { + element(0, 'div'); // translated section 1 + } + if (rf & RenderFlags.Update) { + elementProperty( + 0, 'title', i18nInterpolation8( + i18n_1, ctx.exp1, ctx.exp2, ctx.exp3, ctx.exp4, ctx.exp5, + ctx.exp6, ctx.exp7, ctx.exp8)); + } + } + }); + } + + const fixture = new ComponentFixture(MyApp); + expect(fixture.html).toEqual('
'); + }); + }); });