1// Copyright 2012 The Kyua Authors.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9//   notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright
11//   notice, this list of conditions and the following disclaimer in the
12//   documentation and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors
14//   may be used to endorse or promote products derived from this software
15//   without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29#include "utils/units.hpp"
30
31#include <sstream>
32#include <stdexcept>
33
34#include <atf-c++.hpp>
35
36namespace units = utils::units;
37
38
39ATF_TEST_CASE_WITHOUT_HEAD(bytes__format__tb);
40ATF_TEST_CASE_BODY(bytes__format__tb)
41{
42    using units::TB;
43    using units::GB;
44
45    ATF_REQUIRE_EQ("2.00T", units::bytes(2 * TB).format());
46    ATF_REQUIRE_EQ("45.12T", units::bytes(45 * TB + 120 * GB).format());
47}
48
49
50ATF_TEST_CASE_WITHOUT_HEAD(bytes__format__gb);
51ATF_TEST_CASE_BODY(bytes__format__gb)
52{
53    using units::GB;
54    using units::MB;
55
56    ATF_REQUIRE_EQ("5.00G", units::bytes(5 * GB).format());
57    ATF_REQUIRE_EQ("745.96G", units::bytes(745 * GB + 980 * MB).format());
58}
59
60
61ATF_TEST_CASE_WITHOUT_HEAD(bytes__format__mb);
62ATF_TEST_CASE_BODY(bytes__format__mb)
63{
64    using units::MB;
65    using units::KB;
66
67    ATF_REQUIRE_EQ("1.00M", units::bytes(1 * MB).format());
68    ATF_REQUIRE_EQ("1023.50M", units::bytes(1023 * MB + 512 * KB).format());
69}
70
71
72ATF_TEST_CASE_WITHOUT_HEAD(bytes__format__kb);
73ATF_TEST_CASE_BODY(bytes__format__kb)
74{
75    using units::KB;
76
77    ATF_REQUIRE_EQ("3.00K", units::bytes(3 * KB).format());
78    ATF_REQUIRE_EQ("1.33K", units::bytes(1 * KB + 340).format());
79}
80
81
82ATF_TEST_CASE_WITHOUT_HEAD(bytes__format__b);
83ATF_TEST_CASE_BODY(bytes__format__b)
84{
85    ATF_REQUIRE_EQ("0", units::bytes().format());
86    ATF_REQUIRE_EQ("0", units::bytes(0).format());
87    ATF_REQUIRE_EQ("1023", units::bytes(1023).format());
88}
89
90
91ATF_TEST_CASE_WITHOUT_HEAD(bytes__parse__tb);
92ATF_TEST_CASE_BODY(bytes__parse__tb)
93{
94    using units::TB;
95    using units::GB;
96
97    ATF_REQUIRE_EQ(0, units::bytes::parse("0T"));
98    ATF_REQUIRE_EQ(units::bytes(TB), units::bytes::parse("1T"));
99    ATF_REQUIRE_EQ(units::bytes(TB), units::bytes::parse("1t"));
100    ATF_REQUIRE_EQ(13567973486755LL, units::bytes::parse("12.340000T"));
101}
102
103
104ATF_TEST_CASE_WITHOUT_HEAD(bytes__parse__gb);
105ATF_TEST_CASE_BODY(bytes__parse__gb)
106{
107    using units::GB;
108    using units::MB;
109
110    ATF_REQUIRE_EQ(0, units::bytes::parse("0G"));
111    ATF_REQUIRE_EQ(units::bytes(GB), units::bytes::parse("1G"));
112    ATF_REQUIRE_EQ(units::bytes(GB), units::bytes::parse("1g"));
113    ATF_REQUIRE_EQ(13249974108LL, units::bytes::parse("12.340G"));
114}
115
116
117ATF_TEST_CASE_WITHOUT_HEAD(bytes__parse__mb);
118ATF_TEST_CASE_BODY(bytes__parse__mb)
119{
120    using units::MB;
121    using units::KB;
122
123    ATF_REQUIRE_EQ(0, units::bytes::parse("0M"));
124    ATF_REQUIRE_EQ(units::bytes(MB), units::bytes::parse("1M"));
125    ATF_REQUIRE_EQ(units::bytes(MB), units::bytes::parse("1m"));
126    ATF_REQUIRE_EQ(12939427, units::bytes::parse("12.34000M"));
127}
128
129
130ATF_TEST_CASE_WITHOUT_HEAD(bytes__parse__kb);
131ATF_TEST_CASE_BODY(bytes__parse__kb)
132{
133    using units::KB;
134
135    ATF_REQUIRE_EQ(0, units::bytes::parse("0K"));
136    ATF_REQUIRE_EQ(units::bytes(KB), units::bytes::parse("1K"));
137    ATF_REQUIRE_EQ(units::bytes(KB), units::bytes::parse("1k"));
138    ATF_REQUIRE_EQ(12636, units::bytes::parse("12.34K"));
139}
140
141
142ATF_TEST_CASE_WITHOUT_HEAD(bytes__parse__b);
143ATF_TEST_CASE_BODY(bytes__parse__b)
144{
145    ATF_REQUIRE_EQ(0, units::bytes::parse("0"));
146    ATF_REQUIRE_EQ(89, units::bytes::parse("89"));
147    ATF_REQUIRE_EQ(1234, units::bytes::parse("1234"));
148    ATF_REQUIRE_EQ(1234567890, units::bytes::parse("1234567890"));
149}
150
151
152ATF_TEST_CASE_WITHOUT_HEAD(bytes__parse__error);
153ATF_TEST_CASE_BODY(bytes__parse__error)
154{
155    ATF_REQUIRE_THROW_RE(std::runtime_error, "empty", units::bytes::parse(""));
156    ATF_REQUIRE_THROW_RE(std::runtime_error, "empty", units::bytes::parse("k"));
157
158    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'.'",
159                         units::bytes::parse("."));
160    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'3.'",
161                         units::bytes::parse("3."));
162    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'.3'",
163                         units::bytes::parse(".3"));
164
165    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*' t'",
166                         units::bytes::parse(" t"));
167    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'.t'",
168                         units::bytes::parse(".t"));
169    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'12 t'",
170                         units::bytes::parse("12 t"));
171    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'12.t'",
172                         units::bytes::parse("12.t"));
173    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'.12t'",
174                         units::bytes::parse(".12t"));
175    ATF_REQUIRE_THROW_RE(std::runtime_error, "Invalid.*'abt'",
176                         units::bytes::parse("abt"));
177}
178
179
180ATF_TEST_CASE_WITHOUT_HEAD(bytes__istream__one_word);
181ATF_TEST_CASE_BODY(bytes__istream__one_word)
182{
183    std::istringstream input("12M");
184
185    units::bytes bytes;
186    input >> bytes;
187    ATF_REQUIRE(input.eof());
188    ATF_REQUIRE_EQ(units::bytes(12 * units::MB), bytes);
189}
190
191
192ATF_TEST_CASE_WITHOUT_HEAD(bytes__istream__many_words);
193ATF_TEST_CASE_BODY(bytes__istream__many_words)
194{
195    std::istringstream input("12M more");
196
197    units::bytes bytes;
198    input >> bytes;
199    ATF_REQUIRE(input.good());
200    ATF_REQUIRE_EQ(units::bytes(12 * units::MB), bytes);
201
202    std::string word;
203    input >> word;
204    ATF_REQUIRE_EQ("more", word);
205}
206
207
208ATF_TEST_CASE_WITHOUT_HEAD(bytes__istream__error);
209ATF_TEST_CASE_BODY(bytes__istream__error)
210{
211    std::istringstream input("12.M more");
212
213    units::bytes bytes(123456789);
214    input >> bytes;
215    ATF_REQUIRE(input.bad());
216    ATF_REQUIRE_EQ(units::bytes(123456789), bytes);
217}
218
219
220ATF_TEST_CASE_WITHOUT_HEAD(bytes__ostream);
221ATF_TEST_CASE_BODY(bytes__ostream)
222{
223    std::ostringstream output;
224    output << "foo " << units::bytes(5 * units::KB) << " bar";
225    ATF_REQUIRE_EQ("foo 5.00K bar", output.str());
226}
227
228
229ATF_INIT_TEST_CASES(tcs)
230{
231    ATF_ADD_TEST_CASE(tcs, bytes__format__tb);
232    ATF_ADD_TEST_CASE(tcs, bytes__format__gb);
233    ATF_ADD_TEST_CASE(tcs, bytes__format__mb);
234    ATF_ADD_TEST_CASE(tcs, bytes__format__kb);
235    ATF_ADD_TEST_CASE(tcs, bytes__format__b);
236
237    ATF_ADD_TEST_CASE(tcs, bytes__parse__tb);
238    ATF_ADD_TEST_CASE(tcs, bytes__parse__gb);
239    ATF_ADD_TEST_CASE(tcs, bytes__parse__mb);
240    ATF_ADD_TEST_CASE(tcs, bytes__parse__kb);
241    ATF_ADD_TEST_CASE(tcs, bytes__parse__b);
242    ATF_ADD_TEST_CASE(tcs, bytes__parse__error);
243
244    ATF_ADD_TEST_CASE(tcs, bytes__istream__one_word);
245    ATF_ADD_TEST_CASE(tcs, bytes__istream__many_words);
246    ATF_ADD_TEST_CASE(tcs, bytes__istream__error);
247    ATF_ADD_TEST_CASE(tcs, bytes__ostream);
248}
249