1
exercism fetch ecmascript robot-name

robot-name.spec.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import Robot from './robot-name';

describe('Robot', () => {
  let robot;

  beforeEach(() => {
    robot = new Robot();
  });

  test('has a name', () => {
    expect(robot.name).toMatch(/^[A-Z]{2}\d{3}$/);
  });

  xtest('name is the same each time', () => {
    expect(robot.name).toEqual(robot.name);
  });

  xtest('different robots have different names', () => {
    const differentRobot = new Robot();
    expect(differentRobot.name).not.toEqual(robot.name);
  });

  xtest('is able to reset the name', () => {
    const originalName = robot.name;

    robot.reset();
    const newName = robot.name;

    expect(newName).toMatch(/^[A-Z]{2}\d{3}$/);
    expect(originalName).not.toEqual(newName);
  });

  xtest('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.reset();
      usedNames.add(robot.name);
    }

    expect(usedNames.size).toEqual(NUMBER_OF_ROBOTS + 1);
  });

  xtest('internal name cannot be modified', () => {
    const modifyInternal = () => robot.name += 'a modification';
    expect(modifyInternal).toThrow();
  });


  xtest('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);
  });

  xtest('names from reset should not be sequential', () => {
    const name1 = robot.name;
    robot.reset();
    const name2 = robot.name;
    robot.reset();
    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.
  xtest('there can be lots of robots with different names each', () => {
    const NUMBER_OF_ROBOTS = 10000;
    const usedNames = new Set();

    for (let i = 0; i < NUMBER_OF_ROBOTS; i++) {
      const newRobot = new Robot();
      usedNames.add(newRobot.name);
    }

    expect(usedNames.size).toEqual(NUMBER_OF_ROBOTS);
  });
});

const areSequential = (name1, name2) => {
  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;
};