This commit is contained in:
2022-11-08 21:44:49 +01:00
parent f2d367cd67
commit 1c52c91e7f
13 changed files with 16463 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
!.meta
# Protected or generated
.git
.vscode
# When using npm
node_modules/*
# Configuration files
.eslintrc.cjs
babel.config.cjs
jest.config.cjs

View File

@@ -0,0 +1,41 @@
module.exports = {
root: true,
parserOptions: {
tsconfigRootDir: __dirname,
project: ['./tsconfig.json'],
},
overrides: [
// Student provided files
{
files: ['*.ts'],
excludedFiles: ['.meta/proof.ci.ts', '.meta/exemplar.ts', '*.test.ts'],
extends: '@exercism/eslint-config-typescript',
},
// Exercism given tests
{
files: ['*.test.ts'],
excludedFiles: ['custom.test.ts'],
env: {
jest: true,
},
extends: '@exercism/eslint-config-typescript/maintainers',
},
// Student provided tests
{
files: ['custom.test.ts'],
env: {
jest: true,
},
extends: '@exercism/eslint-config-typescript',
},
// Exercism provided files
{
files: ['.meta/proof.ci.ts', '.meta/exemplar.ts', '*.test.ts'],
excludedFiles: ['custom.test.ts'],
extends: '@exercism/eslint-config-typescript/maintainers',
rules: {
"@typescript-eslint/semi": 0,
},
},
],
}

View File

@@ -0,0 +1,12 @@
{
"blurb": "Implement a clock that handles times without dates.",
"authors": ["rwaskiewicz"],
"contributors": ["masters3d", "SleeplessByte"],
"files": {
"solution": ["clock.ts"],
"test": ["clock.test.ts"],
"example": [".meta/proof.ci.ts"]
},
"source": "Pairing session with Erin Drummond",
"source_url": "https://twitter.com/ebdrummond"
}

View File

@@ -0,0 +1 @@
{"track":"typescript","exercise":"clock","id":"632b2e852a304431b860ddb11884edf0","url":"https://exercism.org/tracks/typescript/exercises/clock","handle":"briemens","is_requester":true,"auto_approve":false}

44
typescript/clock/HELP.md Normal file
View File

@@ -0,0 +1,44 @@
# Help
## Running the tests
Execute the tests with:
```bash
$ yarn test
```
## Skipped tests
In the test suites all tests but the first have been skipped.
Once you get a test passing, you can enable the next one by changing `xit` to
`it`.
## Submitting your solution
You can submit your solution using the `exercism submit clock.ts` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [TypeScript track's documentation](https://exercism.org/docs/tracks/typescript)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [TypeScript QuickStart](https://www.typescriptlang.org/docs/handbook/release-notes/overview.html)
- [ECMAScript 2015 Language Specification](https://www.ecma-international.org/wp-content/uploads/ECMA-262_6th_edition_june_2015.pdf) (pdf)
- [Mozilla JavaScript Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference)
- [/r/typescript](https://www.reddit.com/r/typescript) is the TypeScript subreddit.
- [StackOverflow](https://stackoverflow.com/questions/tagged/typescript) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

View File

@@ -0,0 +1,27 @@
# Clock
Welcome to Clock on Exercism's TypeScript Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Implement a clock that handles times without dates.
You should be able to add and subtract minutes to it.
Two clocks that represent the same time should be equal to each other.
## Source
### Created by
- @rwaskiewicz
### Contributed to by
- @masters3d
- @SleeplessByte
### Based on
Pairing session with Erin Drummond - https://twitter.com/ebdrummond

View File

@@ -0,0 +1,4 @@
module.exports = {
presets: ['@exercism/babel-preset-typescript'],
plugins: [],
}

View File

@@ -0,0 +1,209 @@
import { Clock } from "./clock";
describe("Clock", () => {
describe("Creating a new clock with an initial time", () => {
it("on the hour", () => {
expect(new Clock(8).toString()).toEqual("08:00");
});
it("past the hour", () => {
expect(new Clock(11, 9).toString()).toEqual("11:09");
});
it("midnight is zero hours", () => {
expect(new Clock(24, 0).toString()).toEqual("00:00");
});
it("hour rolls over", () => {
expect(new Clock(25, 0).toString()).toEqual("01:00");
});
it("hour rolls over continuously", () => {
expect(new Clock(100, 0).toString()).toEqual("04:00");
});
it("sixty minutes is next hour", () => {
expect(new Clock(1, 60).toString()).toEqual("02:00");
});
it("minutes roll over", () => {
expect(new Clock(0, 160).toString()).toEqual("02:40");
});
it("minutes roll over continuously", () => {
expect(new Clock(0, 1723).toString()).toEqual("04:43");
});
it("hour and minutes roll over", () => {
expect(new Clock(25, 160).toString()).toEqual("03:40");
});
it("hour and minutes roll over continuously", () => {
expect(new Clock(201, 3001).toString()).toEqual("11:01");
});
it("hour and minutes roll over to exactly midnight", () => {
expect(new Clock(72, 8640).toString()).toEqual("00:00");
});
it("negative hour", () => {
expect(new Clock(-1, 15).toString()).toEqual("23:15");
});
it("negative hour rolls over", () => {
expect(new Clock(-25, 0).toString()).toEqual("23:00");
});
it("negative hour rolls over continuously", () => {
expect(new Clock(-91, 0).toString()).toEqual("05:00");
});
it("negative minutes", () => {
expect(new Clock(1, -40).toString()).toEqual("00:20");
});
it("negative minutes rolls over", () => {
expect(new Clock(1, -160).toString()).toEqual("22:20");
});
it("negative minutes rolls over continuously", () => {
expect(new Clock(1, -4820).toString()).toEqual("16:40");
});
it("negative hour and minutes both roll over", () => {
expect(new Clock(-25, -160).toString()).toEqual("20:20");
});
it("negative hour and minutes both roll over continuously", () => {
expect(new Clock(-121, -5810).toString()).toEqual("22:10");
});
describe("Adding and subtracting minutes", () => {
it("add minutes", () => {
expect(new Clock(10, 0).plus(3).toString()).toEqual("10:03");
});
it("add no minutes", () => {
expect(new Clock(6, 41).plus(0).toString()).toEqual("06:41");
});
it("add to next hour", () => {
expect(new Clock(0, 45).plus(40).toString()).toEqual("01:25");
});
it("add more than one hour", () => {
expect(new Clock(10, 0).plus(61).toString()).toEqual("11:01");
});
it("add more than two hours with carry", () => {
expect(new Clock(0, 45).plus(160).toString()).toEqual("03:25");
});
it("add across midnight", () => {
expect(new Clock(23, 59).plus(2).toString()).toEqual("00:01");
});
it("add more than one day (1500 min = 25 hrs)", () => {
expect(new Clock(5, 32).plus(1500).toString()).toEqual("06:32");
});
it("add more than two days", () => {
expect(new Clock(1, 1).plus(3500).toString()).toEqual("11:21");
});
it("subtract minutes", () => {
expect(new Clock(10, 3).minus(3).toString()).toEqual("10:00");
});
it("subtract to previous hour", () => {
expect(new Clock(10, 3).minus(30).toString()).toEqual("09:33");
});
it("subtract more than an hour", () => {
expect(new Clock(10, 3).minus(70).toString()).toEqual("08:53");
});
it("subtract across midnight", () => {
expect(new Clock(0, 3).minus(4).toString()).toEqual("23:59");
});
it("subtract more than two hours", () => {
expect(new Clock(0, 0).minus(160).toString()).toEqual("21:20");
});
it("subtract more than two hours with borrow", () => {
expect(new Clock(6, 15).minus(160).toString()).toEqual("03:35");
});
it("subtract more than one day (1500 min = 25 hrs)", () => {
expect(new Clock(5, 32).minus(1500).toString()).toEqual("04:32");
});
it("subtract more than two days", () => {
expect(new Clock(2, 20).minus(3000).toString()).toEqual("00:20");
});
});
describe("Construct two separate clocks, set times, test if they are equal", () => {
it("clocks with same time", () => {
expect(new Clock(15, 37).equals(new Clock(15, 37))).toBeTruthy();
});
it("clocks a minute apart", () => {
expect(new Clock(15, 36).equals(new Clock(15, 37))).toBeFalsy();
});
it("clocks an hour apart", () => {
expect(new Clock(14, 37).equals(new Clock(15, 37))).toBeFalsy();
});
it("clocks with hour overflow", () => {
expect(new Clock(10, 37).equals(new Clock(34, 37))).toBeTruthy();
});
it("clocks with hour overflow by several days", () => {
expect(new Clock(3, 11).equals(new Clock(99, 11))).toBeTruthy();
});
it("clocks with negative hour", () => {
expect(new Clock(22, 40).equals(new Clock(-2, 40))).toBeTruthy();
});
it("clocks with negative hour that wraps", () => {
expect(new Clock(17, 3).equals(new Clock(-31, 3))).toBeTruthy();
});
it("clocks with negative hour that wraps multiple times", () => {
expect(new Clock(13, 49).equals(new Clock(-83, 49))).toBeTruthy();
});
it("clocks with minute overflow", () => {
expect(new Clock(0, 1).equals(new Clock(0, 1441))).toBeTruthy();
});
it("clocks with minute overflow by several days", () => {
expect(new Clock(2, 2).equals(new Clock(2, 4322))).toBeTruthy();
});
it("clocks with negative minute", () => {
expect(new Clock(2, 40).equals(new Clock(3, -20))).toBeTruthy();
});
it("clocks with negative minute that wraps", () => {
expect(new Clock(4, 10).equals(new Clock(5, -1490))).toBeTruthy();
});
it("clocks with negative minute that wraps multiple times", () => {
expect(new Clock(6, 15).equals(new Clock(6, -4305))).toBeTruthy();
});
it("clocks with negative hours and minutes", () => {
expect(new Clock(7, 32).equals(new Clock(-12, -268))).toBeTruthy();
});
it("clocks with negative hours and minutes that wrap", () => {
expect(new Clock(18, 7).equals(new Clock(-54, -11513))).toBeTruthy();
});
});
});
});

38
typescript/clock/clock.ts Normal file
View File

@@ -0,0 +1,38 @@
export class Clock {
private _hour = 0;
private _minute = 0;
private setTime(hour: number, minute: number = 0): void {
this._minute = minute % 60;
if (this._minute < 0) {
this._minute = 60 + this._minute;
}
this._hour = (hour + Math.floor(minute / 60)) % 24;
if (this._hour < 0) {
this._hour = (this._hour % 24) + 24;
}
}
constructor(hour: number, minute?: number) {
this.setTime(hour, minute);
}
public toString(): string {
return `${String(this._hour).padStart(2, "0")}:${String(
this._minute
).padStart(2, "0")}`;
}
public plus(minutes: number): Clock {
return new Clock(this._hour, this._minute + minutes);
}
public minus(minutes: number): Clock {
return new Clock(this._hour, this._minute - minutes);
}
public equals(other: Clock): boolean {
return this.toString() === other.toString();
}
}

View File

@@ -0,0 +1,19 @@
module.exports = {
verbose: true,
projects: ['<rootDir>'],
testMatch: [
'**/__tests__/**/*.[jt]s?(x)',
'**/test/**/*.[jt]s?(x)',
'**/?(*.)+(spec|test).[jt]s?(x)',
],
testPathIgnorePatterns: [
'/(?:production_)?node_modules/',
'.d.ts$',
'<rootDir>/test/fixtures',
'<rootDir>/test/helpers',
'__mocks__',
],
transform: {
'^.+\\.[jt]sx?$': 'babel-jest',
},
}

15996
typescript/clock/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
{
"name": "@exercism/typescript-clock",
"version": "1.0.0",
"description": "Exercism exercises in Typescript.",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/exercism/typescript"
},
"type": "module",
"engines": {
"node": "^14.13.1 || >=16.0.0"
},
"devDependencies": {
"@exercism/babel-preset-typescript": "^0.1.0",
"@exercism/eslint-config-typescript": "^0.4.1",
"@types/jest": "^27.4.0",
"@types/node": "^16.11.24",
"babel-jest": "^27.5.1",
"core-js": "^3.21.0",
"eslint": "^8.9.0",
"jest": "^27.5.1",
"typescript": "^4.5.4"
},
"scripts": {
"test": "yarn lint:types && jest --no-cache",
"lint": "yarn lint:types && yarn lint:ci",
"lint:types": "yarn tsc --noEmit -p .",
"lint:ci": "eslint . --ext .tsx,.ts"
}
}

View File

@@ -0,0 +1,28 @@
{
"display": "Configuration for Exercism TypeScript Exercises",
"compilerOptions": {
// Allows you to use the newest syntax, and have access to console.log
// https://www.typescriptlang.org/tsconfig#lib
"lib": ["ESNEXT", "dom"],
// Make sure typescript is configured to output ESM
// https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#how-can-i-make-my-typescript-project-output-esm
"module": "ES2020",
// Since this project is using babel, TypeScript may target something very
// high, and babel will make sure it runs on your local Node version.
// https://babeljs.io/docs/en/
"target": "ESNext", // ESLint doesn't support this yet: "es2022",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
// Because we'll be using babel: ensure that Babel can safely transpile
// files in the TypeScript project.
//
// https://babeljs.io/docs/en/babel-plugin-transform-typescript/#caveats
"isolatedModules": true
},
"include": ["*.ts", "*.tsx", ".meta/*.ts", ".meta/*.tsx"],
"exclude": ["node_modules"]
}