Skip to content

Commit 3e98b7c

Browse files
authored
Add tests for propUpgrades functions (#1914)
## Summary: Only 3 widgets seem to use the `propUpgrades` mechanism: - Radio - Expression - Measurer None of them seemed to have tests (at least not direct tests), so this adds them. I also took out underscore after I wrote the tests. ## Test plan: This is the test plan Author: handeyeco Reviewers: jeremywiebe, handeyeco Required Reviewers: Approved By: jeremywiebe Checks: ✅ Publish npm snapshot (ubuntu-latest, 20.x), ✅ Lint, Typecheck, Format, and Test (ubuntu-latest, 20.x), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 20.x), ✅ Check builds for changes in size (ubuntu-latest, 20.x), ✅ Cypress (ubuntu-latest, 20.x), ✅ Publish Storybook to Chromatic (ubuntu-latest, 20.x), ✅ gerald Pull Request URL: #1914
1 parent ee09e9f commit 3e98b7c

File tree

6 files changed

+138
-27
lines changed

6 files changed

+138
-27
lines changed

.changeset/two-feet-care.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@khanacademy/perseus": patch
3+
---
4+
5+
Add tests for propUpgrades functions (and remove underscore usage)

packages/perseus/src/widgets/expression/expression.test.tsx

+36-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ import {
1717
expressionItemWithLabels,
1818
} from "./expression.testdata";
1919

20-
import type {PerseusItem} from "../../perseus-types";
20+
import type {
21+
PerseusExpressionWidgetOptions,
22+
PerseusItem,
23+
} from "../../perseus-types";
2124
import type {UserEvent} from "@testing-library/user-event";
2225

2326
const renderAndAnswer = async (
@@ -523,4 +526,36 @@ describe("Expression Widget", function () {
523526
).toBeNull();
524527
});
525528
});
529+
530+
describe("propUpgrades", () => {
531+
it("can upgrade from v0 to v1", () => {
532+
const v0props = {
533+
times: false,
534+
buttonSets: ["basic"],
535+
functions: [],
536+
form: false,
537+
simplify: false,
538+
value: "42",
539+
};
540+
541+
const expected: PerseusExpressionWidgetOptions = {
542+
times: false,
543+
buttonSets: ["basic"],
544+
functions: [],
545+
answerForms: [
546+
{
547+
considered: "correct",
548+
form: false,
549+
simplify: false,
550+
value: "42",
551+
},
552+
],
553+
};
554+
555+
const result: PerseusExpressionWidgetOptions =
556+
ExpressionWidgetExport.propUpgrades["1"](v0props);
557+
558+
expect(result).toEqual(expected);
559+
});
560+
});
526561
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import MeasurerWidgetExport from "./measurer";
2+
3+
import type {PerseusMeasurerWidgetOptions} from "../../perseus-types";
4+
5+
describe("measurer", () => {
6+
describe("propUpgrades", () => {
7+
it("can upgrade from v0 to v1", () => {
8+
const v0props = {
9+
imageUrl: "url",
10+
imageTop: 42,
11+
imageLeft: 42,
12+
showProtractor: false,
13+
showRuler: false,
14+
rulerLabel: "test",
15+
rulerTicks: 4,
16+
rulerPixels: 4,
17+
rulerLength: 4,
18+
box: [4, 4],
19+
static: false,
20+
};
21+
22+
const expected: PerseusMeasurerWidgetOptions = {
23+
image: {
24+
url: "url",
25+
top: 42,
26+
left: 42,
27+
},
28+
showProtractor: false,
29+
showRuler: false,
30+
rulerLabel: "test",
31+
rulerTicks: 4,
32+
rulerPixels: 4,
33+
rulerLength: 4,
34+
box: [4, 4],
35+
static: false,
36+
};
37+
38+
const result: PerseusMeasurerWidgetOptions =
39+
MeasurerWidgetExport.propUpgrades["1"](v0props);
40+
41+
expect(result).toEqual(expected);
42+
});
43+
});
44+
});

packages/perseus/src/widgets/measurer/measurer.tsx

+11-13
Original file line numberDiff line numberDiff line change
@@ -182,19 +182,17 @@ class Measurer extends React.Component<Props> implements Widget {
182182
}
183183

184184
const propUpgrades = {
185-
"1": (v0props: any): any => {
186-
const v1props = _(v0props)
187-
.chain()
188-
.omit("imageUrl", "imageTop", "imageLeft")
189-
.extend({
190-
image: {
191-
url: v0props.imageUrl,
192-
top: v0props.imageTop,
193-
left: v0props.imageLeft,
194-
},
195-
})
196-
.value();
197-
return v1props;
185+
"1": (v0props: any): PerseusMeasurerWidgetOptions => {
186+
const {imageUrl, imageTop, imageLeft, ...rest} = v0props;
187+
188+
return {
189+
...rest,
190+
image: {
191+
url: imageUrl,
192+
top: imageTop,
193+
left: imageLeft,
194+
},
195+
};
198196
},
199197
} as const;
200198

packages/perseus/src/widgets/radio/__tests__/radio.test.ts

+34-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as Dependencies from "../../../dependencies";
88
import {mockStrings} from "../../../strings";
99
import {renderQuestion} from "../../__testutils__/renderQuestion";
1010
import PassageWidget from "../../passage";
11+
import RadioWidgetExport from "../radio";
1112
import scoreRadio from "../score-radio";
1213

1314
import {
@@ -17,7 +18,10 @@ import {
1718
shuffledNoneQuestion,
1819
} from "./radio.testdata";
1920

20-
import type {PerseusRenderer} from "../../../perseus-types";
21+
import type {
22+
PerseusRadioWidgetOptions,
23+
PerseusRenderer,
24+
} from "../../../perseus-types";
2125
import type {APIOptions} from "../../../types";
2226
import type {PerseusRadioUserInput} from "../../../validation.types";
2327
import type {UserEvent} from "@testing-library/user-event";
@@ -984,3 +988,32 @@ describe("scoring", () => {
984988
expect(renderer).toHaveBeenAnsweredIncorrectly();
985989
});
986990
});
991+
992+
describe("propsUpgrade", () => {
993+
it("can upgrade from v0 to v1", () => {
994+
const v0props = {
995+
choices: [{content: "Choice 1"}, {content: "Choice 2"}],
996+
};
997+
998+
const expected: PerseusRadioWidgetOptions = {
999+
choices: [{content: "Choice 1"}, {content: "Choice 2"}],
1000+
hasNoneOfTheAbove: false,
1001+
};
1002+
1003+
const result: PerseusRadioWidgetOptions =
1004+
RadioWidgetExport.propUpgrades["1"](v0props);
1005+
1006+
expect(result).toEqual(expected);
1007+
});
1008+
1009+
it("throws from noneOfTheAbove", () => {
1010+
const v0props = {
1011+
choices: [{content: "Choice 1"}, {content: "Choice 2"}],
1012+
noneOfTheAbove: true,
1013+
};
1014+
1015+
expect(() => RadioWidgetExport.propUpgrades["1"](v0props)).toThrow(
1016+
"radio widget v0 no longer supports auto noneOfTheAbove",
1017+
);
1018+
});
1019+
});

packages/perseus/src/widgets/radio/radio.ts

+8-12
Original file line numberDiff line numberDiff line change
@@ -126,23 +126,19 @@ const transform = (
126126
};
127127

128128
const propUpgrades = {
129-
"1": (v0props: any): any => {
130-
let choices;
131-
let hasNoneOfTheAbove;
132-
133-
if (!v0props.noneOfTheAbove) {
134-
choices = v0props.choices;
135-
hasNoneOfTheAbove = false;
136-
} else {
129+
"1": (v0props: any): PerseusRadioWidgetOptions => {
130+
const {noneOfTheAbove, ...rest} = v0props;
131+
132+
if (noneOfTheAbove) {
137133
throw new Error(
138134
"radio widget v0 no longer supports auto noneOfTheAbove",
139135
);
140136
}
141137

142-
return _.extend(_.omit(v0props, "noneOfTheAbove"), {
143-
choices: choices,
144-
hasNoneOfTheAbove: hasNoneOfTheAbove,
145-
});
138+
return {
139+
...rest,
140+
hasNoneOfTheAbove: false,
141+
};
146142
},
147143
} as const;
148144

0 commit comments

Comments
 (0)