Skip to content
File

Blob: src/workerd/jsg/web-idl-test.c++

8.2 KB
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5#include "jsg-test.h"
6 
7namespace workerd::jsg::test {
8namespace {
9 
10// Static unit tests for Web IDL type concepts.
11 
12// DictionaryType concept tests
13static_assert(webidl::DictionaryType<TestStruct>);
14static_assert(!webidl::DictionaryType<NumberBox>);
15static_assert(!webidl::DictionaryType<kj::Maybe<TestStruct>>);
16 
17// NonCallbackInterfaceType concept tests
18static_assert(!webidl::NonCallbackInterfaceType<TestStruct>);
19static_assert(webidl::NonCallbackInterfaceType<NumberBox>);
20static_assert(!webidl::NonCallbackInterfaceType<kj::Maybe<NumberBox>>);
21static_assert(webidl::NonCallbackInterfaceType<Ref<NumberBox>>);
22 
23// Backward-compatible variable template tests (these delegate to concepts)
24static_assert(webidl::isNonCallbackInterfaceType<TestStruct> == false);
25static_assert(webidl::isNonCallbackInterfaceType<NumberBox> == true);
26static_assert(webidl::isNonCallbackInterfaceType<kj::Maybe<NumberBox>> == false);
27 
28// Additional type category concept tests
29static_assert(webidl::StringType<kj::String>);
30static_assert(webidl::StringType<USVString>);
31static_assert(webidl::StringType<DOMString>);
32static_assert(!webidl::StringType<int>);
33 
34static_assert(webidl::NumericType<int>);
35static_assert(webidl::NumericType<double>);
36static_assert(!webidl::NumericType<kj::String>);
37 
38static_assert(webidl::BooleanType<bool>);
39static_assert(!webidl::BooleanType<int>);
40 
41static_assert(webidl::InterfaceLikeType<NumberBox>);
42static_assert(webidl::InterfaceLikeType<kj::Array<kj::byte>>);
43static_assert(!webidl::InterfaceLikeType<kj::String>);
44 
45static_assert(webidl::DistinguishableType<kj::String>);
46static_assert(webidl::DistinguishableType<int>);
47static_assert(webidl::DistinguishableType<bool>);
48static_assert(webidl::DistinguishableType<NumberBox>);
49 
50static_assert(webidl::nullableTypeCount<int> == 0);
51static_assert(webidl::nullableTypeCount<kj::Maybe<int>> == 1);
52static_assert(webidl::nullableTypeCount<kj::Maybe<int>, kj::Maybe<kj::String>> == 2);
53static_assert(webidl::nullableTypeCount<kj::OneOf<kj::Maybe<int>, kj::Maybe<kj::String>>> == 2);
54static_assert(
55 webidl::nullableTypeCount<kj::Maybe<kj::OneOf<kj::Maybe<int>, kj::Maybe<kj::String>>>> == 3);
56static_assert(webidl::nullableTypeCount<kj::OneOf<kj::Maybe<int>, kj::Maybe<kj::String>>,
57 kj::OneOf<kj::Maybe<bool>, kj::Maybe<char>>> == 4);
58static_assert(webidl::nullableTypeCount<kj::Maybe<kj::OneOf<kj::Maybe<int>>>> == 2);
59 
60static_assert(webidl::hasDuplicateTypes<int> == false);
61static_assert(webidl::hasDuplicateTypes<int, int> == true);
62static_assert(webidl::hasDuplicateTypes<int, bool> == false);
63static_assert(webidl::hasDuplicateTypes<bool, int, int> == true);
64static_assert(webidl::hasDuplicateTypes<int, bool, int> == true);
65static_assert(webidl::hasDuplicateTypes<int, int, bool> == true);
66static_assert(webidl::hasDuplicateTypes<int, int, bool, char> == true);
67static_assert(webidl::hasDuplicateTypes<int, bool, int, char> == true);
68static_assert(webidl::hasDuplicateTypes<int, bool, char, int> == true);
69static_assert(webidl::hasDuplicateTypes<bool, int, char, int> == true);
70static_assert(webidl::hasDuplicateTypes<bool, char, int, int> == true);
71 
72static_assert(webidl::FlattenedTypeTraits<kj::String, USVString>::stringTypeCount == 2);
73static_assert(webidl::FlattenedTypeTraits<kj::String, DOMString>::stringTypeCount == 2);
74 
75// =====================================================================================
76// ArgumentIndexes tests (meta.h)
77 
78// Member function - no magic param.
79struct Dummy {
80 int noMagic(int, double, bool);
81 int withLock(Lock&, int, double);
82 int withInfo(const v8::FunctionCallbackInfo<v8::Value>&, int);
83 int constNoMagic(int) const;
84 int constWithLock(Lock&, int, double) const;
85 int constWithInfo(const v8::FunctionCallbackInfo<v8::Value>&) const;
86};
87 
88static_assert(
89 kj::isSameType<ArgumentIndexes<decltype(&Dummy::noMagic)>, kj::_::Indexes<0, 1, 2>>());
90static_assert(kj::isSameType<ArgumentIndexes<decltype(&Dummy::withLock)>, kj::_::Indexes<0, 1>>());
91static_assert(kj::isSameType<ArgumentIndexes<decltype(&Dummy::withInfo)>, kj::_::Indexes<0>>());
92static_assert(kj::isSameType<ArgumentIndexes<decltype(&Dummy::constNoMagic)>, kj::_::Indexes<0>>());
93static_assert(
94 kj::isSameType<ArgumentIndexes<decltype(&Dummy::constWithLock)>, kj::_::Indexes<0, 1>>());
95static_assert(kj::isSameType<ArgumentIndexes<decltype(&Dummy::constWithInfo)>, kj::_::Indexes<>>());
96 
97// Free functions.
98static_assert(kj::isSameType<ArgumentIndexes<int(int, int)>, kj::_::Indexes<0, 1>>());
99static_assert(kj::isSameType<ArgumentIndexes<void(Lock&, int)>, kj::_::Indexes<0>>());
100static_assert(kj::isSameType<ArgumentIndexes<void()>, kj::_::Indexes<>>());
101 
102// =====================================================================================
103// requiredArgumentCount tests (meta.h + type-wrapper.h)
104//
105// requiredArgumentCount<TypeWrapper, FuncType> uses the ValueLessParameter concept to detect
106// injected parameter types. We use a minimal mock wrapper that provides the right unwrap()
107// overloads so the concept checks succeed for TypeHandler<T> and a fake injected config type.
108 
109struct FakeConfig {}; // Simulates an InjectConfiguration<T> injected type.
110 
111struct MockTypeWrapper {
112 // Makes ValueLessParameter<MockTypeWrapper, TypeHandler<T>> true.
113 template <typename U>
114 const TypeHandler<U>& unwrap(Lock&, v8::Local<v8::Context>, TypeHandler<U>*);
115 // Makes ValueLessParameter<MockTypeWrapper, FakeConfig> true (simulates InjectConfiguration).
116 FakeConfig unwrap(Lock&, v8::Local<v8::Context>, FakeConfig*);
117};
118 
119// Shorthand for the tests below.
120template <typename T>
121constexpr int rac = requiredArgumentCount<MockTypeWrapper, T>;
122 
123// All required - count equals total visible args.
124static_assert(rac<int(int, double, bool)> == 3);
125static_assert(rac<int(Lock&, int, double, bool)> == 3);
126 
127// No args — length is 0.
128static_assert(rac<void()> == 0);
129static_assert(rac<void(Lock&)> == 0);
130 
131// Optional args stop the count.
132static_assert(rac<void(int, Optional<int>)> == 1);
133static_assert(rac<void(int, double, Optional<int>)> == 2);
134static_assert(rac<void(Optional<int>)> == 0);
135static_assert(rac<void(Lock&, int, Optional<int>)> == 1);
136 
137// LenientOptional also stops the count.
138static_assert(rac<void(int, LenientOptional<int>)> == 1);
139 
140// TypeHandler<T> is invisible - does not count and does not stop.
141static_assert(rac<void(TypeHandler<int>&, int, double)> == 2);
142static_assert(rac<void(int, TypeHandler<int>&, double)> == 2);
143static_assert(rac<void(int, TypeHandler<int>&, Optional<double>)> == 1);
144// Arguments following optionals are not counted.
145static_assert(rac<void(int, TypeHandler<int>&, Optional<double>, int)> == 1);
146 
147// Arguments<T> is invisible - does not count and does not stop.
148static_assert(rac<void(int, Arguments<int>)> == 1);
149 
150// InjectConfiguration types (e.g. CompatibilityFlags::Reader) are invisible.
151static_assert(rac<void(FakeConfig, int, double)> == 2);
152static_assert(rac<void(int, FakeConfig, double)> == 2);
153static_assert(rac<void(int, FakeConfig, Optional<double>)> == 1);
154 
155// Member functions.
156static_assert(rac<decltype(&Dummy::noMagic)> == 3);
157static_assert(rac<decltype(&Dummy::withLock)> == 2);
158static_assert(rac<decltype(&Dummy::withInfo)> == 1);
159static_assert(rac<decltype(&Dummy::constNoMagic)> == 1);
160static_assert(rac<decltype(&Dummy::constWithLock)> == 2);
161static_assert(rac<decltype(&Dummy::constWithInfo)> == 0);
162 
163// =====================================================================================
164// ValueLessParameter concept tests (type-wrapper.h)
165 
166static_assert(ValueLessParameter<MockTypeWrapper, TypeHandler<int>> == true);
167static_assert(ValueLessParameter<MockTypeWrapper, FakeConfig> == true);
168static_assert(ValueLessParameter<MockTypeWrapper, int> == false);
169static_assert(ValueLessParameter<MockTypeWrapper, Optional<int>> == false);
170static_assert(ValueLessParameter<MockTypeWrapper, kj::String> == false);
171// Arguments<T> is NOT a ValueLessParameter — it has its own handling via isArguments<>().
172static_assert(ValueLessParameter<MockTypeWrapper, Arguments<int>> == false);
173 
174KJ_TEST("web-idl meta") {
175 // Nothing to actually do here; tests are compile-time
176}
177 
178} // namespace
179} // namespace workerd::jsg::test