[ir][spirv-writer] Rework remaining unit tests

Switch almost all tests over to using the `Generate()` and EXPECT_INST
helpers. Fixup some cases of invalid IR that this caught, and tweak
some tests to make sure we're testing the right thing in the presence
of sanitizer transforms.

The `Type` and `Constant` tests still use the PIMPL methods directly,
as types and constants are emitted lazily on first use.

Make almost all of the PIMPL methods private.

Bug: tint:1906
Change-Id: Ia52700e8298b5da5d22770a3949509082cb208bb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/139543
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/writer/spirv/ir/test_helper_ir.h b/src/tint/writer/spirv/ir/test_helper_ir.h
index 27559be..5fbf6e4 100644
--- a/src/tint/writer/spirv/ir/test_helper_ir.h
+++ b/src/tint/writer/spirv/ir/test_helper_ir.h
@@ -17,7 +17,9 @@
 
 #include <string>
 #include <utility>
+#include <vector>
 
+#include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "spirv-tools/libspirv.hpp"
 #include "src/tint/ir/builder.h"
@@ -57,7 +59,7 @@
     /// The SPIR-V generator.
     GeneratorImplIr generator_;
 
-    /// Validation errors
+    /// Errors produced during codegen or SPIR-V validation.
     std::string err_;
 
     /// SPIR-V output.
@@ -66,38 +68,34 @@
     /// @returns the error string from the validation
     std::string Error() const { return err_; }
 
-    /// @returns true if the IR module is valid
-    bool IRIsValid() {
-        auto res = ir::Validate(mod);
-        if (!res) {
-            err_ = res.Failure().str();
+    /// Run the specified generator on the IR module and validate the result.
+    /// @param generator the generator to use for SPIR-V generation
+    /// @returns true if generation and validation succeeded
+    bool Generate(GeneratorImplIr& generator) {
+        if (!generator.Generate()) {
+            err_ = generator.Diagnostics().str();
             return false;
         }
+
+        output_ = Disassemble(generator.Result(), SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES |
+                                                      SPV_BINARY_TO_TEXT_OPTION_INDENT |
+                                                      SPV_BINARY_TO_TEXT_OPTION_COMMENT);
+
+        if (!Validate(generator.Result())) {
+            return false;
+        }
+
         return true;
     }
 
     /// Run the generator on the IR module and validate the result.
     /// @returns true if generation and validation succeeded
-    bool Generate() {
-        if (!generator_.Generate()) {
-            err_ = generator_.Diagnostics().str();
-            return false;
-        }
-        if (!Validate()) {
-            return false;
-        }
-
-        output_ = Disassemble(generator_.Result(), SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES |
-                                                       SPV_BINARY_TO_TEXT_OPTION_INDENT |
-                                                       SPV_BINARY_TO_TEXT_OPTION_COMMENT);
-        return true;
-    }
+    bool Generate() { return Generate(generator_); }
 
     /// Validate the generated SPIR-V using the SPIR-V Tools Validator.
+    /// @param binary the SPIR-V binary module to validate
     /// @returns true if validation succeeded, false otherwise
-    bool Validate() {
-        auto binary = generator_.Result();
-
+    bool Validate(const std::vector<uint32_t>& binary) {
         std::string spv_errors;
         auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*,
                                           const spv_position_t& position, const char* message) {