Set max line length to 120

This commit is contained in:
Rene Saarsoo 2020-09-21 18:11:27 +03:00
parent 79453750e7
commit a390ec62ee
6 changed files with 28 additions and 84 deletions

3
.prettierrc Normal file
View File

@ -0,0 +1,3 @@
{
"printWidth": 120
}

View File

@ -21,11 +21,7 @@ const generateRangeInterval = (
}; };
}; };
const generateSteadyStateInterval = ({ const generateSteadyStateInterval = ({ duration, intensity, cadence }: Interval): xml.XmlObject => {
duration,
intensity,
cadence,
}: Interval): xml.XmlObject => {
return { return {
SteadyState: [ SteadyState: [
{ {
@ -50,12 +46,7 @@ const generateInterval = (interval: Interval): xml.XmlObject => {
} }
}; };
export const generateZwo = ({ export const generateZwo = ({ name, author, description, intervals }: Workout): string => {
name,
author,
description,
intervals,
}: Workout): string => {
return xml( return xml(
{ {
workout_file: [ workout_file: [

View File

@ -122,23 +122,16 @@ Cooldown: 5:30 70%..45%
`); `);
}); });
const parseInterval = (interval: string) => const parseInterval = (interval: string) => parse(`Name: My Workout\n${interval}`).intervals[0];
parse(`Name: My Workout\n${interval}`).intervals[0];
it("requires duration and power parameters to be specified", () => { it("requires duration and power parameters to be specified", () => {
expect(() => expect(() => parseInterval("Interval: 50%")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 50%")
).toThrowErrorMatchingInlineSnapshot(
`"Duration not specified at line 2 char 1"` `"Duration not specified at line 2 char 1"`
); );
expect(() => expect(() => parseInterval("Interval: 30:00")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 30:00")
).toThrowErrorMatchingInlineSnapshot(
`"Power not specified at line 2 char 1"` `"Power not specified at line 2 char 1"`
); );
expect(() => expect(() => parseInterval("Interval: 10rpm")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 10rpm")
).toThrowErrorMatchingInlineSnapshot(
`"Duration not specified at line 2 char 1"` `"Duration not specified at line 2 char 1"`
); );
}); });
@ -180,8 +173,7 @@ Cooldown: 5:30 70%..45%
}); });
it("allows whitespace between interval parameters", () => { it("allows whitespace between interval parameters", () => {
expect(parseInterval("Interval: 50% 00:10 100rpm")) expect(parseInterval("Interval: 50% 00:10 100rpm")).toMatchInlineSnapshot(`
.toMatchInlineSnapshot(`
Object { Object {
"cadence": 100, "cadence": 100,
"duration": 10, "duration": 10,
@ -192,8 +184,7 @@ Cooldown: 5:30 70%..45%
"type": "Interval", "type": "Interval",
} }
`); `);
expect(parseInterval("Interval: \t 50% \t 00:10 \t\t 100rpm \t")) expect(parseInterval("Interval: \t 50% \t 00:10 \t\t 100rpm \t")).toMatchInlineSnapshot(`
.toMatchInlineSnapshot(`
Object { Object {
"cadence": 100, "cadence": 100,
"duration": 10, "duration": 10,
@ -218,50 +209,34 @@ Cooldown: 5:30 70%..45%
}); });
it("throws error for incorrect duration formats", () => { it("throws error for incorrect duration formats", () => {
expect(() => expect(() => parseInterval("Interval: 10 50%")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 10 50%")
).toThrowErrorMatchingInlineSnapshot(
`"Unrecognized interval parameter \\"10\\" at line 2 char 11"` `"Unrecognized interval parameter \\"10\\" at line 2 char 11"`
); );
expect(() => expect(() => parseInterval("Interval: :10 50%")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: :10 50%")
).toThrowErrorMatchingInlineSnapshot(
`"Unrecognized interval parameter \\":10\\" at line 2 char 11"` `"Unrecognized interval parameter \\":10\\" at line 2 char 11"`
); );
expect(() => expect(() => parseInterval("Interval: 0:100 50%")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 0:100 50%")
).toThrowErrorMatchingInlineSnapshot(
`"Unrecognized interval parameter \\"0:100\\" at line 2 char 11"` `"Unrecognized interval parameter \\"0:100\\" at line 2 char 11"`
); );
expect(() => expect(() => parseInterval("Interval: 00:00:00:10 50%")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 00:00:00:10 50%")
).toThrowErrorMatchingInlineSnapshot(
`"Unrecognized interval parameter \\"00:00:00:10\\" at line 2 char 11"` `"Unrecognized interval parameter \\"00:00:00:10\\" at line 2 char 11"`
); );
}); });
it("throws error for unexpected interval parameter", () => { it("throws error for unexpected interval parameter", () => {
expect(() => expect(() => parseInterval("Interval: 10:00 50% foobar")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 10:00 50% foobar")
).toThrowErrorMatchingInlineSnapshot(
`"Unrecognized interval parameter \\"foobar\\" at line 2 char 21"` `"Unrecognized interval parameter \\"foobar\\" at line 2 char 21"`
); );
expect(() => expect(() => parseInterval("Interval: 10:00 50% 123blah")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 10:00 50% 123blah")
).toThrowErrorMatchingInlineSnapshot(
`"Unrecognized interval parameter \\"123blah\\" at line 2 char 21"` `"Unrecognized interval parameter \\"123blah\\" at line 2 char 21"`
); );
expect(() => expect(() => parseInterval("Interval: 10:00 50% ^*&")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 10:00 50% ^*&")
).toThrowErrorMatchingInlineSnapshot(
`"Unrecognized interval parameter \\"^*&\\" at line 2 char 21"` `"Unrecognized interval parameter \\"^*&\\" at line 2 char 21"`
); );
}); });
it("throws error for unexpected type of interval", () => { it("throws error for unexpected type of interval", () => {
expect(() => expect(() => parseInterval("Interval: 30:00 5% \n CustomInterval: 15:00 10%")).toThrowErrorMatchingInlineSnapshot(
parseInterval("Interval: 30:00 5% \n CustomInterval: 15:00 10%")
).toThrowErrorMatchingInlineSnapshot(
`"Unexpected token [text CustomInterval: 15:00 10%] at line 3 char 1"` `"Unexpected token [text CustomInterval: 15:00 10%] at line 3 char 1"`
); );
}); });

View File

@ -51,10 +51,7 @@ const parseHeader = (tokens: Token[]): [Header, Token[]] => {
type IntervalData = Omit<Interval, "type">; type IntervalData = Omit<Interval, "type">;
const parseIntervalParams = ( const parseIntervalParams = (tokens: Token[], loc: SourceLocation): [IntervalData, Token[]] => {
tokens: Token[],
loc: SourceLocation
): [IntervalData, Token[]] => {
const data: Partial<IntervalData> = {}; const data: Partial<IntervalData> = {};
while (tokens[0]) { while (tokens[0]) {
@ -92,10 +89,7 @@ const parseIntervals = (tokens: Token[]): Interval[] => {
while (tokens[0]) { while (tokens[0]) {
const token = tokens.shift() as Token; const token = tokens.shift() as Token;
if (token.type === "label" && isIntervalLabelTokenValue(token.value)) { if (token.type === "label" && isIntervalLabelTokenValue(token.value)) {
const [{ duration, intensity, cadence }, rest] = parseIntervalParams( const [{ duration, intensity, cadence }, rest] = parseIntervalParams(tokens, token.loc);
tokens,
token.loc
);
intervals.push({ intervals.push({
type: token.value, type: token.value,
duration, duration,
@ -106,10 +100,7 @@ const parseIntervals = (tokens: Token[]): Interval[] => {
} else if (token.type === "text" && token.value === "") { } else if (token.type === "text" && token.value === "") {
// Ignore empty lines // Ignore empty lines
} else { } else {
throw new ParseError( throw new ParseError(`Unexpected token [${token.type} ${token.value}]`, token.loc);
`Unexpected token [${token.type} ${token.value}]`,
token.loc
);
} }
} }
@ -120,10 +111,7 @@ export const parseTokens = (tokens: Token[]): Workout => {
const [header, intervalTokens] = parseHeader(tokens); const [header, intervalTokens] = parseHeader(tokens);
if (header.name === undefined) { if (header.name === undefined) {
throw new ParseError( throw new ParseError("Workout is missing a name. Use `Name:` to declare one.", { row: 0, col: 0 });
"Workout is missing a name. Use `Name:` to declare one.",
{ row: 0, col: 0 }
);
} }
return { return {

View File

@ -1,21 +1,13 @@
import { ParseError } from "./ParseError"; import { ParseError } from "./ParseError";
export type HeaderLabelTokenValue = "Name" | "Author" | "Description"; export type HeaderLabelTokenValue = "Name" | "Author" | "Description";
export type IntervalLabelTokenValue = export type IntervalLabelTokenValue = "Warmup" | "Rest" | "Interval" | "Cooldown";
| "Warmup"
| "Rest"
| "Interval"
| "Cooldown";
export type LabelTokenValue = HeaderLabelTokenValue | IntervalLabelTokenValue; export type LabelTokenValue = HeaderLabelTokenValue | IntervalLabelTokenValue;
export const isHeaderLabelTokenValue = ( export const isHeaderLabelTokenValue = (value: string): value is HeaderLabelTokenValue => {
value: string
): value is HeaderLabelTokenValue => {
return ["Name", "Author", "Description"].includes(value); return ["Name", "Author", "Description"].includes(value);
}; };
export const isIntervalLabelTokenValue = ( export const isIntervalLabelTokenValue = (value: string): value is IntervalLabelTokenValue => {
value: string
): value is IntervalLabelTokenValue => {
return ["Warmup", "Rest", "Interval", "Cooldown"].includes(value); return ["Warmup", "Rest", "Interval", "Cooldown"].includes(value);
}; };
export const isLabelTokenValue = (value: string): value is LabelTokenValue => { export const isLabelTokenValue = (value: string): value is LabelTokenValue => {
@ -78,11 +70,7 @@ const tokenizeValueParam = (text: string, loc: SourceLocation): Token => {
throw new ParseError(`Unrecognized interval parameter "${text}"`, loc); throw new ParseError(`Unrecognized interval parameter "${text}"`, loc);
}; };
const tokenizeParams = ( const tokenizeParams = (type: LabelTokenValue, text: string, loc: SourceLocation): Token[] => {
type: LabelTokenValue,
text: string,
loc: SourceLocation
): Token[] => {
switch (type) { switch (type) {
case "Name": case "Name":
case "Author": case "Author":

View File

@ -1,5 +1,4 @@
import { pluck, sum } from "ramda"; import { pluck, sum } from "ramda";
import { Interval } from "../ast"; import { Interval } from "../ast";
export const totalDuration = (intervals: Interval[]) => export const totalDuration = (intervals: Interval[]) => sum(pluck("duration", intervals));
sum(pluck("duration", intervals));