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 "base/macros.h" 12 #include "gn/build_settings.h" 13 #include "gn/c_tool.h" 14 #include "gn/err.h" 15 #include "gn/general_tool.h" 16 #include "gn/input_file.h" 17 #include "gn/parse_tree.h" 18 #include "gn/rust_tool.h" 19 #include "gn/scope.h" 20 #include "gn/scope_per_file_provider.h" 21 #include "gn/settings.h" 22 #include "gn/target.h" 23 #include "gn/token.h" 24 #include "gn/toolchain.h" 25 #include "gn/value.h" 26 27 // A helper class for setting up a Scope that a test can use. It makes a 28 // toolchain and sets up all the build state. 29 class TestWithScope { 30 public: 31 TestWithScope(); 32 ~TestWithScope(); 33 build_settings()34 BuildSettings* build_settings() { return &build_settings_; } settings()35 Settings* settings() { return &settings_; } settings()36 const Settings* settings() const { return &settings_; } toolchain()37 Toolchain* toolchain() { return &toolchain_; } toolchain()38 const Toolchain* toolchain() const { return &toolchain_; } scope()39 Scope* scope() { return &scope_; } items()40 const Scope::ItemVector& items() { return items_; } 41 42 // This buffer accumulates output from any print() commands executed in the 43 // context of this test. Note that the implementation of this is not 44 // threadsafe so don't write tests that call print from multiple threads. print_output()45 std::string& print_output() { return print_output_; } 46 47 // Parse the given string into a label in the default toolchain. This will 48 // assert if the label isn't valid (this is intended for hardcoded labels). 49 Label ParseLabel(const std::string& str) const; 50 51 // Parses, evaluates, and resolves targets from the given snippet of code. 52 // All targets must be defined in dependency order (does not use a Builder, 53 // just blindly resolves all targets in order). 54 bool ExecuteSnippet(const std::string& str, Err* err); 55 56 Value ExecuteExpression(const std::string& expr, Err* err); 57 58 // Fills in the tools for the given toolchain with reasonable default values. 59 // The toolchain in this object will be automatically set up with this 60 // function, it is exposed to allow tests to get the same functionality for 61 // other toolchains they make. 62 // Two slightly different toolchains can be generated by this function, 63 // based on the use_toc argument. This is only currently required by 64 // one test. 65 static void SetupToolchain(Toolchain* toolchain, bool use_toc = false); 66 67 // Sets the given text command on the given tool, parsing it as a 68 // substitution pattern. This will assert if the input is malformed. This is 69 // designed to help setting up Tools for tests. 70 static void SetCommandForTool(const std::string& cmd, Tool* tool); 71 72 private: 73 void AppendPrintOutput(const std::string& str); 74 75 BuildSettings build_settings_; 76 Settings settings_; 77 Toolchain toolchain_; 78 Scope scope_; 79 Scope::ItemVector items_; 80 81 // Supplies the scope with built-in variables like root_out_dir. 82 ScopePerFileProvider scope_progammatic_provider_; 83 84 std::string print_output_; 85 86 DISALLOW_COPY_AND_ASSIGN(TestWithScope); 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 DISALLOW_COPY_AND_ASSIGN(TestParseInput); 115 }; 116 117 // Shortcut for creating targets for tests that take the test setup, a pretty- 118 // style label, and a target type and sets everything up. The target will 119 // default to public visibility. 120 class TestTarget : public Target { 121 public: 122 TestTarget(const TestWithScope& setup, 123 const std::string& label_string, 124 Target::OutputType type); 125 ~TestTarget() override; 126 }; 127 128 #endif // TOOLS_GN_TEST_WITH_SCOPE_H_ 129