Add ParserImplTestWithParam to reduce boilerplate

There were a number of places where we were declaring classes derived from `testing::TestWithParam<T>` and then adding the same `parser()` helper logic.

Move this common logic down to a new `ParserImplTestWithParam<T>` class, and derive from that instead.

Removes a whole bunch of copy-pasta.

Change-Id: I8f308b77817fd6327c045d2fdee4462b7f32897a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/31401
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/reader/wgsl/parser_impl_pipeline_stage_test.cc b/src/reader/wgsl/parser_impl_pipeline_stage_test.cc
index 028f4c7..d1c2852 100644
--- a/src/reader/wgsl/parser_impl_pipeline_stage_test.cc
+++ b/src/reader/wgsl/parser_impl_pipeline_stage_test.cc
@@ -31,24 +31,7 @@
   return out;
 }
 
-class PipelineStageTest : public testing::TestWithParam<PipelineStageData> {
- public:
-  PipelineStageTest() = default;
-  ~PipelineStageTest() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class PipelineStageTest : public ParserImplTestWithParam<PipelineStageData> {};
 
 TEST_P(PipelineStageTest, Parses) {
   auto params = GetParam();
diff --git a/src/reader/wgsl/parser_impl_storage_class_test.cc b/src/reader/wgsl/parser_impl_storage_class_test.cc
index ed3f358..f595120 100644
--- a/src/reader/wgsl/parser_impl_storage_class_test.cc
+++ b/src/reader/wgsl/parser_impl_storage_class_test.cc
@@ -31,24 +31,7 @@
   return out;
 }
 
-class StorageClassTest : public testing::TestWithParam<StorageClassData> {
- public:
-  StorageClassTest() = default;
-  ~StorageClassTest() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class StorageClassTest : public ParserImplTestWithParam<StorageClassData> {};
 
 TEST_P(StorageClassTest, Parses) {
   auto params = GetParam();
diff --git a/src/reader/wgsl/parser_impl_struct_decoration_test.cc b/src/reader/wgsl/parser_impl_struct_decoration_test.cc
index 21102d1..4d07af4 100644
--- a/src/reader/wgsl/parser_impl_struct_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_decoration_test.cc
@@ -32,24 +32,7 @@
 }
 
 class StructDecorationTest
-    : public testing::TestWithParam<StructDecorationData> {
- public:
-  StructDecorationTest() = default;
-  ~StructDecorationTest() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+    : public ParserImplTestWithParam<StructDecorationData> {};
 
 TEST_P(StructDecorationTest, Parses) {
   auto params = GetParam();
diff --git a/src/reader/wgsl/parser_impl_test_helper.h b/src/reader/wgsl/parser_impl_test_helper.h
index bdb1a29..0961b15 100644
--- a/src/reader/wgsl/parser_impl_test_helper.h
+++ b/src/reader/wgsl/parser_impl_test_helper.h
@@ -55,6 +55,36 @@
   Context ctx_;
 };
 
+/// WGSL Parser test class with param
+template <typename T>
+class ParserImplTestWithParam : public testing::TestWithParam<T> {
+ public:
+  /// Constructor
+  ParserImplTestWithParam() = default;
+  ~ParserImplTestWithParam() override = default;
+
+  /// Sets up the test helper
+  void SetUp() override { ctx_.Reset(); }
+
+  /// Tears down the test helper
+  void TearDown() override { impl_ = nullptr; }
+
+  /// Retrieves the parser from the helper
+  /// @param str the string to parse
+  /// @returns the parser implementation
+  ParserImpl* parser(const std::string& str) {
+    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
+    return impl_.get();
+  }
+
+  /// @returns the type manager
+  TypeManager* tm() { return &(ctx_.type_mgr()); }
+
+ private:
+  std::unique_ptr<ParserImpl> impl_;
+  Context ctx_;
+};
+
 }  // namespace wgsl
 }  // namespace reader
 }  // namespace tint
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index 5813451..7ad9e56 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -123,24 +123,8 @@
   out << std::string(data.input);
   return out;
 }
-class VecTest : public testing::TestWithParam<VecData> {
- public:
-  VecTest() = default;
-  ~VecTest() override = default;
 
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class VecTest : public ParserImplTestWithParam<VecData> {};
 
 TEST_P(VecTest, Parse) {
   auto params = GetParam();
@@ -157,24 +141,7 @@
                                          VecData{"vec3<f32>", 3},
                                          VecData{"vec4<f32>", 4}));
 
-class VecMissingGreaterThanTest : public testing::TestWithParam<VecData> {
- public:
-  VecMissingGreaterThanTest() = default;
-  ~VecMissingGreaterThanTest() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class VecMissingGreaterThanTest : public ParserImplTestWithParam<VecData> {};
 
 TEST_P(VecMissingGreaterThanTest, Handles_Missing_GreaterThan) {
   auto params = GetParam();
@@ -190,24 +157,7 @@
                                          VecData{"vec3<f32", 3},
                                          VecData{"vec4<f32", 4}));
 
-class VecMissingLessThanTest : public testing::TestWithParam<VecData> {
- public:
-  VecMissingLessThanTest() = default;
-  ~VecMissingLessThanTest() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class VecMissingLessThanTest : public ParserImplTestWithParam<VecData> {};
 
 TEST_P(VecMissingLessThanTest, Handles_Missing_GreaterThan) {
   auto params = GetParam();
@@ -223,24 +173,7 @@
                                          VecData{"vec3", 3},
                                          VecData{"vec4", 4}));
 
-class VecBadType : public testing::TestWithParam<VecData> {
- public:
-  VecBadType() = default;
-  ~VecBadType() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class VecBadType : public ParserImplTestWithParam<VecData> {};
 
 TEST_P(VecBadType, Handles_Unknown_Type) {
   auto params = GetParam();
@@ -256,24 +189,7 @@
                                          VecData{"vec3<unknown", 3},
                                          VecData{"vec4<unknown", 4}));
 
-class VecMissingType : public testing::TestWithParam<VecData> {
- public:
-  VecMissingType() = default;
-  ~VecMissingType() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class VecMissingType : public ParserImplTestWithParam<VecData> {};
 
 TEST_P(VecMissingType, Handles_Missing_Type) {
   auto params = GetParam();
@@ -604,24 +520,8 @@
   out << std::string(data.input);
   return out;
 }
-class MatrixTest : public testing::TestWithParam<MatrixData> {
- public:
-  MatrixTest() = default;
-  ~MatrixTest() override = default;
 
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class MatrixTest : public ParserImplTestWithParam<MatrixData> {};
 
 TEST_P(MatrixTest, Parse) {
   auto params = GetParam();
@@ -646,24 +546,9 @@
                                          MatrixData{"mat4x3<f32>", 4, 3},
                                          MatrixData{"mat4x4<f32>", 4, 4}));
 
-class MatrixMissingGreaterThanTest : public testing::TestWithParam<MatrixData> {
- public:
-  MatrixMissingGreaterThanTest() = default;
-  ~MatrixMissingGreaterThanTest() override = default;
+class MatrixMissingGreaterThanTest
+    : public ParserImplTestWithParam<MatrixData> {};
 
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
 TEST_P(MatrixMissingGreaterThanTest, Handles_Missing_GreaterThan) {
   auto params = GetParam();
   auto* p = parser(params.input);
@@ -684,24 +569,8 @@
                                          MatrixData{"mat4x3<f32", 4, 3},
                                          MatrixData{"mat4x4<f32", 4, 4}));
 
-class MatrixMissingLessThanTest : public testing::TestWithParam<MatrixData> {
- public:
-  MatrixMissingLessThanTest() = default;
-  ~MatrixMissingLessThanTest() override = default;
+class MatrixMissingLessThanTest : public ParserImplTestWithParam<MatrixData> {};
 
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
 TEST_P(MatrixMissingLessThanTest, Handles_Missing_GreaterThan) {
   auto params = GetParam();
   auto* p = parser(params.input);
@@ -722,24 +591,8 @@
                                          MatrixData{"mat4x3 f32>", 4, 3},
                                          MatrixData{"mat4x4 f32>", 4, 4}));
 
-class MatrixBadType : public testing::TestWithParam<MatrixData> {
- public:
-  MatrixBadType() = default;
-  ~MatrixBadType() override = default;
+class MatrixBadType : public ParserImplTestWithParam<MatrixData> {};
 
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
 TEST_P(MatrixBadType, Handles_Unknown_Type) {
   auto params = GetParam();
   auto* p = parser(params.input);
@@ -760,24 +613,8 @@
                                          MatrixData{"mat4x3<unknown>", 4, 3},
                                          MatrixData{"mat4x4<unknown>", 4, 4}));
 
-class MatrixMissingType : public testing::TestWithParam<MatrixData> {
- public:
-  MatrixMissingType() = default;
-  ~MatrixMissingType() override = default;
+class MatrixMissingType : public ParserImplTestWithParam<MatrixData> {};
 
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
 TEST_P(MatrixMissingType, Handles_Missing_Type) {
   auto params = GetParam();
   auto* p = parser(params.input);
diff --git a/src/reader/wgsl/parser_impl_variable_decoration_test.cc b/src/reader/wgsl/parser_impl_variable_decoration_test.cc
index d410b6d..d2c7755 100644
--- a/src/reader/wgsl/parser_impl_variable_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_decoration_test.cc
@@ -76,24 +76,8 @@
   out << std::string(data.input);
   return out;
 }
-class BuiltinTest : public testing::TestWithParam<BuiltinData> {
- public:
-  BuiltinTest() = default;
-  ~BuiltinTest() override = default;
 
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class BuiltinTest : public ParserImplTestWithParam<BuiltinData> {};
 
 TEST_P(BuiltinTest, VariableDecoration_Builtin) {
   auto params = GetParam();
diff --git a/src/reader/wgsl/parser_impl_variable_storage_decoration_test.cc b/src/reader/wgsl/parser_impl_variable_storage_decoration_test.cc
index 6cbe9cd..fa2b40f 100644
--- a/src/reader/wgsl/parser_impl_variable_storage_decoration_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_storage_decoration_test.cc
@@ -31,24 +31,8 @@
   return out;
 }
 
-class VariableStorageTest : public testing::TestWithParam<VariableStorageData> {
- public:
-  VariableStorageTest() = default;
-  ~VariableStorageTest() override = default;
-
-  void SetUp() override { ctx_.Reset(); }
-
-  void TearDown() override { impl_ = nullptr; }
-
-  ParserImpl* parser(const std::string& str) {
-    impl_ = std::make_unique<ParserImpl>(&ctx_, str);
-    return impl_.get();
-  }
-
- private:
-  std::unique_ptr<ParserImpl> impl_;
-  Context ctx_;
-};
+class VariableStorageTest
+    : public ParserImplTestWithParam<VariableStorageData> {};
 
 TEST_P(VariableStorageTest, Parses) {
   auto params = GetParam();