1 // Copyright 2014 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 "model/test_result.hpp" 30 31 #include "utils/format/macros.hpp" 32 #include "utils/sanity.hpp" 33 #include "utils/text/operations.ipp" 34 35 namespace text = utils::text; 36 37 38 /// Constructs a base result. 39 /// 40 /// \param type_ The type of the result. 41 /// \param reason_ The reason explaining the result, if any. It is OK for this 42 /// to be empty, which is actually the default. 43 model::test_result::test_result(const test_result_type type_, 44 const std::string& reason_) : 45 _type(type_), 46 _reason(reason_) 47 { 48 } 49 50 51 /// Returns the type of the result. 52 /// 53 /// \return A result type. 54 model::test_result_type 55 model::test_result::type(void) const 56 { 57 return _type; 58 } 59 60 61 /// Returns the reason explaining the result. 62 /// 63 /// \return A textual reason, possibly empty. 64 const std::string& 65 model::test_result::reason(void) const 66 { 67 return _reason; 68 } 69 70 71 /// True if the test case result has a positive connotation. 72 /// 73 /// \return Whether the test case is good or not. 74 bool 75 model::test_result::good(void) const 76 { 77 switch (_type) { 78 case test_result_expected_failure: 79 case test_result_passed: 80 case test_result_skipped: 81 return true; 82 83 case test_result_broken: 84 case test_result_failed: 85 return false; 86 } 87 UNREACHABLE; 88 } 89 90 91 /// Equality comparator. 92 /// 93 /// \param other The test result to compare to. 94 /// 95 /// \return True if the other object is equal to this one, false otherwise. 96 bool 97 model::test_result::operator==(const test_result& other) const 98 { 99 return _type == other._type && _reason == other._reason; 100 } 101 102 103 /// Inequality comparator. 104 /// 105 /// \param other The test result to compare to. 106 /// 107 /// \return True if the other object is different from this one, false 108 /// otherwise. 109 bool 110 model::test_result::operator!=(const test_result& other) const 111 { 112 return !(*this == other); 113 } 114 115 116 /// Injects the object into a stream. 117 /// 118 /// \param output The stream into which to inject the object. 119 /// \param object The object to format. 120 /// 121 /// \return The output stream. 122 std::ostream& 123 model::operator<<(std::ostream& output, const test_result& object) 124 { 125 std::string result_name; 126 switch (object.type()) { 127 case test_result_broken: result_name = "broken"; break; 128 case test_result_expected_failure: result_name = "expected_failure"; break; 129 case test_result_failed: result_name = "failed"; break; 130 case test_result_passed: result_name = "passed"; break; 131 case test_result_skipped: result_name = "skipped"; break; 132 } 133 const std::string& reason = object.reason(); 134 if (reason.empty()) { 135 output << F("model::test_result{type=%s}") 136 % text::quote(result_name, '\''); 137 } else { 138 output << F("model::test_result{type=%s, reason=%s}") 139 % text::quote(result_name, '\'') % text::quote(reason, '\''); 140 } 141 return output; 142 } 143