[dawn.node] Fix webgpu:api,operation,adapter failures

 - Identifier weren't normalized
 - Unknown but undefined limits weren't ignored.
 - GPUFeatureName in webgpu.idl but without a corresponding
   wgpu::FeatureName were ignored.

Bug: None
Change-Id: I723c4b8a66a1f3aa633078cdfc047ea96abb5e33
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/226414
Reviewed-by: Gregg Tavares <gman@google.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/node/binding/GPUAdapter.cpp b/src/dawn/node/binding/GPUAdapter.cpp
index 610a4a8..3a9585e 100644
--- a/src/dawn/node/binding/GPUAdapter.cpp
+++ b/src/dawn/node/binding/GPUAdapter.cpp
@@ -204,6 +204,7 @@
         // requiredFeatures is a "sequence<GPUFeatureName>" so a Javascript exception should be
         // thrown if one of the strings isn't one of the known features.
         if (!conv(feature, required)) {
+            Napi::TypeError::New(env, "Unknown GPUFeatureName.").ThrowAsJavaScriptException();
             return {env, interop::kUnusedPromise};
         }
 
@@ -237,9 +238,11 @@
     FOR_EACH_LIMIT(COPY_LIMIT)
 #undef COPY_LIMIT
 
-    for (auto [key, _] : descriptor.requiredLimits) {
-        promise.Reject(binding::Errors::OperationError(env, "Unknown limit \"" + key + "\""));
-        return promise;
+    for (auto [key, limit] : descriptor.requiredLimits) {
+        if (!std::holds_alternative<interop::UndefinedType>(limit)) {
+            promise.Reject(binding::Errors::OperationError(env, "Unknown limit \"" + key + "\""));
+            return promise;
+        }
     }
 
     desc.requiredFeatureCount = requiredFeatures.size();
diff --git a/src/dawn/node/binding/GPUAdapterInfo.cpp b/src/dawn/node/binding/GPUAdapterInfo.cpp
index cfd1c73..81dab1c 100644
--- a/src/dawn/node/binding/GPUAdapterInfo.cpp
+++ b/src/dawn/node/binding/GPUAdapterInfo.cpp
@@ -27,6 +27,7 @@
 
 #include "src/dawn/node/binding/GPUAdapterInfo.h"
 
+#include <cctype>
 #include <iomanip>
 #include <sstream>
 
@@ -76,12 +77,36 @@
     uint32_t getN(Napi::Env) override { return N; }
     uint32_t getK(Napi::Env) override { return K; }
 };
+
+// Normalize according to https://gpuweb.github.io/gpuweb/#normalized-identifier-string
+std::string NormalizeIdentifierString(wgpu::StringView s) {
+    std::ostringstream o;
+
+    // Used to concatenate multiple non-alnum into a single dash.
+    bool lastWasDash = false;
+    // Used to start adding dashes only after we had one alnum.
+    bool hadAlnum = false;
+
+    for (char c : std::string_view(s)) {
+        if (std::isalnum(c)) {
+            o << std::tolower(c);
+            lastWasDash = false;
+            hadAlnum = true;
+        } else if (!lastWasDash && hadAlnum) {
+            o << '-';
+            lastWasDash = true;
+        }
+    }
+
+    return o.str();
+}
+
 }  // namespace
 
 GPUAdapterInfo::GPUAdapterInfo(const wgpu::AdapterInfo& info)
-    : vendor_(info.vendor),
-      architecture_(info.architecture),
-      device_(info.device),
+    : vendor_(NormalizeIdentifierString(info.vendor)),
+      architecture_(NormalizeIdentifierString(info.architecture)),
+      device_(NormalizeIdentifierString(info.device)),
       description_(info.description),
       subgroup_min_size_(info.subgroupMinSize),
       subgroup_max_size_(info.subgroupMaxSize) {