diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/slang-test/slang-test-main.cpp | 4 | ||||
| -rw-r--r-- | tools/slang-test/unit-test-json.cpp | 45 | ||||
| -rw-r--r-- | tools/slang-test/unit-test-string.cpp | 137 |
3 files changed, 184 insertions, 2 deletions
diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index ded4c777c..5e0d1142d 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -1416,8 +1416,8 @@ TestResult runCompile(TestContext* context, TestInput& input) for (auto arg : input.testOptions->args) { - // If there is a quote in the string, assume it is 'escaped'. - if (arg.indexOf(escapeHandler->getQuoteChar()) >= 0) + // If unescaping is needed, do it + if (StringEscapeUtil::isUnescapeShellLikeNeeded(escapeHandler, arg.getUnownedSlice())) { StringBuilder buf; StringEscapeUtil::unescapeShellLike(escapeHandler, arg.getUnownedSlice(), buf); diff --git a/tools/slang-test/unit-test-json.cpp b/tools/slang-test/unit-test-json.cpp index 5a59cdcc3..bcd5bf1f0 100644 --- a/tools/slang-test/unit-test-json.cpp +++ b/tools/slang-test/unit-test-json.cpp @@ -2,6 +2,7 @@ #include "../../source/compiler-core/slang-json-lexer.h" #include "../../source/core/slang-string-escape-util.h" #include "../../source/compiler-core/slang-json-parser.h" +#include "../../source/compiler-core/slang-json-value.h" #include "test-context.h" @@ -221,6 +222,50 @@ static void jsonUnitTest() } } + + + { + JSONValue value; + + value = JSONValue::makeBool(true); + + // Only need a SourceManager if we are going to store lexemes + RefPtr<JSONContainer> container = new JSONContainer(nullptr); + + { + List<JSONValue> values; + + for (Int i = 0; i < 100; ++i) + { + + values.add(JSONValue::makeInt(i)); + values.add(JSONValue::makeFloat(-double(i))); + } + + JSONValue array = container->createArray(values.getBuffer(), values.getCount()); + + auto arrayView = container->getArray(array); + + SLANG_CHECK(arrayView.getCount() == values.getCount()); + + // Check the values are the same + SLANG_CHECK(container->areEqual(arrayView.getBuffer(), values.getBuffer(), arrayView.getCount())); + } + { + JSONValue obj = JSONValue::makeEmptyObject(); + + JSONKey key = container->getKey(UnownedStringSlice::fromLiteral("Hello")); + + container->setKeyValue(obj, key, JSONValue::makeNull()); + container->setKeyValue(obj, key, JSONValue::makeInt(10)); + + auto objView = container->getObject(obj); + + SLANG_CHECK(objView.getCount() == 1); + + SLANG_CHECK(objView[0].value.asInteger() == 10); + } + } } SLANG_UNIT_TEST("JSON", jsonUnitTest); diff --git a/tools/slang-test/unit-test-string.cpp b/tools/slang-test/unit-test-string.cpp index e27411b3e..e8a33fbbe 100644 --- a/tools/slang-test/unit-test-string.cpp +++ b/tools/slang-test/unit-test-string.cpp @@ -4,6 +4,10 @@ #include "test-context.h" +//#include <math.h> + +#include <sstream> + using namespace Slang; static bool _areEqual(const List<UnownedStringSlice>& lines, const UnownedStringSlice* checkLines, Int checkLinesCount) @@ -43,6 +47,71 @@ static bool _checkLineParser(const UnownedStringSlice& input) return StringUtil::extractLine(remaining, line) == false; } +static void _append(double v, StringBuilder& buf) +{ + std::ostringstream stream; + stream.imbue(std::locale::classic()); + stream.setf(std::ios::fixed, std::ios::floatfield); + stream.precision(20); + + stream << std::scientific << v; + + buf << stream.str().c_str(); +} + +// Unit of least precision +static int64_t _calcULPDistance(double a, double b) +{ + // Save work if the floats are equal. + // Also handles +0 == -0 + if (a == b) + { + return 0; + } + + const int64_t max = int64_t((~uint64_t(0)) >> 1); + +#if 0 + // Max distance for NaN + if (isnan(a) || isnan(b)) + { + return max; + } + + // If one's infinite and they're not equal, max distance. + if (isinf(a) || isinf(b)) + { + return max; + } +#endif + + int64_t ia, ib; + memcpy(&ia, &a, sizeof(a)); + memcpy(&ib, &b, sizeof(b)); + + // Don't compare differently-signed floats. + if ((ia < 0) != (ib < 0)) + { + return max; + } + + // Return the absolute value of the distance in ULPs. + int64_t distance = ia - ib; + return distance < 0 ? -distance : distance; +} + +static bool _areApproximatelyEqual(double a, double b, double fixedEpsilon = 1e-10, int ulpsEpsilon = 100) +{ + // Handle the near-zero case. + const double difference = abs(a - b); + if (difference <= fixedEpsilon) + { + return true; + } + + return _calcULPDistance(a, b) <= ulpsEpsilon; +} + static void stringUnitTest() { { @@ -122,6 +191,74 @@ static void stringUnitTest() SLANG_CHECK(checkValues.getArrayView() == ArrayView<UnownedStringSlice>(values, 3)); } } + { + + List<double> values; + values.add(0.0); + values.add(-0.0); + + for (Index i = -300; i < 300; ++i) + { + double value = pow(10, i); + + values.add(value); + values.add(-value); + + values.addRange(value / 3); + values.addRange(-value / 3); + } + + StringBuilder buf; + + for (auto value : values) + { + buf.Clear(); + _append(value, buf); + + UnownedStringSlice slice = buf.getUnownedSlice(); + + double parsedValue; + SlangResult res = StringUtil::parseDouble(slice, parsedValue); + + auto ulpsParsed = _calcULPDistance(value, parsedValue); + + SLANG_CHECK(SLANG_SUCCEEDED(res)); + + // Check that they are equal + SLANG_CHECK(_areApproximatelyEqual(value, parsedValue)); + } + } + { + List<int64_t> values; + values.add(0); + + for (Index i = 0; i < 63; ++i) + { + auto value = int64_t(1) << i; + + values.add(value); + values.add(-value); + } + + StringBuilder buf; + + for (auto value : values) + { + buf.Clear(); + buf << value; + + + int64_t parsedValue; + + UnownedStringSlice slice = buf.getUnownedSlice(); + SlangResult res = StringUtil::parseInt64(slice, parsedValue); + + SLANG_CHECK(SLANG_SUCCEEDED(res)); + + // Check that they are equal + SLANG_CHECK(value == parsedValue); + } + } } SLANG_UNIT_TEST("String", stringUnitTest); |
