Skip to content

Commit

Permalink
Add context now nmethod, update relative-time test
Browse files Browse the repository at this point in the history
  • Loading branch information
phensley committed Mar 2, 2020
1 parent 8c6873f commit 48bfbab
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 29 deletions.
2 changes: 2 additions & 0 deletions __tests__/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,13 @@ export class TemplateTestLoader extends TestLoader {

// i18n-enable the execution context
const locale = (params || {}).locale || 'en';
const now: number | undefined = (params || {}).now;
const cldr = framework.get(locale);

// execute the test case
const { ctx } = compiler.execute({
cldr,
now,
code: spec.TEMPLATE,
json: spec.JSON,
partials: spec.PARTIALS,
Expand Down
22 changes: 9 additions & 13 deletions __tests__/plugins/formatters.i18n.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,22 +68,14 @@ const formatInterval = (cldr: CLDR | undefined, start: number, end: number, zone

const formatRelativeTime = (cldr: CLDR | undefined, start: number | undefined, vars: Variable[], args: string[]) => {
const impl = TABLE['relative-time'] as RelativeTimeFormatter;
if (start) {
impl.NOW = new Date(start);
}
const ctx = new Context({}, { cldr });
const ctx = new Context({}, { cldr, now: start });
impl.apply(args, vars, ctx);
return vars[0].get();
};

const formatTimeSince = (cldr: CLDR | undefined, start: Date | undefined, end: number, args: string[]) => {
const formatTimeSince = (cldr: CLDR | undefined, start: number | undefined, end: number, args: string[]) => {
const impl = TABLE.timesince as TimeSinceFormatter;
// 'timesince' formatter computes relative to now, so use a special
// property on the formatter to set "now"
if (start) {
impl.NOW = start;
}
const ctx = new Context({}, { cldr });
const ctx = new Context({}, { cldr, now: start });
const vars = variables(end);
impl.apply(args, vars, ctx);
return vars[0].get();
Expand Down Expand Up @@ -249,6 +241,10 @@ test('message', () => {
expect(formatMessage(EN, '{0 datetime}', args, ctx)).toEqual('');
});

pathseq('f-relative-time-%N.html', 1).forEach(path => {
test(`relative time - ${path}`, () => loader.execute(path));
});

test('relative time', () => {
const base = new Date().getTime();
const start = EN.Calendars.toGregorianDate({ date: base });
Expand Down Expand Up @@ -308,8 +304,8 @@ test('relative time', () => {
});

test('timesince', () => {
const base = new Date();
const start = EN.Calendars.toGregorianDate(base);
const base = new Date().getTime();
const start = EN.Calendars.toGregorianDate({ date: base });
const args: string[] = [];
let e: number;

Expand Down
30 changes: 30 additions & 0 deletions __tests__/plugins/resources/f-relative-time-1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
:PARAMS
{
"now": 1502298000000
}

:JSON
{
"dates": [
{"start": 1509647217000, "end": 1510641417000},
{"start": 1502298000000, "end": 1502305200000}
],
"timestamps": [
1502305200000,
1502258000000
]
}


:TEMPLATE
{.repeated section dates}
{start, end|relative-time}{.end}
{.repeated section timestamps}
{@|relative-time context=begin-sentence}{.end}

:OUTPUT
in 2 weeks
in 2 hours

in 2 hours
11 hours ago
7 changes: 4 additions & 3 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Matcher } from './matcher';

const EMPTY_CODE: Code = [Opcode.ROOT, 1, [], Opcode.EOF];

export interface CompilerProps extends EngineProps {}
export interface CompilerProps extends EngineProps { }

export type InjectsMap = { [path: string]: any };

Expand All @@ -22,6 +22,7 @@ export interface ExecuteProps {
partials?: Partials;
injects?: InjectsMap;
cldr?: CLDR;
now?: number;
}

export interface ParseResult {
Expand Down Expand Up @@ -86,14 +87,14 @@ export class Compiler {
*/
execute(props: ExecuteProps = DefaultExecuteProps): ExecuteResult {
let code: string | Code = props.code;
const { cldr, json, partials, injects } = props;
const { cldr, now, json, partials, injects } = props;
let errors: TemplateError[] = [];

if (typeof code === 'string') {
({ code, errors } = this.parse(code));
}

const ctx = new Context(json, { cldr, partials, injects });
const ctx = new Context(json, { cldr, now, partials, injects });
ctx.parsefunc = (raw: string) => this.parse(raw);
this.engine.execute(code, ctx);

Expand Down
11 changes: 7 additions & 4 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export interface ContextProps {
partials?: Partials;
injects?: any;
cldr?: CLDR;
// Override the 'now' timestamp
now?: number;
}

type ParseFunc = (s: string) => { code: Code, errors: TemplateError[] };
Expand All @@ -39,9 +41,10 @@ export class Context {
public version: number;
public engine: ContextEngineRef | null;
public parsefunc: ParseFunc | null;
public errors: any[];
public cldr?: CLDR;
public formatter?: MessageFormats;
readonly errors: any[];
readonly cldr?: CLDR;
readonly now?: number;
readonly formatter?: MessageFormats;

private locale?: any;
private partials: Partials;
Expand All @@ -61,13 +64,13 @@ export class Context {
this.locale = props.locale;
this.partials = props.partials || {};
this.injects = props.injects || {};
this.now = props.now;

// Instance of @phensley/cldr interface CLDR providing cldr-based formatting for
// a given locale. It is the caller's responsibility to set this. If not
// set you will experience partial functionality. All @phensley/cldr-based
// formatters will return '' and predicates will evaluate to false.
this.cldr = props.cldr;

// If i18n is enabled, define the message formatter
if (this.cldr) {
this.formatter = new MessageFormats(this.cldr);
Expand Down
13 changes: 4 additions & 9 deletions src/plugins/formatters.i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,14 @@ export class MoneyFormatter extends Formatter {

export class RelativeTimeFormatter extends Formatter {

// exposed only for testing
public NOW: Date | undefined;

apply(args: string[], vars: Variable[], ctx: Context): void {
const first = vars[0];
const { cldr } = ctx;
if (!cldr) {
first.set('');
return;
}
let s = (this.NOW || new Date()).getTime();
let s = ctx.now === undefined ? new Date().getTime() : ctx.now;
let e = first.node.asNumber();
if (vars.length > 1) {
s = e;
Expand All @@ -212,9 +209,6 @@ export class RelativeTimeFormatter extends Formatter {

export class TimeSinceFormatter extends Formatter {

// exposed only for testing
public NOW: Date | undefined;

apply(args: string[], vars: Variable[], ctx: Context): void {
const first = vars[0];
const n = first.node.asNumber();
Expand All @@ -223,10 +217,11 @@ export class TimeSinceFormatter extends Formatter {
first.set('');
return;
}
const now = cldr.Calendars.toGregorianDate(this.NOW || new Date());
const now = ctx.now === undefined ? new Date().getDate() : ctx.now;
const base = cldr.Calendars.toGregorianDate({ date: now });
const date = cldr.Calendars.toGregorianDate({ date: n });

const delta = now.unixEpoch() - date.unixEpoch();
const delta = base.unixEpoch() - date.unixEpoch();
const res = humanizeDate(delta, false);
first.set(res);
}
Expand Down

0 comments on commit 48bfbab

Please sign in to comment.