-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsimple-cipher.spec.js
123 lines (100 loc) · 3.4 KB
/
simple-cipher.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* eslint-disable no-new */
import { Cipher } from './simple-cipher';
describe('Random key generation', () => {
test('generates keys at random', () => {
// Strictly speaking, this is difficult to test with 100% certainty.
// But, if you have a generator that generates 100-character-long
// strings of lowercase letters at random, the odds of two consecutively
// generated keys being identical are astronomically low.
expect(new Cipher().key).not.toEqual(new Cipher().key);
});
});
describe('Random key cipher', () => {
const cipher = new Cipher();
test('has a key made of letters', () => {
expect(cipher.key).toMatch(/^[a-z]+$/);
});
test('has a key that is at least 100 characters long', () => {
expect(cipher.key.length).toBeGreaterThanOrEqual(100);
});
// Here we take advantage of the fact that plaintext of "aaa..."
// outputs the key. This is a critical problem with shift ciphers, some
// characters will always output the key verbatim.
test('can encode', () => {
expect(cipher.encode('aaaaaaaaaa')).toEqual(cipher.key.substr(0, 10));
});
test('can decode', () => {
expect(cipher.decode(cipher.key.substr(0, 10))).toEqual('aaaaaaaaaa');
});
test('is reversible', () => {
const plaintext = 'abcdefghij';
expect(cipher.decode(cipher.encode(plaintext))).toEqual(plaintext);
});
});
describe('Incorrect key cipher', () => {
test('throws an error with an all caps key', () => {
expect(() => {
new Cipher('ABCDEF');
}).toThrow(new Error('Bad key'));
});
test('throws an error with a mixed-case key', () => {
expect(() => {
new Cipher('ABcdEF');
}).toThrow(new Error('Bad key'));
});
test('throws an error with a numeric key', () => {
expect(() => {
new Cipher('12345');
}).toThrow(new Error('Bad key'));
});
test('throws an error with an empty key', () => {
expect(() => {
new Cipher('');
}).toThrow(new Error('Bad key'));
});
test('throws an error with a leading space', () => {
expect(() => {
new Cipher(' leadingspace');
}).toThrow(new Error('Bad key'));
});
test('throws an error with a punctuation mark', () => {
expect(() => {
new Cipher('hyphened-word');
}).toThrow(new Error('Bad key'));
});
test('throws an error with a single capital letter', () => {
expect(() => {
new Cipher('leonardoDavinci');
}).toThrow(new Error('Bad key'));
});
});
describe('Substitution cipher', () => {
const key = 'abcdefghij';
const cipher = new Cipher(key);
test('keeps the submitted key', () => {
expect(cipher.key).toEqual(key);
});
test('can encode', () => {
expect(cipher.encode('aaaaaaaaaa')).toEqual('abcdefghij');
});
test('can decode', () => {
expect(cipher.decode('abcdefghij')).toEqual('aaaaaaaaaa');
});
test('is reversible', () => {
expect(cipher.decode(cipher.encode('abcdefghij'))).toEqual('abcdefghij');
});
test(': double shift encode', () => {
expect(new Cipher('iamapandabear').encode('iamapandabear'))
.toEqual('qayaeaagaciai');
});
test('can wrap on encode', () => {
expect(cipher.encode('zzzzzzzzzz')).toEqual('zabcdefghi');
});
test('can wrap on decode', () => {
expect(cipher.decode('zabcdefghi')).toEqual('zzzzzzzzzz');
});
test('can handle messages longer than the key', () => {
expect(new Cipher('abc').encode('iamapandabear'))
.toEqual('iboaqcnecbfcr');
});
});