Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
5,553 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
bin/* | ||
dist/* | ||
docs/* | ||
node_modules/* | ||
production_node_modules/* | ||
test/fixtures/* | ||
tmp/* | ||
|
||
babel.config.js | ||
jest.config.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
{ | ||
"root": true, | ||
"parser": "@typescript-eslint/parser", | ||
"parserOptions": { | ||
"project": "./tsconfig.json", | ||
"ecmaFeatures": { | ||
"jsx": true | ||
}, | ||
"ecmaVersion": 2018, | ||
"sourceType": "module" | ||
}, | ||
"env": { | ||
"browser": true, | ||
"es6": true | ||
}, | ||
"extends": [ | ||
"eslint:recommended", | ||
"plugin:@typescript-eslint/eslint-recommended", | ||
"plugin:@typescript-eslint/recommended" | ||
], | ||
"globals": { | ||
"Atomics": "readonly", | ||
"SharedArrayBuffer": "readonly" | ||
}, | ||
"plugins": [ | ||
"@typescript-eslint" | ||
], | ||
"rules": { | ||
// Code style not forced upon the student | ||
"@typescript-eslint/array-type": "off", | ||
|
||
// Prevent bugs | ||
"@typescript-eslint/explicit-function-return-type": [ | ||
"warn", { | ||
"allowExpressions": false, | ||
"allowTypedFunctionExpressions": true, | ||
"allowHigherOrderFunctions": true | ||
} | ||
], | ||
|
||
// Code style not forced upon the student | ||
"@typescript-eslint/explicit-member-accessibility": "off", | ||
|
||
// Code style not forced upon the student | ||
"@typescript-eslint/indent": "off", | ||
|
||
"@typescript-eslint/no-inferrable-types": [ | ||
"error", { | ||
"ignoreParameters": true | ||
} | ||
], | ||
|
||
// Code style not forced upon the student | ||
"@typescript-eslint/member-delimiter-style": "off", | ||
|
||
// Code style not forced upon the student | ||
"@typescript-eslint/no-non-null-assertion": "off", | ||
|
||
// Only disallow readonly without an access modifier | ||
"@typescript-eslint/no-parameter-properties": [ | ||
"warn", { | ||
"allows": [ | ||
"private", "protected", "public", | ||
"private readonly", "protected readonly", "public readonly" | ||
] | ||
} | ||
], | ||
|
||
// Covered by the tsc compiler (noUnusedLocals) | ||
"@typescript-eslint/no-unused-vars": "off", | ||
|
||
// Prevent bugs, not styling | ||
"@typescript-eslint/no-use-before-define": [ | ||
"error", { | ||
"functions": false, | ||
"typedefs": false | ||
} | ||
], | ||
|
||
// Always disable base-rule | ||
"semi": "off", | ||
|
||
// Code style not forced upon student | ||
"@typescript-eslint/semi": "off" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Robot Name | ||
|
||
Manage robot factory settings. | ||
|
||
When robots come off the factory floor, they have no name. | ||
|
||
The first time you boot them up, a random name is generated in the format | ||
of two uppercase letters followed by three digits, such as RX837 or BC811. | ||
|
||
Every once in a while we need to reset a robot to its factory settings, | ||
which means that their name gets wiped. The next time you ask, it will | ||
respond with a new random name. | ||
|
||
The names must be random: they should not follow a predictable sequence. | ||
Random names means a risk of collisions. Your solution must ensure that | ||
every existing robot has a unique name. | ||
|
||
## Setup | ||
|
||
Go through the setup instructions for TypeScript to install the necessary | ||
dependencies: | ||
|
||
[https://exercism.io/tracks/typescript/installation](https://exercism.io/tracks/typescript/installation) | ||
|
||
## Requirements | ||
|
||
Install assignment dependencies: | ||
|
||
```bash | ||
$ yarn install | ||
``` | ||
|
||
## Making the test suite pass | ||
|
||
Execute the tests with: | ||
|
||
```bash | ||
$ yarn test | ||
``` | ||
|
||
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`. | ||
|
||
## Source | ||
|
||
A debugging session with Paul Blackwell at gSchool. | ||
|
||
## Submitting Incomplete Solutions | ||
|
||
It's possible to submit an incomplete solution so you can see how others have | ||
completed the exercise. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module.exports = { | ||
presets: [ | ||
[ | ||
'@babel/preset-env', | ||
{ | ||
targets: { | ||
node: 'current', | ||
}, | ||
useBuiltIns: 'entry', | ||
corejs: 3, | ||
}, | ||
], | ||
'@babel/preset-typescript', | ||
], | ||
plugins: [ | ||
'@babel/proposal-class-properties', | ||
'@babel/proposal-object-rest-spread', | ||
'@babel/plugin-syntax-bigint', | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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', | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "@exercism/typescript", | ||
"description": "Exercism exercises in Typescript.", | ||
"private": true, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/exercism/typescript" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.12.10", | ||
"@babel/plugin-proposal-class-properties": "^7.12.1", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.12.1", | ||
"@babel/plugin-syntax-bigint": "^7.8.3", | ||
"@babel/preset-env": "^7.12.11", | ||
"@babel/preset-typescript": "^7.12.7", | ||
"@types/jest": "^26.0.19", | ||
"@types/node": "^14.14.14", | ||
"@typescript-eslint/eslint-plugin": "^4.11.0", | ||
"@typescript-eslint/parser": "^4.11.0", | ||
"babel-jest": "^26.6.3", | ||
"core-js": "^3.8.1", | ||
"eslint": "^7.16.0", | ||
"eslint-plugin-import": "^2.22.1", | ||
"jest": "^26.6.3", | ||
"typescript": "^4.1.3" | ||
}, | ||
"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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import Robot from './robot-name' | ||
|
||
const areSequential = (name1: string, name2: string): boolean => { | ||
const alpha1 = name1.substr(0, 2) | ||
const alpha2 = name2.substr(0, 2) | ||
const num1 = +name1.substr(2, 3) | ||
const num2 = +name2.substr(2, 3) | ||
|
||
const numDiff = num2 - num1 | ||
const alphaDiff = | ||
(alpha2.charCodeAt(0) - alpha1.charCodeAt(0)) * 26 + | ||
(alpha2.charCodeAt(1) - alpha1.charCodeAt(1)) | ||
|
||
const totalDiff = alphaDiff * 1000 + numDiff | ||
|
||
return Math.abs(totalDiff) <= 1 | ||
} | ||
|
||
const NAME_RE = /^[A-Z]{2}\d{3}$/ | ||
const TOTAL_NUMBER_OF_NAMES = | ||
26 * // A-Z | ||
26 * // A-Z | ||
10 * // 0-9 | ||
10 * // 0-9 | ||
10 // 0-9 | ||
|
||
describe('Robot', () => { | ||
let robot: Robot | ||
|
||
beforeEach(() => { | ||
robot = new Robot() | ||
}) | ||
|
||
afterEach(() => { | ||
Robot.releaseNames() | ||
}) | ||
|
||
it('has a name', () => { | ||
expect(robot.name).toMatch(NAME_RE) | ||
}) | ||
|
||
xit('name is the same each time', () => { | ||
expect(robot.name).toEqual(robot.name) | ||
}) | ||
|
||
xit('different robots have different names', () => { | ||
const differentRobot = new Robot() | ||
expect(differentRobot.name).not.toEqual(robot.name) | ||
}) | ||
|
||
xit('is able to reset the name', () => { | ||
const originalName = robot.name | ||
|
||
robot.resetName() | ||
const newName = robot.name | ||
|
||
expect(newName).toMatch(NAME_RE) | ||
expect(originalName).not.toEqual(newName) | ||
}) | ||
|
||
xit('should set a unique name after reset', () => { | ||
const NUMBER_OF_ROBOTS = 10000 | ||
const usedNames = new Set() | ||
|
||
usedNames.add(robot.name) | ||
for (let i = 0; i < NUMBER_OF_ROBOTS; i++) { | ||
robot.resetName() | ||
usedNames.add(robot.name) | ||
} | ||
|
||
expect(usedNames.size).toEqual(NUMBER_OF_ROBOTS + 1) | ||
}) | ||
|
||
xit('new names should not be sequential', () => { | ||
const name1 = robot.name | ||
const name2 = new Robot().name | ||
const name3 = new Robot().name | ||
expect(areSequential(name1, name1)).toBe(true) | ||
expect(areSequential(name1, name2)).toBe(false) | ||
expect(areSequential(name2, name3)).toBe(false) | ||
}) | ||
|
||
xit('names from reset should not be sequential', () => { | ||
const name1 = robot.name | ||
robot.resetName() | ||
const name2 = robot.name | ||
robot.resetName() | ||
const name3 = robot.name | ||
expect(areSequential(name1, name2)).toBe(false) | ||
expect(areSequential(name2, name3)).toBe(false) | ||
expect(areSequential(name3, name3)).toBe(true) | ||
}) | ||
|
||
// This test is optional. | ||
xit('all the names can be generated', () => { | ||
const usedNames = new Set() | ||
usedNames.add(robot.name) | ||
|
||
for (let i = 0; i < TOTAL_NUMBER_OF_NAMES - 1; i += 1) { | ||
const newRobot = new Robot() | ||
usedNames.add(newRobot.name) | ||
} | ||
|
||
expect(usedNames.size).toEqual(TOTAL_NUMBER_OF_NAMES) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
export default class Robot { | ||
constructor() {} | ||
|
||
public get name(): string { | ||
throw new Error('Implement Robot#name') | ||
} | ||
|
||
public resetName(): void { | ||
throw new Error('Implement Robot#resetName') | ||
} | ||
|
||
public static releaseNames(): void { | ||
throw new Error('Implement Robot.releaseNames') | ||
} | ||
} |
Oops, something went wrong.