1 // Copyright (c) 2013 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 #ifndef TOOLS_GN_TEST_WITH_SCOPE_H_ 6 #define TOOLS_GN_TEST_WITH_SCOPE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "gn/build_settings.h" 12 #include "gn/c_tool.h" 13 #include "gn/err.h" 14 #include "gn/general_tool.h" 15 #include "gn/input_file.h" 16 #include "gn/parse_tree.h" 17 #include "gn/rust_tool.h" 18 #include "gn/scope.h" 19 #include "gn/scope_per_file_provider.h" 20 #include "gn/settings.h" 21 #include "gn/target.h" 22 #include "gn/token.h" 23 #include "gn/toolchain.h" 24 #include "gn/value.h" 25 26 // A helper class for setting up a Scope that a test can use. It makes a 27 // toolchain and sets up all the build state. 28 class TestWithScope { 29 public: 30 TestWithScope(); 31 ~TestWithScope(); 32 build_settings()33 BuildSettings* build_settings() { return &build_settings_; } settings()34 Settings* settings() { return &settings_; } settings()35 const Settings* settings() const { return &settings_; } toolchain()36 Toolchain* toolchain() { return &toolchain_; } toolchain()37 const Toolchain* toolchain() const { return &toolchain_; } scope()38 Scope* scope() { return &scope_; } items()39 const Scope::ItemVector& items() { return items_; } 40 41 // This buffer accumulates output from any print() commands executed in the 42 // context of this test. Note that the implementation of this is not 43 // threadsafe so don't write tests that call print from multiple threads. print_output()44 std::string& print_output() { return print_output_; } 45 46 // Parse the given string into a label in the default toolchain. This will 47 // assert if the label isn't valid (this is intended for hardcoded labels). 48 Label ParseLabel(const std::string& str) const; 49 50 // Parses, evaluates, and resolves targets from the given snippet of code. 51 // All targets must be defined in dependency order (does not use a Builder, 52 // just blindly resolves all targets in order). 53 bool ExecuteSnippet(const std::string& str, Err* err); 54 55 Value ExecuteExpression(const std::string& expr, Err* err); 56 57 // Fills in the tools for the given toolchain with reasonable default values. 58 // The toolchain in this object will be automatically set up with this 59 // function, it is exposed to allow tests to get the same functionality for 60 // other toolchains they make. 61 // Two slightly different toolchains can be generated by this function, 62 // based on the use_toc argument. This is only currently required by 63 // one test. 64 static void SetupToolchain(Toolchain* toolchain, bool use_toc = false); 65 66 // Sets the given text command on the given tool, parsing it as a 67 // substitution pattern. This will assert if the input is malformed. This is 68 // designed to help setting up Tools for tests. 69 static void SetCommandForTool(const std::string& cmd, Tool* tool); 70 71 private: 72 void AppendPrintOutput(const std::string& str); 73 74 BuildSettings build_settings_; 75 Settings settings_; 76 Toolchain toolchain_; 77 Scope scope_; 78 Scope::ItemVector items_; 79 80 // Supplies the scope with built-in variables like root_out_dir. 81 ScopePerFileProvider scope_progammatic_provider_; 82 83 std::string print_output_; 84 85 TestWithScope(const TestWithScope&) = delete; 86 TestWithScope& operator=(const TestWithScope&) = delete; 87 }; 88 89 // Helper class to treat some string input as a file. 90 // 91 // Instantiate it with the contents you want, be sure to check for error, and 92 // then you can execute the ParseNode or whatever. 93 class TestParseInput { 94 public: 95 explicit TestParseInput(const std::string& input); 96 ~TestParseInput(); 97 98 // Indicates whether and what error occurred during tokenizing and parsing. has_error()99 bool has_error() const { return parse_err_.has_error(); } parse_err()100 const Err& parse_err() const { return parse_err_; } 101 input_file()102 const InputFile& input_file() const { return input_file_; } tokens()103 const std::vector<Token>& tokens() const { return tokens_; } parsed()104 const ParseNode* parsed() const { return parsed_.get(); } 105 106 private: 107 InputFile input_file_; 108 109 std::vector<Token> tokens_; 110 std::unique_ptr<ParseNode> parsed_; 111 112 Err parse_err_; 113 114 TestParseInput(const TestParseInput&) = delete; 115 TestParseInput& operator=(const TestParseInput&) = delete; 116 }; 117 118 // Shortcut for creating targets for tests that take the test setup, a pretty- 119 // style label, and a target type and sets everything up. The target will 120 // default to public visibility. 121 class TestTarget : public Target { 122 public: 123 TestTarget(const TestWithScope& setup, 124 const std::string& label_string, 125 Target::OutputType type); 126 ~TestTarget() override; 127 }; 128 129 #endif // TOOLS_GN_TEST_WITH_SCOPE_H_ 130