diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 9cf7468531198..6bb326c7408d1 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -1276,6 +1276,7 @@ if( LLVM_INCLUDE_UTILS ) add_subdirectory(utils/yaml-bench) add_subdirectory(utils/split-file) add_subdirectory(utils/mlgo-utils) + add_subdirectory(utils/llvm-mustachespec) if( LLVM_INCLUDE_TESTS ) set(LLVM_SUBPROJECT_TITLE "Third-Party/Google Test") add_subdirectory(${LLVM_THIRD_PARTY_DIR}/unittest ${CMAKE_CURRENT_BINARY_DIR}/third-party/unittest) diff --git a/llvm/docs/CommandGuide/index.rst b/llvm/docs/CommandGuide/index.rst index 643951eca2a26..2b556c504afb5 100644 --- a/llvm/docs/CommandGuide/index.rst +++ b/llvm/docs/CommandGuide/index.rst @@ -90,6 +90,7 @@ Developer Tools llvm-pdbutil llvm-profgen llvm-tli-checker + llvm-mustachespec Remarks Tools ~~~~~~~~~~~~~~ diff --git a/llvm/docs/CommandGuide/llvm-mustachespec.rst b/llvm/docs/CommandGuide/llvm-mustachespec.rst new file mode 100644 index 0000000000000..75682a4d8cdb0 --- /dev/null +++ b/llvm/docs/CommandGuide/llvm-mustachespec.rst @@ -0,0 +1,12 @@ +llvm-mustachespec - LLVM tool to test Mustache Compliance Library +================================================================= + +llvm-mustachespec test the mustache spec conformance of the LLVM +mustache library. The spec can be found here https://github.com/mustache/spec + + $ llvm-mustachespec input-file + +.. program:: llvm-mustachespec + +Outputs the number of tests failures and success in the spec + diff --git a/llvm/utils/llvm-mustachespec/CMakeLists.txt b/llvm/utils/llvm-mustachespec/CMakeLists.txt new file mode 100644 index 0000000000000..2a94eda32c9bb --- /dev/null +++ b/llvm/utils/llvm-mustachespec/CMakeLists.txt @@ -0,0 +1,5 @@ +add_llvm_utility(llvm-mustachespec + llvm-mustachespec.cpp + ) + +target_link_libraries(llvm-mustachespec PRIVATE LLVMSupport) diff --git a/llvm/utils/llvm-mustachespec/llvm-mustachespec.cpp b/llvm/utils/llvm-mustachespec/llvm-mustachespec.cpp new file mode 100644 index 0000000000000..13d1cdba2c861 --- /dev/null +++ b/llvm/utils/llvm-mustachespec/llvm-mustachespec.cpp @@ -0,0 +1,104 @@ +//===- llvm-mustachespec.cpp - The LLVM Modular Optimizer +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Simple drivers to test the mustache spec found here +// https://github.com/mustache/ +// It is used to verify that the current implementation conforms to the spec +// simply download the spec and pass the test files to the driver +// +// Currently Triple Mustache is not supported we expect the following spec +// test to fail: +// Triple Mustache +// Triple Mustache Integer Interpolation +// Triple Mustache Decimal Interpolation +// Triple Mustache Null Interpolation +// Triple Mustache Context Miss Interpolation +// Dotted Names - Triple Mustache Interpolation +// Implicit Iterators - Triple Mustache +// Triple Mustache - Surrounding Whitespace +// Triple Mustache - Standalone +// Triple Mustache With Padding +// Standalone Indentation +// Implicit Iterator - Triple mustache +// +// Usage: +// mustache path/to/test/file/test.json path/to/test/file/test2.json ... +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Mustache.h" +#include + +using namespace llvm; +using namespace llvm::json; +using namespace llvm::mustache; + +cl::list InputFiles(cl::Positional, cl::desc(""), + cl::OneOrMore); + +void runThroughTest(StringRef InputFile) { + llvm::outs() << "Running Tests: " << InputFile << "\n"; + ErrorOr> BufferOrError = + MemoryBuffer::getFile(InputFile); + + if (auto EC = BufferOrError.getError()) { + return; + } + std::unique_ptr Buffer = std::move(BufferOrError.get()); + llvm::StringRef FileContent = Buffer->getBuffer(); + Expected Json = parse(FileContent); + + if (auto E = Json.takeError()) { + errs() << "Parsing error: " << toString(std::move(E)) << "\n"; + return; + } + // Get test + Array *Obj = (*Json).getAsObject()->getArray("tests"); + size_t Total = 0; + size_t Success = 0; + for (Value V : *Obj) { + Object *TestCase = V.getAsObject(); + StringRef TemplateStr = TestCase->getString("template").value(); + StringRef ExpectedStr = TestCase->getString("expected").value(); + StringRef Name = TestCase->getString("name").value(); + Value *Data = TestCase->get("data"); + Value *Partials = TestCase->get("partials"); + + if (!Data) + continue; + + Template T = Template(TemplateStr); + if (Partials) { + for (auto &PartialPairs : *Partials->getAsObject()) { + const auto &[Partial, Str] = PartialPairs; + T.registerPartial((*Str.getAsString()).str(), Partial.str()); + } + } + std::string ActualStr; + llvm::raw_string_ostream OS(ActualStr); + T.render(*Data, OS); + if (ExpectedStr == ActualStr) { + Success++; + } else { + llvm::outs() << "Test Failed: " << Name << "\n"; + } + Total++; + } + + llvm::outs() << "Result " << Success << "/" << Total << " succeeded\n"; +} + +int main(int argc, char **argv) { + llvm::cl::ParseCommandLineOptions(argc, argv); + for (const auto &FileName : InputFiles) { + runThroughTest(FileName); + } + return 0; +}