269 lines
7.0 KiB
TypeScript
269 lines
7.0 KiB
TypeScript
import { parse } from ".";
|
|
|
|
describe("Parser", () => {
|
|
it("throws error for empty file", () => {
|
|
expect(() => parse("")).toThrowErrorMatchingInlineSnapshot(
|
|
`"Workout is missing a name. Use \`Name:\` to declare one. at line 1 char 1"`
|
|
);
|
|
|
|
expect(() => parse(" \n \n \t")).toThrowErrorMatchingInlineSnapshot(
|
|
`"Workout is missing a name. Use \`Name:\` to declare one. at line 1 char 1"`
|
|
);
|
|
});
|
|
|
|
it("parses workout with just Name field", () => {
|
|
expect(parse(`Name: My Workout`)).toMatchInlineSnapshot(`
|
|
Object {
|
|
"author": "",
|
|
"description": "",
|
|
"intervals": Array [],
|
|
"name": "My Workout",
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("parses workout header with all fields", () => {
|
|
expect(
|
|
parse(`
|
|
Name: My Workout
|
|
Author: John Doe
|
|
Description:
|
|
It's a great workout.
|
|
|
|
Do it when you dare,
|
|
it'll cause lots of pain.
|
|
`)
|
|
).toMatchInlineSnapshot(`
|
|
Object {
|
|
"author": "John Doe",
|
|
"description": "It's a great workout.
|
|
|
|
Do it when you dare,
|
|
it'll cause lots of pain.",
|
|
"intervals": Array [],
|
|
"name": "My Workout",
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("parses basic intervals", () => {
|
|
expect(
|
|
parse(`
|
|
Name: My Workout
|
|
|
|
Rest: 5:00 50%
|
|
|
|
Interval: 10:00 80% 90rpm
|
|
|
|
Rest: 5:00 45%
|
|
`).intervals
|
|
).toMatchInlineSnapshot(`
|
|
Array [
|
|
Object {
|
|
"cadence": undefined,
|
|
"duration": 300,
|
|
"intensity": Object {
|
|
"from": 0.5,
|
|
"to": 0.5,
|
|
},
|
|
"type": "Rest",
|
|
},
|
|
Object {
|
|
"cadence": 90,
|
|
"duration": 600,
|
|
"intensity": Object {
|
|
"from": 0.8,
|
|
"to": 0.8,
|
|
},
|
|
"type": "Interval",
|
|
},
|
|
Object {
|
|
"cadence": undefined,
|
|
"duration": 300,
|
|
"intensity": Object {
|
|
"from": 0.45,
|
|
"to": 0.45,
|
|
},
|
|
"type": "Rest",
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
it("parses power-range intervals", () => {
|
|
expect(
|
|
parse(`
|
|
Name: My Workout
|
|
|
|
Warmup: 5:30 50%..80% 100rpm
|
|
Cooldown: 5:30 70%..45%
|
|
`).intervals
|
|
).toMatchInlineSnapshot(`
|
|
Array [
|
|
Object {
|
|
"cadence": 100,
|
|
"duration": 330,
|
|
"intensity": Object {
|
|
"from": 0.5,
|
|
"to": 0.8,
|
|
},
|
|
"type": "Warmup",
|
|
},
|
|
Object {
|
|
"cadence": undefined,
|
|
"duration": 330,
|
|
"intensity": Object {
|
|
"from": 0.7,
|
|
"to": 0.45,
|
|
},
|
|
"type": "Cooldown",
|
|
},
|
|
]
|
|
`);
|
|
});
|
|
|
|
const parseInterval = (interval: string) =>
|
|
parse(`Name: My Workout\n${interval}`).intervals[0];
|
|
|
|
it("requires duration and power parameters to be specified", () => {
|
|
expect(() =>
|
|
parseInterval("Interval: 50%")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Duration not specified at line 2 char 1"`
|
|
);
|
|
expect(() =>
|
|
parseInterval("Interval: 30:00")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Power not specified at line 2 char 1"`
|
|
);
|
|
expect(() =>
|
|
parseInterval("Interval: 10rpm")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Duration not specified at line 2 char 1"`
|
|
);
|
|
});
|
|
|
|
it("allows any order for interval parameters", () => {
|
|
expect(parseInterval("Interval: 50% 00:10")).toMatchInlineSnapshot(`
|
|
Object {
|
|
"cadence": undefined,
|
|
"duration": 10,
|
|
"intensity": Object {
|
|
"from": 0.5,
|
|
"to": 0.5,
|
|
},
|
|
"type": "Interval",
|
|
}
|
|
`);
|
|
expect(parseInterval("Interval: 50% 100rpm 00:10")).toMatchInlineSnapshot(`
|
|
Object {
|
|
"cadence": 100,
|
|
"duration": 10,
|
|
"intensity": Object {
|
|
"from": 0.5,
|
|
"to": 0.5,
|
|
},
|
|
"type": "Interval",
|
|
}
|
|
`);
|
|
expect(parseInterval("Interval: 100rpm 00:10 50%")).toMatchInlineSnapshot(`
|
|
Object {
|
|
"cadence": 100,
|
|
"duration": 10,
|
|
"intensity": Object {
|
|
"from": 0.5,
|
|
"to": 0.5,
|
|
},
|
|
"type": "Interval",
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("allows whitespace between interval parameters", () => {
|
|
expect(parseInterval("Interval: 50% 00:10 100rpm"))
|
|
.toMatchInlineSnapshot(`
|
|
Object {
|
|
"cadence": 100,
|
|
"duration": 10,
|
|
"intensity": Object {
|
|
"from": 0.5,
|
|
"to": 0.5,
|
|
},
|
|
"type": "Interval",
|
|
}
|
|
`);
|
|
expect(parseInterval("Interval: \t 50% \t 00:10 \t\t 100rpm \t"))
|
|
.toMatchInlineSnapshot(`
|
|
Object {
|
|
"cadence": 100,
|
|
"duration": 10,
|
|
"intensity": Object {
|
|
"from": 0.5,
|
|
"to": 0.5,
|
|
},
|
|
"type": "Interval",
|
|
}
|
|
`);
|
|
});
|
|
|
|
it("parses correct duration formats", () => {
|
|
expect(parseInterval("Interval: 0:10 50%").duration).toEqual(10);
|
|
expect(parseInterval("Interval: 00:10 50%").duration).toEqual(10);
|
|
expect(parseInterval("Interval: 0:00:10 50%").duration).toEqual(10);
|
|
expect(parseInterval("Interval: 0:02:05 50%").duration).toEqual(125);
|
|
expect(parseInterval("Interval: 1:00:00 50%").duration).toEqual(3600);
|
|
expect(parseInterval("Interval: 1:00:0 50%").duration).toEqual(3600);
|
|
expect(parseInterval("Interval: 1:0:0 50%").duration).toEqual(3600);
|
|
expect(parseInterval("Interval: 10:00:00 50%").duration).toEqual(36000);
|
|
});
|
|
|
|
it("throws error for incorrect duration formats", () => {
|
|
expect(() =>
|
|
parseInterval("Interval: 10 50%")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unrecognized interval parameter \\"10\\" at line 2 char 11"`
|
|
);
|
|
expect(() =>
|
|
parseInterval("Interval: :10 50%")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unrecognized interval parameter \\":10\\" at line 2 char 11"`
|
|
);
|
|
expect(() =>
|
|
parseInterval("Interval: 0:100 50%")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unrecognized interval parameter \\"0:100\\" at line 2 char 11"`
|
|
);
|
|
expect(() =>
|
|
parseInterval("Interval: 00:00:00:10 50%")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unrecognized interval parameter \\"00:00:00:10\\" at line 2 char 11"`
|
|
);
|
|
});
|
|
|
|
it("throws error for unexpected interval parameter", () => {
|
|
expect(() =>
|
|
parseInterval("Interval: 10:00 50% foobar")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unrecognized interval parameter \\"foobar\\" at line 2 char 21"`
|
|
);
|
|
expect(() =>
|
|
parseInterval("Interval: 10:00 50% 123blah")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unrecognized interval parameter \\"123blah\\" at line 2 char 21"`
|
|
);
|
|
expect(() =>
|
|
parseInterval("Interval: 10:00 50% ^*&")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unrecognized interval parameter \\"^*&\\" at line 2 char 21"`
|
|
);
|
|
});
|
|
|
|
it("throws error for unexpected type of interval", () => {
|
|
expect(() =>
|
|
parseInterval("Interval: 30:00 5% \n CustomInterval: 15:00 10%")
|
|
).toThrowErrorMatchingInlineSnapshot(
|
|
`"Unexpected token [text CustomInterval: 15:00 10%] at line 3 char 1"`
|
|
);
|
|
});
|
|
});
|