1 module tanya.tests.conv;
2 
3 import tanya.conv;
4 import tanya.range;
5 import tanya.test.assertion;
6 import tanya.test.stub;
7 
8 // ':' is not a hex value
9 @nogc nothrow pure @safe unittest
10 {
11     string colon = ":";
12     auto actual = readIntegral!ubyte(colon, 16);
13     assert(actual == 0);
14     assert(colon.length == 1);
15 }
16 
17 // reads ubyte.max
18 @nogc nothrow pure @safe unittest
19 {
20     string number = "255";
21     assert(readIntegral!ubyte(number) == 255);
22     assert(number.empty);
23 }
24 
25 // detects integer overflow
26 @nogc nothrow pure @safe unittest
27 {
28     string number = "500";
29     readIntegral!ubyte(number);
30     assert(number.front == '0');
31     assert(number.length == 1);
32 }
33 
34 // stops on a non-digit
35 @nogc nothrow pure @safe unittest
36 {
37     string number = "10-";
38     readIntegral!ubyte(number);
39     assert(number.front == '-');
40 }
41 
42 // returns false if the number string is empty
43 @nogc nothrow pure @safe unittest
44 {
45     string number = "";
46     readIntegral!ubyte(number);
47     assert(number.empty);
48 }
49 
50 @nogc nothrow pure @safe unittest
51 {
52     string number = "29";
53     assert(readIntegral!ubyte(number) == 29);
54     assert(number.empty);
55 }
56 
57 @nogc nothrow pure @safe unittest
58 {
59     string number = "25467";
60     readIntegral!ubyte(number);
61     assert(number.front == '6');
62 }
63 
64 // Converts lower case hexadecimals
65 @nogc nothrow pure @safe unittest
66 {
67     string number = "a";
68     assert(readIntegral!ubyte(number, 16) == 10);
69     assert(number.empty);
70 }
71 
72 // Converts upper case hexadecimals
73 @nogc nothrow pure @safe unittest
74 {
75     string number = "FF";
76     assert(readIntegral!ubyte(number, 16) == 255);
77     assert(number.empty);
78 }
79 
80 // Handles small overflows
81 @nogc nothrow pure @safe unittest
82 {
83     string number = "256";
84     assert(readIntegral!ubyte(number, 10) == 25);
85     assert(number.front == '6');
86 }
87 
88 @nogc nothrow pure @safe unittest
89 {
90     int val = 5;
91     assert(val.to!int() == 5);
92 }
93 
94 @nogc nothrow pure @safe unittest
95 {
96     // ubyte -> ushort
97     assert((cast(ubyte) 0).to!ushort == 0);
98     assert((cast(ubyte) 1).to!ushort == 1);
99     assert((cast(ubyte) (ubyte.max - 1)).to!ushort == ubyte.max - 1);
100     assert((cast(ubyte) ubyte.max).to!ushort == ubyte.max);
101 
102     // ubyte -> short
103     assert((cast(ubyte) 0).to!short == 0);
104     assert((cast(ubyte) 1).to!short == 1);
105     assert((cast(ubyte) (ubyte.max - 1)).to!short == ubyte.max - 1);
106     assert((cast(ubyte) ubyte.max).to!short == ubyte.max);
107 }
108 
109 @nogc pure @safe unittest
110 {
111     // ubyte <- ushort
112     assert((cast(ushort) 0).to!ubyte == 0);
113     assert((cast(ushort) 1).to!ubyte == 1);
114     assert((cast(ushort) (ubyte.max - 1)).to!ubyte == ubyte.max - 1);
115     assert((cast(ushort) ubyte.max).to!ubyte == ubyte.max);
116 
117     // ubyte <- short
118     assert((cast(short) 0).to!ubyte == 0);
119     assert((cast(short) 1).to!ubyte == 1);
120     assert((cast(short) (ubyte.max - 1)).to!ubyte == ubyte.max - 1);
121     assert((cast(short) ubyte.max).to!ubyte == ubyte.max);
122 
123     // short <-> int
124     assert(short.min.to!int == short.min);
125     assert((short.min + 1).to!int == short.min + 1);
126     assert((cast(short) -1).to!int == -1);
127     assert((cast(short) 0).to!int == 0);
128     assert((cast(short) 1).to!int == 1);
129     assert((short.max - 1).to!int == short.max - 1);
130     assert(short.max.to!int == short.max);
131 
132     assert((cast(int) short.min).to!short == short.min);
133     assert((cast(int) short.min + 1).to!short == short.min + 1);
134     assert((cast(int) -1).to!short == -1);
135     assert((cast(int) 0).to!short == 0);
136     assert((cast(int) 1).to!short == 1);
137     assert((cast(int) short.max - 1).to!short == short.max - 1);
138     assert((cast(int) short.max).to!short == short.max);
139 
140     // uint <-> int
141     assert((cast(uint) 0).to!int == 0);
142     assert((cast(uint) 1).to!int == 1);
143     assert((cast(uint) (int.max - 1)).to!int == int.max - 1);
144     assert((cast(uint) int.max).to!int == int.max);
145 
146     assert((cast(int) 0).to!uint == 0);
147     assert((cast(int) 1).to!uint == 1);
148     assert((cast(int) (int.max - 1)).to!uint == int.max - 1);
149     assert((cast(int) int.max).to!uint == int.max);
150 }
151 
152 @nogc pure @safe unittest
153 {
154     assertThrown!ConvException(&to!(short, int), int.min);
155     assertThrown!ConvException(&to!(short, int), int.max);
156     assertThrown!ConvException(&to!(ushort, uint), uint.max);
157     assertThrown!ConvException(&to!(uint, int), -1);
158 }
159 
160 @nogc nothrow pure @safe unittest
161 {
162     enum Test : int
163     {
164         one,
165         two,
166     }
167     assert(Test.one.to!int == 0);
168     assert(Test.two.to!int == 1);
169 }
170 
171 @nogc pure @safe unittest
172 {
173     assertThrown!ConvException(&to!(int, double), 2147483647.5);
174     assertThrown!ConvException(&to!(int, double), -2147483648.5);
175     assertThrown!ConvException(&to!(uint, double), -21474.5);
176 }
177 
178 @nogc pure @safe unittest
179 {
180     enum Test : uint
181     {
182         one,
183         two,
184     }
185     assertThrown!ConvException(&to!(Test, int), 5);
186 }
187 
188 @nogc pure @safe unittest
189 {
190     assertThrown!ConvException(&to!(bool, int), -1);
191     assertThrown!ConvException(&to!(bool, int), 2);
192 }
193 
194 @nogc pure @safe unittest
195 {
196     assertThrown!ConvException(() => "1".to!bool);
197 }
198 
199 @nogc pure @safe unittest
200 {
201     assertThrown!ConvException(() => "".to!int);
202     assertThrown!ConvException(() => "-".to!int);
203     assertThrown!ConvException(() => "-5".to!uint);
204     assertThrown!ConvException(() => "-129".to!byte);
205     assertThrown!ConvException(() => "256".to!ubyte);
206 }