1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/zucchini/io_utils.h"
6
7 #include <stdint.h>
8
9 #include <sstream>
10 #include <string>
11
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace zucchini {
15
TEST(IOUtilsTest,LimitedOutputStream)16 TEST(IOUtilsTest, LimitedOutputStream) {
17 std::ostringstream oss;
18 LimitedOutputStream los(oss, 3);
19 EXPECT_FALSE(los.full());
20 EXPECT_EQ("", oss.str());
21 // Line 1.
22 los << "a" << 1 << "b" << 2 << "c" << 3 << std::endl;
23 EXPECT_FALSE(los.full());
24 EXPECT_EQ("a1b2c3\n", oss.str());
25 // Line 2.
26 oss.str("");
27 los << "\r\r\n\n" << std::endl; // Manual new lines don't count.
28 EXPECT_FALSE(los.full());
29 EXPECT_EQ("\r\r\n\n\n", oss.str());
30 // Line 3.
31 oss.str("");
32 los << "blah" << 137;
33 EXPECT_FALSE(los.full());
34 los << std::endl;
35 EXPECT_TRUE(los.full());
36 EXPECT_EQ("blah137\n(Additional output suppressed)\n", oss.str());
37 // Not testing adding more lines: the behavior is undefined since we rely on
38 // caller suppressing output if |los.full()| is true.
39 }
40
TEST(IOUtilsTest,AsHex)41 TEST(IOUtilsTest, AsHex) {
42 std::ostringstream oss;
43 // Helper for single-line tests. Eats dummy std::ostream& from operator<<().
44 auto extract = [&oss](std::ostream&) -> std::string {
45 std::string ret = oss.str();
46 oss.str("");
47 return ret;
48 };
49
50 EXPECT_EQ("00000000", extract(oss << AsHex<8>(0)));
51 EXPECT_EQ("12345678", extract(oss << AsHex<8>(0x12345678U)));
52 EXPECT_EQ("9ABCDEF0", extract(oss << AsHex<8>(0x9ABCDEF0U)));
53 EXPECT_EQ("(00000064)", extract(oss << "(" << AsHex<8>(100) << ")"));
54 EXPECT_EQ("00FFFF", extract(oss << AsHex<6>(0xFFFFU)));
55 EXPECT_EQ("FFFF", extract(oss << AsHex<4>(0xFFFFU)));
56 EXPECT_EQ("...FF", extract(oss << AsHex<2>(0xFFFFU)));
57 EXPECT_EQ("...00", extract(oss << AsHex<2>(0x100U)));
58 EXPECT_EQ("FF\n", extract(oss << AsHex<2>(0xFFU) << std::endl));
59 EXPECT_EQ("132457689BACDEF0",
60 extract(oss << AsHex<16, uint64_t>(0x132457689BACDEF0LLU)));
61 EXPECT_EQ("000000000001", extract(oss << AsHex<12, uint8_t>(1)));
62 EXPECT_EQ("00000089", extract(oss << AsHex<8, int32_t>(137)));
63 EXPECT_EQ("...FFFFFFFF", extract(oss << AsHex<8, int32_t>(-1)));
64 EXPECT_EQ("7FFF", extract(oss << AsHex<4, int16_t>(0x7FFFU)));
65 EXPECT_EQ("...8000", extract(oss << AsHex<4, int16_t>(0x8000U)));
66 EXPECT_EQ("8000", extract(oss << AsHex<4, uint16_t>(0x8000U)));
67 }
68
TEST(IOUtilsTest,PrefixSep)69 TEST(IOUtilsTest, PrefixSep) {
70 std::ostringstream oss;
71 PrefixSep sep(",");
72 oss << sep << 3;
73 EXPECT_EQ("3", oss.str());
74 oss << sep << 1;
75 EXPECT_EQ("3,1", oss.str());
76 oss << sep << 4 << sep << 1 << sep << "59";
77 EXPECT_EQ("3,1,4,1,59", oss.str());
78 }
79
TEST(IOUtilsTest,PrefixSepAlt)80 TEST(IOUtilsTest, PrefixSepAlt) {
81 std::ostringstream oss;
82 PrefixSep sep(" ");
83 oss << sep << 3;
84 EXPECT_EQ("3", oss.str());
85 oss << sep << 1;
86 EXPECT_EQ("3 1", oss.str());
87 oss << sep << 4 << sep << 1 << sep << "59";
88 EXPECT_EQ("3 1 4 1 59", oss.str());
89 }
90
TEST(IOUtilsTest,EatChar)91 TEST(IOUtilsTest, EatChar) {
92 std::istringstream main_iss;
93 // Helper for single-line tests.
94 auto iss = [&main_iss](const std::string s) -> std::istringstream& {
95 main_iss.clear();
96 main_iss.str(s);
97 return main_iss;
98 };
99
100 EXPECT_TRUE(iss("a,1") >> EatChar('a') >> EatChar(',') >> EatChar('1'));
101 EXPECT_FALSE(iss("a,a") >> EatChar('a') >> EatChar(',') >> EatChar('1'));
102 EXPECT_FALSE(iss("a") >> EatChar('a') >> EatChar(',') >> EatChar('1'));
103 EXPECT_FALSE(iss("x") >> EatChar('X'));
104 EXPECT_TRUE(iss("_\n") >> EatChar('_') >> EatChar('\n'));
105 }
106
TEST(IOUtilsTest,StrictUInt)107 TEST(IOUtilsTest, StrictUInt) {
108 std::istringstream main_iss;
109 // Helper for single-line tests.
110 auto iss = [&main_iss](const std::string& s) -> std::istringstream& {
111 main_iss.clear();
112 main_iss.str(s);
113 return main_iss;
114 };
115
116 uint32_t u32 = 0;
117 EXPECT_TRUE(iss("1234") >> StrictUInt<uint32_t>(u32));
118 EXPECT_EQ(uint32_t(1234), u32);
119 EXPECT_TRUE(iss("001234") >> StrictUInt<uint32_t>(u32));
120 EXPECT_EQ(uint32_t(1234), u32);
121 EXPECT_FALSE(iss("blahblah") >> StrictUInt<uint32_t>(u32));
122 EXPECT_EQ(uint32_t(1234), u32); // No overwrite on failure.
123 EXPECT_TRUE(iss("137suffix") >> StrictUInt<uint32_t>(u32));
124 EXPECT_EQ(uint32_t(137), u32);
125 EXPECT_FALSE(iss(" 1234") >> StrictUInt<uint32_t>(u32));
126 EXPECT_FALSE(iss("-1234") >> StrictUInt<uint32_t>(u32));
127
128 uint16_t u16 = 0;
129 EXPECT_TRUE(iss("65535") >> StrictUInt<uint16_t>(u16));
130 EXPECT_EQ(uint16_t(65535), u16);
131 EXPECT_FALSE(iss("65536") >> StrictUInt<uint16_t>(u16)); // Overflow.
132
133 uint64_t u64 = 0;
134 EXPECT_TRUE(iss("1000000000001") >> StrictUInt<uint64_t>(u64));
135 EXPECT_EQ(uint64_t(1000000000001LL), u64);
136
137 // uint8_t is stubbed out, so no tests for it.
138 }
139
TEST(IOUtilsTest,ParseSimpleEquations)140 TEST(IOUtilsTest, ParseSimpleEquations) {
141 std::istringstream iss("123+456=579,4-3=1");
142 uint32_t a = 0;
143 uint32_t b = 0;
144 uint32_t c = 0;
145 EXPECT_TRUE(iss >> StrictUInt<uint32_t>(a) >> EatChar('+') >>
146 StrictUInt<uint32_t>(b) >> EatChar('=') >>
147 StrictUInt<uint32_t>(c));
148 EXPECT_EQ(uint32_t(123), a);
149 EXPECT_EQ(uint32_t(456), b);
150 EXPECT_EQ(uint32_t(579), c);
151 EXPECT_TRUE(iss >> EatChar(','));
152 EXPECT_TRUE(iss >> StrictUInt<uint32_t>(a) >> EatChar('-') >>
153 StrictUInt<uint32_t>(b) >> EatChar('=') >>
154 StrictUInt<uint32_t>(c));
155 EXPECT_EQ(uint32_t(4), a);
156 EXPECT_EQ(uint32_t(3), b);
157 EXPECT_EQ(uint32_t(1), c);
158 }
159
160 } // namespace zucchini
161