Skip to content

Commit 4a41097

Browse files
Add The Typeinator > 01. Syntactic Sugar (#239)
* Add The Typeinator > 01. Syntactic Sugar * Fix its README.md * Fix files test * tsc exit 0 for the-typeinator
1 parent e9058c8 commit 4a41097

File tree

21 files changed

+154
-18
lines changed

21 files changed

+154
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Step 1: Syntactic Sugar
2+
3+
> _"In computer science, syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express."_ - [Wikipedia](https://en.wikipedia.org/wiki/Syntactic_sugar)
4+
5+
The first project you must improve is written in relatively old JavaScript style.
6+
Its `announceMachines` function, as written in the [`original.js`](./original.js) file, is meant to receive an `announce` function and any number of machine objects.
7+
It does two things:
8+
9+
- Call `announce` for each of the machine objects: with the machine's `label` property if it exists, or with its `make` and `model` properties if not
10+
- Return a number indicating how many machine objects had a `label` property
11+
12+
That function uses `var` for variables, `arguments` for allowing a flexible number of arguments, and manual string concatenation.
13+
Can you imagine humans previously writing code in that way?
14+
15+
Your task is to rewrite the function using more modern JavaScript syntax.
16+
17+
## Specification
18+
19+
In `index.js`, export an `announceMachines` function that:
20+
21+
- Uses `let` and `const` instead of `var` for variables
22+
- Uses `...` spread for arguments instead of `arguments`
23+
- Uses a `for`-`of` loop instead of a loop
24+
- Uses <code>\`</code> template string literal concatenation instead of `+`
25+
26+
## Files
27+
28+
- `index.js`: Write your `announceMachines` function here
29+
- `index.test.js`: Tests verifying `announceMachines`
30+
- `solution.js`: Solution code
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Put your announceMachines function here! ✨
2+
// See ./original.js for its older JavaScript code.
3+
4+
module.exports.announceMachines = announceMachines;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
const { announceMachines } = process.env.TEST_SOLUTIONS
2+
? require("./solution")
3+
: require("./index");
4+
5+
describe(announceMachines, () => {
6+
it("announces a machine's label when the label exists", () => {
7+
const announce = jest.fn();
8+
const label = "test label";
9+
10+
announceMachines(announce, { label });
11+
12+
expect(announce).toHaveBeenCalledWith(label);
13+
});
14+
15+
it("announces a machine's make and model when it does not have a label", () => {
16+
const announce = jest.fn();
17+
const make = "test make";
18+
const model = "test model";
19+
20+
announceMachines(announce, { make, model });
21+
22+
expect(announce).toHaveBeenCalledWith(`Make: test make; Model: test model`);
23+
});
24+
25+
it("returns an increased count when a machine has a label", () => {
26+
const announce = jest.fn();
27+
28+
const labelsCount = announceMachines(announce, { label: "test label" });
29+
30+
expect(labelsCount).toBe(1);
31+
});
32+
33+
it("returns a non-increased count when a machine does not has a label", () => {
34+
const announce = jest.fn();
35+
36+
const labelsCount = announceMachines(announce, { make: "", model: "" });
37+
38+
expect(labelsCount).toBe(0);
39+
});
40+
41+
it("returns an increased count for labels when only some machines have label", () => {
42+
const announce = jest.fn();
43+
44+
const labelsCount = announceMachines(
45+
announce,
46+
{ label: "test label" },
47+
{ make: "", model: "" },
48+
{ label: "test label" }
49+
);
50+
51+
expect(labelsCount).toBe(2);
52+
});
53+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
function announceMachines(announce) {
2+
var label;
3+
var labelsCount = 0;
4+
5+
for (var i = 1; i < arguments.length; i += 1) {
6+
const machine = arguments[i];
7+
8+
if (machine.label) {
9+
label = machine.label;
10+
labelsCount += 1;
11+
} else {
12+
label = "Make: " + machine.make + "; Model: " + machine.model;
13+
}
14+
15+
announce(label);
16+
}
17+
18+
return labelsCount;
19+
}
20+
21+
module.exports.announceMachines = announceMachines;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function announceMachines(announce, ...machines) {
2+
let labelsCount = 0;
3+
4+
for (const machine of machines) {
5+
let label;
6+
7+
if (machine.label) {
8+
label = machine.label;
9+
labelsCount += 1;
10+
} else {
11+
label = `Make: ${machine.make}; Model: ${machine.model}`;
12+
}
13+
14+
announce(label);
15+
}
16+
17+
return labelsCount;
18+
}
19+
20+
module.exports.announceMachines = announceMachines;

Diff for: projects/from-javascript-to-typescript/the-typeinator/01-prototypes-to-classes/README.md renamed to projects/from-javascript-to-typescript/the-typeinator/02-prototypes-to-classes/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Step 1: Prototypes to Classes
1+
# Step 2: Prototypes to Classes
22

3-
The first project for you to overhaul hails from before the time of `class` syntax.
3+
The next project for you to overhaul hails from before the time of `class` syntax.
44
How primitive.
55

66
The [`original.js`](./original.js) file contains the project's original code for `Robot` and `Humanoid` functions used as classes.

Diff for: projects/from-javascript-to-typescript/the-typeinator/02-callbacks-to-async-await/README.md renamed to projects/from-javascript-to-typescript/the-typeinator/03-callbacks-to-async-await/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# Step 2: Callbacks to Async Await
1+
# Step 3: Callbacks to Async Await
22

33
Your operational results are within the expected parameters.
4-
Time for the next project.
4+
Time for the last project.
55

66
The [`original.js`](./original.js) file contains the project's original code for `checkEmotion` and `speak` functions.
77
In this time period, those functions are written with traditional Node-style callback parameters.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "../../../../tsconfig.json",
3+
"include": ["."]
4+
}

Diff for: projects/from-javascript-to-typescript/the-typeinator/README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ npm run test -- 1 --watch
2424

2525
## Steps
2626

27-
- [1. Prototypes to Classes](./01-prototypes-to-classes)
28-
- [2. Callbacks to Async Await](./02-callbacks-to-async-await)
27+
- [1. Syntactic Sugar](./01-syntactic-sugar)
28+
- [2. Prototypes to Classes](./01-prototypes-to-classes)
29+
- [3. Callbacks to Async Await](./02-callbacks-to-async-await)
2930

3031
## Notes
3132

Diff for: projects/from-javascript-to-typescript/the-typeinator/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"scripts": {
44
"test": "jest",
55
"test:solutions": "cross-env TEST_SOLUTIONS=1 jest",
6-
"tsc": "tsc"
6+
"tsc": "exit 0"
77
}
88
}

Diff for: test/files.test.ts

+14-11
Original file line numberDiff line numberDiff line change
@@ -71,29 +71,32 @@ for (const chapterSlug of fs.readdirSync("projects")) {
7171
`> A [Learning TypeScript > ${chapterTitle}](https://learning-typescript.com/${chapterSlug}) 🥗 appetizer project.`
7272
);
7373
expect(contents).toContain(`## Setup`);
74-
expect(contents)
75-
.toContain(`un the TypeScript compiler via the \`tsc\` script within whichever step you're working on.
74+
75+
if (projectSlug !== "the-typeinator") {
76+
expect(contents)
77+
.toContain(`un the TypeScript compiler via the \`tsc\` script within whichever step you're working on.
7678
For example, to start the TypeScript compiler on the first step in watch mode:
7779
7880
\`\`\`shell
7981
npm run tsc -- --project ${stepSlugs[0]} --watch
8082
\`\`\`
8183
`);
8284

83-
if (contents.includes("run Jest")) {
84-
expect(contents).toContain(
85-
"In one terminal, run the TypeScript compiler"
86-
);
87-
expect(contents).toContain(
88-
`In another terminal, run Jest via the \`test\` script on whichever step you're working on.
85+
if (contents.includes("run Jest")) {
86+
expect(contents).toContain(
87+
"In one terminal, run the TypeScript compiler"
88+
);
89+
expect(contents).toContain(
90+
`In another terminal, run Jest via the \`test\` script on whichever step you're working on.
8991
For example, to start tests for the first step in watch mode:
9092
9193
\`\`\`shell
9294
npm run test -- 1 --watch
9395
\`\`\``
94-
);
95-
} else {
96-
expect(contents).toContain("In your terminal, run the");
96+
);
97+
} else {
98+
expect(contents).toContain("In your terminal, run the");
99+
}
97100
}
98101
});
99102

0 commit comments

Comments
 (0)