refactor: move angular source to /packages rather than modules/@angular
This commit is contained in:
216
packages/common/test/pipes/async_pipe_spec.ts
Normal file
216
packages/common/test/pipes/async_pipe_spec.ts
Normal file
@ -0,0 +1,216 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {AsyncPipe} from '@angular/common';
|
||||
import {EventEmitter, WrappedValue} from '@angular/core';
|
||||
import {AsyncTestCompleter, beforeEach, describe, expect, inject, it} from '@angular/core/testing/testing_internal';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
import {browserDetection} from '@angular/platform-browser/testing/browser_util';
|
||||
|
||||
import {SpyChangeDetectorRef} from '../spies';
|
||||
|
||||
export function main() {
|
||||
describe('AsyncPipe', () => {
|
||||
|
||||
describe('Observable', () => {
|
||||
let emitter: EventEmitter<any>;
|
||||
let pipe: AsyncPipe;
|
||||
let ref: any;
|
||||
const message = {};
|
||||
|
||||
beforeEach(() => {
|
||||
emitter = new EventEmitter();
|
||||
ref = new SpyChangeDetectorRef();
|
||||
pipe = new AsyncPipe(ref);
|
||||
});
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return null when subscribing to an observable',
|
||||
() => { expect(pipe.transform(emitter)).toBe(null); });
|
||||
|
||||
it('should return the latest available value wrapped',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(emitter);
|
||||
emitter.emit(message);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(pipe.transform(emitter)).toEqual(new WrappedValue(message));
|
||||
async.done();
|
||||
}, 0);
|
||||
}));
|
||||
|
||||
|
||||
it('should return same value when nothing has changed since the last call',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(emitter);
|
||||
emitter.emit(message);
|
||||
|
||||
setTimeout(() => {
|
||||
pipe.transform(emitter);
|
||||
expect(pipe.transform(emitter)).toBe(message);
|
||||
async.done();
|
||||
}, 0);
|
||||
}));
|
||||
|
||||
it('should dispose of the existing subscription when subscribing to a new observable',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(emitter);
|
||||
|
||||
const newEmitter = new EventEmitter();
|
||||
expect(pipe.transform(newEmitter)).toBe(null);
|
||||
emitter.emit(message);
|
||||
|
||||
// this should not affect the pipe
|
||||
setTimeout(() => {
|
||||
expect(pipe.transform(newEmitter)).toBe(null);
|
||||
async.done();
|
||||
}, 0);
|
||||
}));
|
||||
|
||||
it('should request a change detection check upon receiving a new value',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(emitter);
|
||||
emitter.emit(message);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(ref.spy('markForCheck')).toHaveBeenCalled();
|
||||
async.done();
|
||||
}, 10);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('ngOnDestroy', () => {
|
||||
it('should do nothing when no subscription',
|
||||
() => { expect(() => pipe.ngOnDestroy()).not.toThrow(); });
|
||||
|
||||
it('should dispose of the existing subscription',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(emitter);
|
||||
pipe.ngOnDestroy();
|
||||
emitter.emit(message);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(pipe.transform(emitter)).toBe(null);
|
||||
async.done();
|
||||
}, 0);
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Promise', () => {
|
||||
const message = new Object();
|
||||
let pipe: AsyncPipe;
|
||||
let resolve: (result: any) => void;
|
||||
let reject: (error: any) => void;
|
||||
let promise: Promise<any>;
|
||||
let ref: SpyChangeDetectorRef;
|
||||
// adds longer timers for passing tests in IE
|
||||
const timer = (getDOM() && browserDetection.isIE) ? 50 : 10;
|
||||
|
||||
beforeEach(() => {
|
||||
promise = new Promise((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
ref = new SpyChangeDetectorRef();
|
||||
pipe = new AsyncPipe(<any>ref);
|
||||
});
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return null when subscribing to a promise',
|
||||
() => { expect(pipe.transform(promise)).toBe(null); });
|
||||
|
||||
it('should return the latest available value',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(promise);
|
||||
|
||||
resolve(message);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(pipe.transform(promise)).toEqual(new WrappedValue(message));
|
||||
async.done();
|
||||
}, timer);
|
||||
}));
|
||||
|
||||
it('should return unwrapped value when nothing has changed since the last call',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(promise);
|
||||
resolve(message);
|
||||
|
||||
setTimeout(() => {
|
||||
pipe.transform(promise);
|
||||
expect(pipe.transform(promise)).toBe(message);
|
||||
async.done();
|
||||
}, timer);
|
||||
}));
|
||||
|
||||
it('should dispose of the existing subscription when subscribing to a new promise',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(promise);
|
||||
|
||||
promise = new Promise<any>(() => {});
|
||||
expect(pipe.transform(promise)).toBe(null);
|
||||
|
||||
// this should not affect the pipe, so it should return WrappedValue
|
||||
resolve(message);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(pipe.transform(promise)).toBe(null);
|
||||
async.done();
|
||||
}, timer);
|
||||
}));
|
||||
|
||||
it('should request a change detection check upon receiving a new value',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
const markForCheck = ref.spy('markForCheck');
|
||||
pipe.transform(promise);
|
||||
resolve(message);
|
||||
|
||||
setTimeout(() => {
|
||||
expect(markForCheck).toHaveBeenCalled();
|
||||
async.done();
|
||||
}, timer);
|
||||
}));
|
||||
|
||||
describe('ngOnDestroy', () => {
|
||||
it('should do nothing when no source',
|
||||
() => { expect(() => pipe.ngOnDestroy()).not.toThrow(); });
|
||||
|
||||
it('should dispose of the existing source',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
pipe.transform(promise);
|
||||
expect(pipe.transform(promise)).toBe(null);
|
||||
resolve(message);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
expect(pipe.transform(promise)).toEqual(new WrappedValue(message));
|
||||
pipe.ngOnDestroy();
|
||||
expect(pipe.transform(promise)).toBe(null);
|
||||
async.done();
|
||||
}, timer);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('null', () => {
|
||||
it('should return null when given null', () => {
|
||||
const pipe = new AsyncPipe(null);
|
||||
expect(pipe.transform(null)).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('other types', () => {
|
||||
it('should throw when given an invalid object', () => {
|
||||
const pipe = new AsyncPipe(null);
|
||||
expect(() => pipe.transform(<any>'some bogus object')).toThrowError();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
67
packages/common/test/pipes/case_conversion_pipes_spec.ts
Normal file
67
packages/common/test/pipes/case_conversion_pipes_spec.ts
Normal file
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {LowerCasePipe, TitleCasePipe, UpperCasePipe} from '@angular/common';
|
||||
|
||||
export function main() {
|
||||
describe('LowerCasePipe', () => {
|
||||
let pipe: LowerCasePipe;
|
||||
|
||||
beforeEach(() => { pipe = new LowerCasePipe(); });
|
||||
|
||||
it('should return lowercase', () => { expect(pipe.transform('FOO')).toEqual('foo'); });
|
||||
|
||||
it('should lowercase when there is a new value', () => {
|
||||
expect(pipe.transform('FOO')).toEqual('foo');
|
||||
expect(pipe.transform('BAr')).toEqual('bar');
|
||||
});
|
||||
|
||||
it('should not support other objects',
|
||||
() => { expect(() => pipe.transform(<any>{})).toThrowError(); });
|
||||
});
|
||||
|
||||
describe('TitleCasePipe', () => {
|
||||
let pipe: TitleCasePipe;
|
||||
|
||||
beforeEach(() => { pipe = new TitleCasePipe(); });
|
||||
|
||||
it('should return titlecase', () => { expect(pipe.transform('foo')).toEqual('Foo'); });
|
||||
|
||||
it('should return titlecase for subsequent words',
|
||||
() => { expect(pipe.transform('one TWO Three fouR')).toEqual('One Two Three Four'); });
|
||||
|
||||
it('should support empty strings', () => { expect(pipe.transform('')).toEqual(''); });
|
||||
|
||||
it('should persist whitespace',
|
||||
() => { expect(pipe.transform('one two')).toEqual('One Two'); });
|
||||
|
||||
it('should titlecase when there is a new value', () => {
|
||||
expect(pipe.transform('bar')).toEqual('Bar');
|
||||
expect(pipe.transform('foo')).toEqual('Foo');
|
||||
});
|
||||
|
||||
it('should not support other objects',
|
||||
() => { expect(() => pipe.transform(<any>{})).toThrowError(); });
|
||||
});
|
||||
|
||||
describe('UpperCasePipe', () => {
|
||||
let pipe: UpperCasePipe;
|
||||
|
||||
beforeEach(() => { pipe = new UpperCasePipe(); });
|
||||
|
||||
it('should return uppercase', () => { expect(pipe.transform('foo')).toEqual('FOO'); });
|
||||
|
||||
it('should uppercase when there is a new value', () => {
|
||||
expect(pipe.transform('foo')).toEqual('FOO');
|
||||
expect(pipe.transform('bar')).toEqual('BAR');
|
||||
});
|
||||
|
||||
it('should not support other objects',
|
||||
() => { expect(() => pipe.transform(<any>{})).toThrowError(); });
|
||||
});
|
||||
}
|
203
packages/common/test/pipes/date_pipe_spec.ts
Normal file
203
packages/common/test/pipes/date_pipe_spec.ts
Normal file
@ -0,0 +1,203 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {DatePipe} from '@angular/common';
|
||||
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
||||
import {browserDetection} from '@angular/platform-browser/testing/browser_util';
|
||||
|
||||
export function main() {
|
||||
describe('DatePipe', () => {
|
||||
let date: Date;
|
||||
const isoStringWithoutTime = '2015-01-01';
|
||||
let pipe: DatePipe;
|
||||
|
||||
// Check the transformation of a date into a pattern
|
||||
function expectDateFormatAs(date: Date | string, pattern: any, output: string): void {
|
||||
expect(pipe.transform(date, pattern)).toEqual(output);
|
||||
}
|
||||
|
||||
// TODO: reactivate the disabled expectations once emulators are fixed in SauceLabs
|
||||
// In some old versions of Chrome in Android emulators, time formatting returns dates in the
|
||||
// timezone of the VM host,
|
||||
// instead of the device timezone. Same symptoms as
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=406382
|
||||
// This happens locally and in SauceLabs, so some checks are disabled to avoid failures.
|
||||
// Tracking issue: https://github.com/angular/angular/issues/11187
|
||||
|
||||
beforeEach(() => {
|
||||
date = new Date(2015, 5, 15, 9, 3, 1);
|
||||
pipe = new DatePipe('en-US');
|
||||
});
|
||||
|
||||
it('should be marked as pure',
|
||||
() => { expect(new PipeResolver().resolve(DatePipe).pure).toEqual(true); });
|
||||
|
||||
describe('supports', () => {
|
||||
it('should support date', () => { expect(() => pipe.transform(date)).not.toThrow(); });
|
||||
|
||||
it('should support int', () => { expect(() => pipe.transform(123456789)).not.toThrow(); });
|
||||
|
||||
it('should support numeric strings',
|
||||
() => { expect(() => pipe.transform('123456789')).not.toThrow(); });
|
||||
|
||||
it('should support decimal strings',
|
||||
() => { expect(() => pipe.transform('123456789.11')).not.toThrow(); });
|
||||
|
||||
it('should support ISO string',
|
||||
() => expect(() => pipe.transform('2015-06-15T21:43:11Z')).not.toThrow());
|
||||
|
||||
it('should return null for empty string', () => expect(pipe.transform('')).toEqual(null));
|
||||
|
||||
it('should return null for NaN', () => expect(pipe.transform(Number.NaN)).toEqual(null));
|
||||
|
||||
it('should support ISO string without time',
|
||||
() => { expect(() => pipe.transform(isoStringWithoutTime)).not.toThrow(); });
|
||||
|
||||
it('should not support other objects',
|
||||
() => expect(() => pipe.transform({})).toThrowError(/InvalidPipeArgument/));
|
||||
});
|
||||
|
||||
describe('transform', () => {
|
||||
it('should format each component correctly', () => {
|
||||
const dateFixtures: any = {
|
||||
'y': '2015',
|
||||
'yy': '15',
|
||||
'M': '6',
|
||||
'MM': '06',
|
||||
'MMM': 'Jun',
|
||||
'MMMM': 'June',
|
||||
'd': '15',
|
||||
'dd': '15',
|
||||
'EEE': 'Mon',
|
||||
'EEEE': 'Monday'
|
||||
};
|
||||
|
||||
const isoStringWithoutTimeFixtures: any = {
|
||||
'y': '2015',
|
||||
'yy': '15',
|
||||
'M': '1',
|
||||
'MM': '01',
|
||||
'MMM': 'Jan',
|
||||
'MMMM': 'January',
|
||||
'd': '1',
|
||||
'dd': '01',
|
||||
'EEE': 'Thu',
|
||||
'EEEE': 'Thursday'
|
||||
};
|
||||
|
||||
if (!browserDetection.isOldChrome) {
|
||||
dateFixtures['h'] = '9';
|
||||
dateFixtures['hh'] = '09';
|
||||
dateFixtures['j'] = '9 AM';
|
||||
isoStringWithoutTimeFixtures['h'] = '12';
|
||||
isoStringWithoutTimeFixtures['hh'] = '12';
|
||||
isoStringWithoutTimeFixtures['j'] = '12 AM';
|
||||
}
|
||||
|
||||
// IE and Edge can't format a date to minutes and seconds without hours
|
||||
if (!browserDetection.isEdge && !browserDetection.isIE ||
|
||||
!browserDetection.supportsNativeIntlApi) {
|
||||
if (!browserDetection.isOldChrome) {
|
||||
dateFixtures['HH'] = '09';
|
||||
isoStringWithoutTimeFixtures['HH'] = '00';
|
||||
}
|
||||
dateFixtures['E'] = 'M';
|
||||
dateFixtures['L'] = 'J';
|
||||
dateFixtures['m'] = '3';
|
||||
dateFixtures['s'] = '1';
|
||||
dateFixtures['mm'] = '03';
|
||||
dateFixtures['ss'] = '01';
|
||||
isoStringWithoutTimeFixtures['m'] = '0';
|
||||
isoStringWithoutTimeFixtures['s'] = '0';
|
||||
isoStringWithoutTimeFixtures['mm'] = '00';
|
||||
isoStringWithoutTimeFixtures['ss'] = '00';
|
||||
}
|
||||
|
||||
Object.keys(dateFixtures).forEach((pattern: string) => {
|
||||
expectDateFormatAs(date, pattern, dateFixtures[pattern]);
|
||||
});
|
||||
|
||||
Object.keys(isoStringWithoutTimeFixtures).forEach((pattern: string) => {
|
||||
expectDateFormatAs(isoStringWithoutTime, pattern, isoStringWithoutTimeFixtures[pattern]);
|
||||
});
|
||||
|
||||
expect(pipe.transform(date, 'Z')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should format common multi component patterns', () => {
|
||||
const dateFixtures: any = {
|
||||
'EEE, M/d/y': 'Mon, 6/15/2015',
|
||||
'EEE, M/d': 'Mon, 6/15',
|
||||
'MMM d': 'Jun 15',
|
||||
'dd/MM/yyyy': '15/06/2015',
|
||||
'MM/dd/yyyy': '06/15/2015',
|
||||
'yMEEEd': '20156Mon15',
|
||||
'MEEEd': '6Mon15',
|
||||
'MMMd': 'Jun15',
|
||||
'yMMMMEEEEd': 'Monday, June 15, 2015'
|
||||
};
|
||||
|
||||
// IE and Edge can't format a date to minutes and seconds without hours
|
||||
if (!browserDetection.isEdge && !browserDetection.isIE ||
|
||||
!browserDetection.supportsNativeIntlApi) {
|
||||
dateFixtures['ms'] = '31';
|
||||
}
|
||||
|
||||
if (!browserDetection.isOldChrome) {
|
||||
dateFixtures['jm'] = '9:03 AM';
|
||||
}
|
||||
|
||||
Object.keys(dateFixtures).forEach((pattern: string) => {
|
||||
expectDateFormatAs(date, pattern, dateFixtures[pattern]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should format with pattern aliases', () => {
|
||||
const dateFixtures: any = {
|
||||
'MM/dd/yyyy': '06/15/2015',
|
||||
'fullDate': 'Monday, June 15, 2015',
|
||||
'longDate': 'June 15, 2015',
|
||||
'mediumDate': 'Jun 15, 2015',
|
||||
'shortDate': '6/15/2015'
|
||||
};
|
||||
|
||||
if (!browserDetection.isOldChrome) {
|
||||
// IE and Edge do not add a coma after the year in these 2 cases
|
||||
if ((browserDetection.isEdge || browserDetection.isIE) &&
|
||||
browserDetection.supportsNativeIntlApi) {
|
||||
dateFixtures['medium'] = 'Jun 15, 2015 9:03:01 AM';
|
||||
dateFixtures['short'] = '6/15/2015 9:03 AM';
|
||||
} else {
|
||||
dateFixtures['medium'] = 'Jun 15, 2015, 9:03:01 AM';
|
||||
dateFixtures['short'] = '6/15/2015, 9:03 AM';
|
||||
}
|
||||
}
|
||||
|
||||
if (!browserDetection.isOldChrome) {
|
||||
dateFixtures['mediumTime'] = '9:03:01 AM';
|
||||
dateFixtures['shortTime'] = '9:03 AM';
|
||||
}
|
||||
|
||||
Object.keys(dateFixtures).forEach((pattern: string) => {
|
||||
expectDateFormatAs(date, pattern, dateFixtures[pattern]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should format invalid in IE ISO date',
|
||||
() => expect(pipe.transform('2017-01-11T09:25:14.014-0500')).toEqual('Jan 11, 2017'));
|
||||
|
||||
it('should format invalid in Safari ISO date',
|
||||
() => expect(pipe.transform('2017-01-20T19:00:00+0000')).toEqual('Jan 20, 2017'));
|
||||
|
||||
it('should remove bidi control characters',
|
||||
() => expect(pipe.transform(date, 'MM/dd/yyyy').length).toEqual(10));
|
||||
});
|
||||
});
|
||||
}
|
68
packages/common/test/pipes/i18n_plural_pipe_spec.ts
Normal file
68
packages/common/test/pipes/i18n_plural_pipe_spec.ts
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {I18nPluralPipe, NgLocalization} from '@angular/common';
|
||||
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
||||
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
|
||||
|
||||
export function main() {
|
||||
describe('I18nPluralPipe', () => {
|
||||
let localization: NgLocalization;
|
||||
let pipe: I18nPluralPipe;
|
||||
|
||||
const mapping = {
|
||||
'=0': 'No messages.',
|
||||
'=1': 'One message.',
|
||||
'many': 'Many messages.',
|
||||
'other': 'There are # messages, that is #.',
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
localization = new TestLocalization();
|
||||
pipe = new I18nPluralPipe(localization);
|
||||
});
|
||||
|
||||
it('should be marked as pure',
|
||||
() => { expect(new PipeResolver().resolve(I18nPluralPipe).pure).toEqual(true); });
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return 0 text if value is 0', () => {
|
||||
const val = pipe.transform(0, mapping);
|
||||
expect(val).toEqual('No messages.');
|
||||
});
|
||||
|
||||
it('should return 1 text if value is 1', () => {
|
||||
const val = pipe.transform(1, mapping);
|
||||
expect(val).toEqual('One message.');
|
||||
});
|
||||
|
||||
it('should return category messages', () => {
|
||||
const val = pipe.transform(4, mapping);
|
||||
expect(val).toEqual('Many messages.');
|
||||
});
|
||||
|
||||
it('should interpolate the value into the text where indicated', () => {
|
||||
const val = pipe.transform(6, mapping);
|
||||
expect(val).toEqual('There are 6 messages, that is 6.');
|
||||
});
|
||||
|
||||
it('should use "" if value is undefined', () => {
|
||||
const val = pipe.transform(void(0), mapping);
|
||||
expect(val).toEqual('');
|
||||
});
|
||||
|
||||
it('should not support bad arguments',
|
||||
() => { expect(() => pipe.transform(0, <any>'hey')).toThrowError(); });
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
class TestLocalization extends NgLocalization {
|
||||
getPluralCategory(value: number): string { return value > 1 && value < 6 ? 'many' : 'other'; }
|
||||
}
|
44
packages/common/test/pipes/i18n_select_pipe_spec.ts
Normal file
44
packages/common/test/pipes/i18n_select_pipe_spec.ts
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {I18nSelectPipe} from '@angular/common';
|
||||
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
||||
|
||||
export function main() {
|
||||
describe('I18nSelectPipe', () => {
|
||||
const pipe: I18nSelectPipe = new I18nSelectPipe();
|
||||
const mapping = {'male': 'Invite him.', 'female': 'Invite her.', 'other': 'Invite them.'};
|
||||
|
||||
it('should be marked as pure',
|
||||
() => { expect(new PipeResolver().resolve(I18nSelectPipe).pure).toEqual(true); });
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return the "male" text if value is "male"', () => {
|
||||
const val = pipe.transform('male', mapping);
|
||||
expect(val).toEqual('Invite him.');
|
||||
});
|
||||
|
||||
it('should return the "female" text if value is "female"', () => {
|
||||
const val = pipe.transform('female', mapping);
|
||||
expect(val).toEqual('Invite her.');
|
||||
});
|
||||
|
||||
it('should return the "other" text if value is neither "male" nor "female"',
|
||||
() => { expect(pipe.transform('Anything else', mapping)).toEqual('Invite them.'); });
|
||||
|
||||
it('should return an empty text if value is null or undefined', () => {
|
||||
expect(pipe.transform(null, mapping)).toEqual('');
|
||||
expect(pipe.transform(void 0, mapping)).toEqual('');
|
||||
});
|
||||
|
||||
it('should throw on bad arguments',
|
||||
() => { expect(() => pipe.transform('male', <any>'hey')).toThrowError(); });
|
||||
});
|
||||
|
||||
});
|
||||
}
|
78
packages/common/test/pipes/json_pipe_spec.ts
Normal file
78
packages/common/test/pipes/json_pipe_spec.ts
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CommonModule, JsonPipe} from '@angular/common';
|
||||
import {Component} from '@angular/core';
|
||||
import {TestBed, async} from '@angular/core/testing';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
||||
export function main() {
|
||||
describe('JsonPipe', () => {
|
||||
const regNewLine = '\n';
|
||||
let inceptionObj: any;
|
||||
let inceptionObjString: string;
|
||||
let pipe: JsonPipe;
|
||||
|
||||
function normalize(obj: string): string { return obj.replace(regNewLine, ''); }
|
||||
|
||||
beforeEach(() => {
|
||||
inceptionObj = {dream: {dream: {dream: 'Limbo'}}};
|
||||
inceptionObjString = '{\n' +
|
||||
' "dream": {\n' +
|
||||
' "dream": {\n' +
|
||||
' "dream": "Limbo"\n' +
|
||||
' }\n' +
|
||||
' }\n' +
|
||||
'}';
|
||||
|
||||
|
||||
pipe = new JsonPipe();
|
||||
});
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return JSON-formatted string',
|
||||
() => { expect(pipe.transform(inceptionObj)).toEqual(inceptionObjString); });
|
||||
|
||||
it('should return JSON-formatted string even when normalized', () => {
|
||||
const dream1 = normalize(pipe.transform(inceptionObj));
|
||||
const dream2 = normalize(inceptionObjString);
|
||||
expect(dream1).toEqual(dream2);
|
||||
});
|
||||
|
||||
it('should return JSON-formatted string similar to Json.stringify', () => {
|
||||
const dream1 = normalize(pipe.transform(inceptionObj));
|
||||
const dream2 = normalize(JSON.stringify(inceptionObj, null, 2));
|
||||
expect(dream1).toEqual(dream2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('integration', () => {
|
||||
|
||||
@Component({selector: 'test-comp', template: '{{data | json}}'})
|
||||
class TestComp {
|
||||
data: any;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({declarations: [TestComp], imports: [CommonModule]});
|
||||
});
|
||||
|
||||
it('should work with mutable objects', async(() => {
|
||||
const fixture = TestBed.createComponent(TestComp);
|
||||
const mutable: number[] = [1];
|
||||
fixture.componentInstance.data = mutable;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement).toHaveText('[\n 1\n]');
|
||||
|
||||
mutable.push(2);
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement).toHaveText('[\n 1,\n 2\n]');
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
110
packages/common/test/pipes/number_pipe_spec.ts
Normal file
110
packages/common/test/pipes/number_pipe_spec.ts
Normal file
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CurrencyPipe, DecimalPipe, PercentPipe} from '@angular/common';
|
||||
import {isNumeric} from '@angular/common/src/pipes/number_pipe';
|
||||
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
|
||||
import {browserDetection} from '@angular/platform-browser/testing/browser_util';
|
||||
|
||||
export function main() {
|
||||
describe('Number pipes', () => {
|
||||
describe('DecimalPipe', () => {
|
||||
let pipe: DecimalPipe;
|
||||
|
||||
beforeEach(() => { pipe = new DecimalPipe('en-US'); });
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return correct value for numbers', () => {
|
||||
expect(pipe.transform(12345)).toEqual('12,345');
|
||||
expect(pipe.transform(123, '.2')).toEqual('123.00');
|
||||
expect(pipe.transform(1, '3.')).toEqual('001');
|
||||
expect(pipe.transform(1.1, '3.4-5')).toEqual('001.1000');
|
||||
expect(pipe.transform(1.123456, '3.4-5')).toEqual('001.12346');
|
||||
expect(pipe.transform(1.1234)).toEqual('1.123');
|
||||
});
|
||||
|
||||
it('should support strings', () => {
|
||||
expect(pipe.transform('12345')).toEqual('12,345');
|
||||
expect(pipe.transform('123', '.2')).toEqual('123.00');
|
||||
expect(pipe.transform('1', '3.')).toEqual('001');
|
||||
expect(pipe.transform('1.1', '3.4-5')).toEqual('001.1000');
|
||||
expect(pipe.transform('1.123456', '3.4-5')).toEqual('001.12346');
|
||||
expect(pipe.transform('1.1234')).toEqual('1.123');
|
||||
});
|
||||
|
||||
it('should not support other objects', () => {
|
||||
expect(() => pipe.transform(new Object())).toThrowError();
|
||||
expect(() => pipe.transform('123abc')).toThrowError();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PercentPipe', () => {
|
||||
let pipe: PercentPipe;
|
||||
|
||||
beforeEach(() => { pipe = new PercentPipe('en-US'); });
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return correct value for numbers', () => {
|
||||
expect(normalize(pipe.transform(1.23))).toEqual('123%');
|
||||
expect(normalize(pipe.transform(1.2, '.2'))).toEqual('120.00%');
|
||||
});
|
||||
|
||||
it('should not support other objects',
|
||||
() => { expect(() => pipe.transform(new Object())).toThrowError(); });
|
||||
});
|
||||
});
|
||||
|
||||
describe('CurrencyPipe', () => {
|
||||
let pipe: CurrencyPipe;
|
||||
|
||||
beforeEach(() => { pipe = new CurrencyPipe('en-US'); });
|
||||
|
||||
describe('transform', () => {
|
||||
it('should return correct value for numbers', () => {
|
||||
// In old Chrome, default formatiing for USD is different
|
||||
if (browserDetection.isOldChrome) {
|
||||
expect(normalize(pipe.transform(123))).toEqual('USD123');
|
||||
} else {
|
||||
expect(normalize(pipe.transform(123))).toEqual('USD123.00');
|
||||
}
|
||||
expect(normalize(pipe.transform(12, 'EUR', false, '.1'))).toEqual('EUR12.0');
|
||||
expect(normalize(pipe.transform(5.1234, 'USD', false, '.0-3'))).toEqual('USD5.123');
|
||||
});
|
||||
|
||||
it('should not support other objects',
|
||||
() => { expect(() => pipe.transform(new Object())).toThrowError(); });
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNumeric', () => {
|
||||
it('should return true when passing correct numeric string',
|
||||
() => { expect(isNumeric('2')).toBe(true); });
|
||||
|
||||
it('should return true when passing correct double string',
|
||||
() => { expect(isNumeric('1.123')).toBe(true); });
|
||||
|
||||
it('should return true when passing correct negative string',
|
||||
() => { expect(isNumeric('-2')).toBe(true); });
|
||||
|
||||
it('should return true when passing correct scientific notation string',
|
||||
() => { expect(isNumeric('1e5')).toBe(true); });
|
||||
|
||||
it('should return false when passing incorrect numeric',
|
||||
() => { expect(isNumeric('a')).toBe(false); });
|
||||
|
||||
it('should return false when passing parseable but non numeric',
|
||||
() => { expect(isNumeric('2a')).toBe(false); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Between the symbol and the number, Edge adds a no breaking space and IE11 adds a standard space
|
||||
function normalize(s: string): string {
|
||||
return s.replace(/\u00A0| /g, '');
|
||||
}
|
108
packages/common/test/pipes/slice_pipe_spec.ts
Normal file
108
packages/common/test/pipes/slice_pipe_spec.ts
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CommonModule, SlicePipe} from '@angular/common';
|
||||
import {Component} from '@angular/core';
|
||||
import {TestBed, async} from '@angular/core/testing';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
|
||||
export function main() {
|
||||
describe('SlicePipe', () => {
|
||||
let list: number[];
|
||||
let str: string;
|
||||
let pipe: SlicePipe;
|
||||
|
||||
beforeEach(() => {
|
||||
list = [1, 2, 3, 4, 5];
|
||||
str = 'tuvwxyz';
|
||||
pipe = new SlicePipe();
|
||||
});
|
||||
|
||||
describe('supports', () => {
|
||||
it('should support strings', () => { expect(() => pipe.transform(str, 0)).not.toThrow(); });
|
||||
it('should support lists', () => { expect(() => pipe.transform(list, 0)).not.toThrow(); });
|
||||
|
||||
it('should not support other objects',
|
||||
() => { expect(() => pipe.transform({}, 0)).toThrow(); });
|
||||
});
|
||||
|
||||
describe('transform', () => {
|
||||
|
||||
it('should return null if the value is null',
|
||||
() => { expect(pipe.transform(null, 1)).toBe(null); });
|
||||
|
||||
it('should return all items after START index when START is positive and END is omitted',
|
||||
() => {
|
||||
expect(pipe.transform(list, 3)).toEqual([4, 5]);
|
||||
expect(pipe.transform(str, 3)).toEqual('wxyz');
|
||||
});
|
||||
|
||||
it('should return last START items when START is negative and END is omitted', () => {
|
||||
expect(pipe.transform(list, -3)).toEqual([3, 4, 5]);
|
||||
expect(pipe.transform(str, -3)).toEqual('xyz');
|
||||
});
|
||||
|
||||
it('should return all items between START and END index when START and END are positive',
|
||||
() => {
|
||||
expect(pipe.transform(list, 1, 3)).toEqual([2, 3]);
|
||||
expect(pipe.transform(str, 1, 3)).toEqual('uv');
|
||||
});
|
||||
|
||||
it('should return all items between START and END from the end when START and END are negative',
|
||||
() => {
|
||||
expect(pipe.transform(list, -4, -2)).toEqual([2, 3]);
|
||||
expect(pipe.transform(str, -4, -2)).toEqual('wx');
|
||||
});
|
||||
|
||||
it('should return an empty value if START is greater than END', () => {
|
||||
expect(pipe.transform(list, 4, 2)).toEqual([]);
|
||||
expect(pipe.transform(str, 4, 2)).toEqual('');
|
||||
});
|
||||
|
||||
it('should return an empty value if START greater than input length', () => {
|
||||
expect(pipe.transform(list, 99)).toEqual([]);
|
||||
expect(pipe.transform(str, 99)).toEqual('');
|
||||
});
|
||||
|
||||
it('should return entire input if START is negative and greater than input length', () => {
|
||||
expect(pipe.transform(list, -99)).toEqual([1, 2, 3, 4, 5]);
|
||||
expect(pipe.transform(str, -99)).toEqual('tuvwxyz');
|
||||
});
|
||||
|
||||
it('should not modify the input list', () => {
|
||||
expect(pipe.transform(list, 2)).toEqual([3, 4, 5]);
|
||||
expect(list).toEqual([1, 2, 3, 4, 5]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('integration', () => {
|
||||
|
||||
@Component({selector: 'test-comp', template: '{{(data | slice:1).join(",") }}'})
|
||||
class TestComp {
|
||||
data: any;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({declarations: [TestComp], imports: [CommonModule]});
|
||||
});
|
||||
|
||||
it('should work with mutable arrays', async(() => {
|
||||
const fixture = TestBed.createComponent(TestComp);
|
||||
const mutable: number[] = [1, 2];
|
||||
fixture.componentInstance.data = mutable;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement).toHaveText('2');
|
||||
|
||||
mutable.push(3);
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement).toHaveText('2,3');
|
||||
}));
|
||||
});
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user