comparison enigma/tests/test_rotor.t.h @ 2:713fa2a9ea9a

CxxTest support. Added rotor tests.
author Brian Neal <bgneal@gmail.com>
date Fri, 22 Jun 2012 22:02:55 -0500
parents
children f4e25e6b76c3
comparison
equal deleted inserted replaced
1:1459e74fda3f 2:713fa2a9ea9a
1 // Copyright (C) 2012 by Brian Neal.
2 // This file is part of Cpp-Enigma, the Enigma Machine simulation.
3 // Cpp-Enigma is released under the MIT License (see License.txt).
4 //
5 // test_rotor.t.h - rotor unit tests
6
7 #include <deque>
8 #include <string>
9 #include <memory>
10 #include <cxxtest/TestSuite.h>
11 #include "rotor.h"
12 #include "enigma_utils.h"
13 #include "rotor_data.h"
14 #include "rotor_factory.h"
15
16 using namespace enigma;
17
18 const char* const wiring = "EKMFLGDQVZNTOWYHXUSPAIBRCJ";
19
20
21 class MyTestSuite1 : public CxxTest::TestSuite
22 {
23 public:
24
25 void test_bad_wiring()
26 {
27 TS_ASSERT_THROWS(rotor("I", ""), rotor_error);
28 TS_ASSERT_THROWS(rotor("I", "ABC"), rotor_error);
29 TS_ASSERT_THROWS(rotor("I", "123"), rotor_error);
30 TS_ASSERT_THROWS(rotor("I", "!\"#$%&'()*+,-./:;<=>?@[\\]^"), rotor_error);
31 TS_ASSERT_THROWS(rotor("I", "ABCDABCDABCDABCDABCDABCDAB"), rotor_error);
32 }
33
34 void test_bad_ring_setting()
35 {
36 TS_ASSERT_THROWS(rotor("I", wiring, -1), rotor_error);
37 TS_ASSERT_THROWS(rotor("I", wiring, 26), rotor_error);
38 }
39
40 void test_bad_stepping()
41 {
42 TS_ASSERT_THROWS(rotor("I", wiring, 1, "0"), rotor_error);
43 TS_ASSERT_THROWS(rotor("I", wiring, 1, "-"), rotor_error);
44 TS_ASSERT_THROWS(rotor("I", wiring, 1, "A%"), rotor_error);
45 TS_ASSERT_THROWS(rotor("I", wiring, 1, "A%14"), rotor_error);
46 }
47
48 void test_display()
49 {
50 for (int i = 0; i < 26; ++i)
51 {
52 rotor r{"I", wiring, i};
53 for (int j = 0; j < 26; ++j)
54 {
55 r.set_display(j + 'A');
56 TS_ASSERT_EQUALS(j + 'A', r.get_display());
57 }
58 }
59 }
60
61 // Loop through all ring settings & rotor positions and test the wiring.
62 void test_wiring()
63 {
64 for (int r = 0; r < 26; ++r)
65 {
66 rotor test_rotor("I", wiring, r);
67
68 for (int n = 0; n < 26; ++n)
69 {
70 const char d = n + 'A';
71 test_rotor.set_display(d);
72
73 std::deque<char> wiring_deque(wiring, wiring + 26);
74 // rotate contents to the right if positive, left if negative:
75 int rotate_count = r - n;
76 const bool rotate_right = rotate_count >= 0;
77 if (rotate_count < 0)
78 {
79 rotate_count = -rotate_count;
80 }
81 for (int x = 0; x < rotate_count; ++x)
82 {
83 if (rotate_right)
84 {
85 wiring_deque.push_front(wiring_deque.back());
86 wiring_deque.pop_back();
87 }
88 else
89 {
90 wiring_deque.push_back(wiring_deque.front());
91 wiring_deque.pop_front();
92 }
93 }
94
95 for (int i = 0; i < 26; ++i)
96 {
97 int output = test_rotor.signal_in(i);
98 int expected = alpha_mod(wiring_deque[i] - 'A' + r - n);
99 TS_ASSERT_EQUALS(output, expected);
100
101 output = test_rotor.signal_out(expected);
102 TS_ASSERT_EQUALS(output, i);
103 }
104 }
105 }
106 }
107
108 // For every rotor we simulate, ensure that the notch setting is correct
109 // regardless of the ring setting.
110 void test_notches()
111 {
112 for (const auto& p : simulated_rotors)
113 {
114 const std::string& rotor_name(p.first);
115 const rotor_data& rd(p.second);
116 if (rd.stepping == nullptr)
117 {
118 continue;
119 }
120 const std::string notches(rd.stepping);
121
122 for (int r = 0; r < 26; ++r)
123 {
124 std::unique_ptr<rotor> rp = create_rotor(rotor_name.c_str(), r);
125 rp->set_display('A');
126
127 for (int n = 0; n < 26; ++n)
128 {
129 const bool over_notch = notches.find(rp->get_display()) != std::string::npos;
130 TS_ASSERT_EQUALS(over_notch, rp->notch_over_pawl());
131 }
132 }
133 }
134 }
135
136 void test_rotate()
137 {
138 for (int r = 0; r < 26; ++r)
139 {
140 rotor r1("X", wiring, r);
141 rotor r2("Y", wiring, r);
142
143 r2.set_display('A');
144 for (int i = 0; i < 26; ++i)
145 {
146 r1.set_display(i + 'A');
147 TS_ASSERT_EQUALS(r1.get_display(), r2.get_display());
148 r2.rotate();
149 }
150 }
151 }
152
153 void test_ring_setting()
154 {
155 rotor r("X", wiring, 0);
156 for (int n = 0; n < 26; ++n)
157 {
158 r.set_ring_setting(n);
159 TS_ASSERT_EQUALS(n, r.get_ring_setting());
160
161 r.set_display('A');
162 for (int a = 0; a < 26; ++a)
163 {
164 TS_ASSERT_EQUALS(a + 'A', r.get_display());
165 r.rotate();
166 }
167 }
168 }
169 };