Add resolver::TestHelper

First step in splitting out resolver tests into multiple files

Change-Id: I58c66ad5e348a50b3e028dff5749cfacb273ea62
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/44161
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index d96332e..7a3a7ca 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -843,6 +843,8 @@
     "src/program_builder_test.cc",
     "src/program_test.cc",
     "src/resolver/resolver_test.cc",
+    "src/resolver/resolver_test_helper.cc",
+    "src/resolver/resolver_test_helper.h",
     "src/semantic/sem_intrinsic_test.cc",
     "src/scope_stack_test.cc",
     "src/symbol_table_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ba20f11..684a9c4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -471,6 +471,8 @@
     intrinsic_table_test.cc
     program_test.cc
     resolver/resolver_test.cc
+    resolver/resolver_test_helper.cc
+    resolver/resolver_test_helper.h
     semantic/sem_intrinsic_test.cc
     scope_stack_test.cc
     symbol_table_test.cc
diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc
index 3f899a2..0e11556 100644
--- a/src/resolver/resolver_test.cc
+++ b/src/resolver/resolver_test.cc
@@ -28,6 +28,7 @@
 #include "src/ast/switch_statement.h"
 #include "src/ast/unary_op_expression.h"
 #include "src/ast/variable_decl_statement.h"
+#include "src/resolver/resolver_test_helper.h"
 #include "src/semantic/call.h"
 #include "src/semantic/function.h"
 #include "src/semantic/member_accessor_expression.h"
@@ -63,41 +64,6 @@
   void to_str(const semantic::Info&, std::ostream&, size_t) const override {}
 };
 
-class ResolverHelper : public ProgramBuilder {
- public:
-  ResolverHelper() : td_(std::make_unique<Resolver>(this)) {}
-
-  Resolver* r() const { return td_.get(); }
-
-  ast::Statement* StmtOf(ast::Expression* expr) {
-    auto* sem_stmt = Sem().Get(expr)->Stmt();
-    return sem_stmt ? sem_stmt->Declaration() : nullptr;
-  }
-
-  bool CheckVarUsers(ast::Variable* var,
-                     std::vector<ast::Expression*>&& expected_users) {
-    auto& var_users = Sem().Get(var)->Users();
-    if (var_users.size() != expected_users.size()) {
-      return false;
-    }
-    for (size_t i = 0; i < var_users.size(); i++) {
-      if (var_users[i]->Declaration() != expected_users[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
- private:
-  std::unique_ptr<Resolver> td_;
-};
-
-class ResolverTest : public ResolverHelper, public testing::Test {};
-
-template <typename T>
-class ResolverTestWithParam : public ResolverHelper,
-                              public testing::TestWithParam<T> {};
-
 TEST_F(ResolverTest, Error_WithEmptySource) {
   auto* s = create<FakeStmt>();
   WrapInFunction(s);
diff --git a/src/resolver/resolver_test_helper.cc b/src/resolver/resolver_test_helper.cc
new file mode 100644
index 0000000..ef3ff64
--- /dev/null
+++ b/src/resolver/resolver_test_helper.cc
@@ -0,0 +1,27 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/resolver/resolver_test_helper.h"
+
+#include <memory>
+
+namespace tint {
+namespace resolver {
+
+TestHelper::TestHelper() : td_(std::make_unique<Resolver>(this)) {}
+
+TestHelper::~TestHelper() = default;
+
+}  // namespace resolver
+}  // namespace tint
diff --git a/src/resolver/resolver_test_helper.h b/src/resolver/resolver_test_helper.h
new file mode 100644
index 0000000..ad60ab9
--- /dev/null
+++ b/src/resolver/resolver_test_helper.h
@@ -0,0 +1,83 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_RESOLVER_RESOLVER_TEST_HELPER_H_
+#define SRC_RESOLVER_RESOLVER_TEST_HELPER_H_
+
+#include <memory>
+#include <vector>
+
+#include "gtest/gtest.h"
+#include "src/program_builder.h"
+#include "src/resolver/resolver.h"
+#include "src/semantic/expression.h"
+#include "src/semantic/statement.h"
+#include "src/semantic/variable.h"
+
+namespace tint {
+namespace resolver {
+
+/// Helper class for testing
+class TestHelper : public ProgramBuilder {
+ public:
+  /// Constructor
+  TestHelper();
+
+  /// Destructor
+  ~TestHelper() override;
+
+  /// @return a pointer to the Resolver
+  Resolver* r() const { return td_.get(); }
+
+  /// Returns the statement that holds the given expression.
+  /// @param expr the ast::Expression
+  /// @return the ast::Statement of the ast::Expression, or nullptr if the
+  /// expression is not owned by a statement.
+  ast::Statement* StmtOf(ast::Expression* expr) {
+    auto* sem_stmt = Sem().Get(expr)->Stmt();
+    return sem_stmt ? sem_stmt->Declaration() : nullptr;
+  }
+
+  /// Checks that all the users of the given variable are as expected
+  /// @param var the variable to check
+  /// @param expected_users the expected users of the variable
+  /// @return true if all users are as expected
+  bool CheckVarUsers(ast::Variable* var,
+                     std::vector<ast::Expression*>&& expected_users) {
+    auto& var_users = Sem().Get(var)->Users();
+    if (var_users.size() != expected_users.size()) {
+      return false;
+    }
+    for (size_t i = 0; i < var_users.size(); i++) {
+      if (var_users[i]->Declaration() != expected_users[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+ private:
+  std::unique_ptr<Resolver> td_;
+};
+
+class ResolverTest : public TestHelper, public testing::Test {};
+
+template <typename T>
+class ResolverTestWithParam : public TestHelper,
+                              public testing::TestWithParam<T> {};
+
+}  // namespace resolver
+}  // namespace tint
+
+#endif  // SRC_RESOLVER_RESOLVER_TEST_HELPER_H_