Skip to content

Commit

Permalink
[package:js] Add test for is checks and as casts
Browse files Browse the repository at this point in the history
Adds tests for type checks and casts using JS classes and object
literals. Checks typing between different classes, same classes,
object literals, subtypes, and dynamic conversions.

Change-Id: I01c384395f0e6c8d671ac9bd0dc6e6905845a760
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152990
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
  • Loading branch information
srujzs authored and commit-bot@chromium.org committed Jul 10, 2020
1 parent b91ff15 commit 0e25306
Showing 1 changed file with 122 additions and 0 deletions.
122 changes: 122 additions & 0 deletions tests/lib/js/is_check_and_as_cast_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Tests `is` checks and `as` casts between various JS objects. Currently, all
// checks and casts should be allowed between JS objects.

@JS()
library is_check_and_as_cast_test;

import 'package:js/js.dart';
import 'package:expect/minitest.dart';

@JS()
external void eval(String code);

@JS()
class Foo {
external Foo(int a);
external int get a;
}

// Class with same structure as Foo but separate JS class.
@JS()
class Bar {
external Bar(int a);
external int get a;
}

@JS('Bar')
class BarCopy {
external BarCopy(int a);
external int get a;
}

@JS()
class Baz {
external Baz(int a, int b);
external int get a;
external int get b;
}

// JS object literals
@JS()
@anonymous
class LiteralA {
external int get x;
}

@JS()
@anonymous
class LiteralB {
external int get y;
}

// Library is annotated with JS so we don't need the annotation here.
external LiteralA get a;
external LiteralB get b;

void main() {
eval(r"""
function Foo(a) {
this.a = a;
}
function Bar(a) {
this.a = a;
}
function Baz(a, b) {
Foo.call(this, a);
this.b = b;
}
Baz.prototype.__proto__ = Foo.prototype;
var a = {
x: 1,
};
var b = {
y: 2,
};
""");

// JS class object can be checked and casted with itself.
var foo = Foo(42);
expect(foo is Foo, isTrue);
expect(() => (foo as Foo), returnsNormally);

// Try it with dynamic.
dynamic d = Foo(42);
expect(d is Foo, isTrue);
expect(() => (d as Foo), returnsNormally);

// Casts are allowed between any JS class objects.
expect(foo is Bar, isTrue);
expect(d is Bar, isTrue);
expect(() => (foo as Bar), returnsNormally);
expect(() => (d as Bar), returnsNormally);

// Type-checking and casting works regardless of the inheritance chain.
var baz = Baz(42, 43);
expect(baz is Foo, isTrue);
expect(() => (baz as Foo), returnsNormally);
expect(foo is Baz, isTrue);
expect(() => (foo as Baz), returnsNormally);

// BarCopy is the same JS class as Bar.
var barCopy = BarCopy(42);
expect(barCopy is Bar, isTrue);
expect(() => (barCopy as Bar), returnsNormally);

// JS object literal can be checked and casted with itself.
expect(a is LiteralA, isTrue);
expect(() => (a as LiteralA), returnsNormally);

// Like class objects, casts are allowed between any object literals.
expect(a is LiteralB, isTrue);
expect(() => (a as LiteralB), returnsNormally);

// Similarly, casts are allowed between any class objects and object literals.
expect(foo is LiteralB, isTrue);
expect(() => (foo as LiteralB), returnsNormally);
expect(a is Foo, isTrue);
expect(() => (a as Foo), returnsNormally);
}

0 comments on commit 0e25306

Please sign in to comment.