Skip to content

Commit d609e0c

Browse files
Add regression tests for jsifying props containing frozen objects
1 parent 020a1a7 commit d609e0c

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

test/react_client/js_interop_helpers_test.dart

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ class Foo {
5050
external num bar();
5151
}
5252

53+
@JS()
54+
external dynamic createArray();
55+
5356
main() {
5457
group('jsifyAndAllowInterop', () {
5558
test('converts a List', () {
@@ -131,5 +134,82 @@ main() {
131134
expect(objectKeys(convertedNestedJsObject), expectedProperties,
132135
reason: 'JS object should not have any additional properties');
133136
});
137+
138+
group('works as expected when the map contains frozen objects:', () {
139+
test('anonymous object', () {
140+
final frozenAnonymousObject = jsify({'foo': 'bar'});
141+
expect(_getPrototypeOf(frozenAnonymousObject), _objectPrototype,
142+
reason: 'test setup check; should not extend from another JS type');
143+
144+
_freeze(frozenAnonymousObject);
145+
expect(_isFrozen(frozenAnonymousObject), isTrue, reason: 'test setup check; should have frozen');
146+
147+
dynamic jsObject;
148+
expect(() {
149+
jsObject = jsifyAndAllowInterop({
150+
'frozenObject': frozenAnonymousObject,
151+
});
152+
}, returnsNormally, reason: 'should not throw when it encounters a frozen object');
153+
final convertedNestedFrozenObject = getProperty(jsObject, 'frozenObject');
154+
expect(convertedNestedFrozenObject, same(frozenAnonymousObject),
155+
reason: 'JS object should have just gotten passed through');
156+
});
157+
158+
test('non-anonymous object', () {
159+
final frozenNonAnynymousObject = Foo(21);
160+
expect(_getPrototypeOf(frozenNonAnynymousObject), isNot(_objectPrototype),
161+
reason: 'test setup check; should extend from another JS type');
162+
163+
_freeze(frozenNonAnynymousObject);
164+
expect(_isFrozen(frozenNonAnynymousObject), isTrue, reason: 'test setup check; should have frozen');
165+
166+
dynamic jsObject;
167+
expect(() {
168+
jsObject = jsifyAndAllowInterop({
169+
'frozenObject': frozenNonAnynymousObject,
170+
});
171+
}, returnsNormally, reason: 'should not throw when it encounters a frozen object');
172+
final convertedNestedFrozenObject = getProperty(jsObject, 'frozenObject');
173+
expect(convertedNestedFrozenObject, same(frozenNonAnynymousObject),
174+
reason: 'JS object should have just gotten passed through');
175+
});
176+
177+
test('array object constructed in JS', () {
178+
// Create this and freeze it on the JS side so that we're not starting out with Dart's list implementation
179+
// and potentially any wrapper classes.
180+
final frozenArray = createArray();
181+
expect(_getPrototypeOf(frozenArray), _arrayPrototype, reason: 'test setup check; should be an array');
182+
183+
_freeze(frozenArray);
184+
expect(_isFrozen(frozenArray), isTrue, reason: 'test setup check; should have frozen');
185+
186+
dynamic jsObject;
187+
expect(() {
188+
jsObject = jsifyAndAllowInterop({
189+
'frozenArray': frozenArray,
190+
});
191+
}, returnsNormally, reason: 'should not throw when it encounters a frozen object');
192+
final convertedNestedFrozenObject = getProperty(jsObject, 'frozenArray');
193+
// Note that we don't expect it to be `same(frozenArray)` since the array passes the `is Iterable` check,
194+
// and thus gets processed in _convertDataTree.
195+
expect(convertedNestedFrozenObject, equals(frozenArray),
196+
reason: 'JS object should have been converted properly passed through');
197+
});
198+
});
134199
});
135200
}
201+
202+
@JS('Object.prototype')
203+
external dynamic get _objectPrototype;
204+
205+
@JS('Array.prototype')
206+
external dynamic get _arrayPrototype;
207+
208+
@JS('Object.freeze')
209+
external void _freeze(Object object);
210+
211+
@JS('Object.isFrozen')
212+
external bool _isFrozen(Object object);
213+
214+
@JS('Object.getPrototypeOf')
215+
external dynamic _getPrototypeOf(Object object);

test/react_client/js_interop_helpers_test.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
else
2121
return false;
2222
}
23+
24+
function createArray() {
25+
return [1, 2, 3];
26+
}
2327
</script>
2428

2529
<link rel="x-dart-test" href="js_interop_helpers_test.dart">

0 commit comments

Comments
 (0)