#993. More tests for Union added
diff --git a/LibTest/ffi/Struct/Struct_A01_t06.dart b/LibTest/ffi/Struct/Struct_A01_t06.dart
new file mode 100644
index 0000000..ee1671b
--- /dev/null
+++ b/LibTest/ffi/Struct/Struct_A01_t06.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Struct subclass declaration must
+/// either have type int or double and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer or subtype of Struct.
+///
+/// @description Checks that it is a compile error if any of the field in Struct
+/// subclass is not 'int', 'double' or 'Pointer' or subtype of 'Struct'. Test
+/// field of 'Union' and 'Struct' subclass type
+/// @author sgrekhov@unipro.ru
+/// @issue 46194
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+class U extends Union {
+  @Int32()
+  external int x;
+}
+
+class S extends Struct {
+  @Int32()
+  external int y;
+}
+
+class S1 extends Struct {
+  @Int8()
+  external int i;
+
+  external S s;
+
+  external U u;
+}
+
+void main() {
+  Pointer<S1> p = calloc<S1>();
+  S1 s1 = p.ref;
+  s1.u.x = 42;
+  print(s1.u.x);
+  s1.s.y = -42;
+  print(s1.s.y);
+}
diff --git a/LibTest/ffi/Union/Union_A01_t06.dart b/LibTest/ffi/Union/Union_A01_t06.dart
new file mode 100644
index 0000000..d21cffc
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A01_t06.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that it is a compile error if any of the field in Struct
+/// subclass is not 'int', 'double' or 'Pointer'. Test
+/// field of 'Union' and 'Struct' subclass type
+/// @author sgrekhov@unipro.ru
+/// @issue 46194
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+
+class U extends Union {
+  @Int32()
+  external int x;
+}
+
+class S extends Struct {
+  @Int32()
+  external int y;
+}
+
+class U1 extends Union {
+  @Int8()
+  external int i;
+
+  external S s;
+
+  external U u;
+}
+
+void main() {
+  Pointer<U1> p = calloc<U1>();
+  U1 u1 = p.ref;
+  u1.u.x = 42;
+  print(u1.u.x);
+  u1.s.y = -42;
+  print(u1.s.y);
+}
diff --git a/LibTest/ffi/Union/Union_A05_t01.dart b/LibTest/ffi/Union/Union_A05_t01.dart
new file mode 100644
index 0000000..49b88a7
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t01.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Int64()
+  external int x;
+}
+
+class U2 extends Union {
+  @Int32()
+  external int x;
+}
+
+class U3 extends Union {
+  @Uint32()
+  external int x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 0x1111111122222222;
+    Expect.equals(0x1111111122222222, u1.ref.x);
+
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.equals(0x22222222, u2.ref.x);
+    Expect.equals(0x11111111, u2.elementAt(1).ref.x);
+
+    Pointer<U3> u3 = new Pointer.fromAddress(u1.address);
+    Expect.equals(0x22222222, u3.ref.x);
+    Expect.equals(0x11111111, u3.elementAt(1).ref.x);
+
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+    Expect.equals(-1, u2.ref.x);
+    Expect.equals(4294967295, u3.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A05_t02.dart b/LibTest/ffi/Union/Union_A05_t02.dart
new file mode 100644
index 0000000..6bc81d6
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t02.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Int64()
+  external int x;
+}
+
+class U2 extends Union {
+  @Int16()
+  external int x;
+}
+
+class U3 extends Union {
+  @Uint16()
+  external int x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 0x1111222233334444;
+    Expect.equals(0x1111222233334444, u1.ref.x);
+
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.equals(0x4444, u2.ref.x);
+    Expect.equals(0x3333, u2.elementAt(1).ref.x);
+    Expect.equals(0x2222, u2.elementAt(2).ref.x);
+    Expect.equals(0x1111, u2.elementAt(3).ref.x);
+
+    Pointer<U3> u3 = new Pointer.fromAddress(u1.address);
+    Expect.equals(0x4444, u3.ref.x);
+    Expect.equals(0x3333, u3.elementAt(1).ref.x);
+    Expect.equals(0x2222, u3.elementAt(2).ref.x);
+    Expect.equals(0x1111, u3.elementAt(3).ref.x);
+
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+    Expect.equals(-1, u2.ref.x);
+    Expect.equals(65535, u3.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A05_t03.dart b/LibTest/ffi/Union/Union_A05_t03.dart
new file mode 100644
index 0000000..7275ce8
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t03.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Int64()
+  external int x;
+}
+
+class U2 extends Union {
+  @Int8()
+  external int x;
+}
+
+class U3 extends Union {
+  @Uint8()
+  external int x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 0x1122334455667712;
+    Expect.equals(0x1122334455667712, u1.ref.x);
+
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.equals(0x12, u2.ref.x);
+    Expect.equals(0x77, u2.elementAt(1).ref.x);
+    Expect.equals(0x66, u2.elementAt(2).ref.x);
+    Expect.equals(0x55, u2.elementAt(3).ref.x);
+    Expect.equals(0x44, u2.elementAt(4).ref.x);
+    Expect.equals(0x33, u2.elementAt(5).ref.x);
+    Expect.equals(0x22, u2.elementAt(6).ref.x);
+    Expect.equals(0x11, u2.elementAt(7).ref.x);
+
+    Pointer<U3> u3 = new Pointer.fromAddress(u1.address);
+    Expect.equals(0x12, u3.ref.x);
+    Expect.equals(0x77, u3.elementAt(1).ref.x);
+    Expect.equals(0x66, u3.elementAt(2).ref.x);
+    Expect.equals(0x55, u3.elementAt(3).ref.x);
+    Expect.equals(0x44, u3.elementAt(4).ref.x);
+    Expect.equals(0x33, u3.elementAt(5).ref.x);
+    Expect.equals(0x22, u3.elementAt(6).ref.x);
+    Expect.equals(0x11, u3.elementAt(7).ref.x);
+
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+    Expect.equals(-1, u2.ref.x);
+    Expect.equals(255, u3.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A05_t04.dart b/LibTest/ffi/Union/Union_A05_t04.dart
new file mode 100644
index 0000000..bddd32b
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t04.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Int64()
+  external int x;
+}
+
+class U2 extends Union {
+  @Uint64()
+  external int x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+    Expect.equals(0xFFFFFFFFFFFFFFFF, u1.ref.x);
+
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.equals(0xFFFFFFFFFFFFFFFF, u2.ref.x);
+
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+    Expect.equals(-1, u1.ref.x);
+    Expect.equals(-1, u2.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A05_t05.dart b/LibTest/ffi/Union/Union_A05_t05.dart
new file mode 100644
index 0000000..c633a00
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t05.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Uint64()
+  external int x;
+}
+
+class U2 extends Union {
+  @Int32()
+  external int x;
+}
+
+class U3 extends Union {
+  @Uint32()
+  external int x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.equals(-1, u2.ref.x);
+
+    Pointer<U3> u3 = new Pointer.fromAddress(u1.address);
+    Expect.equals(4294967295, u3.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A05_t06.dart b/LibTest/ffi/Union/Union_A05_t06.dart
new file mode 100644
index 0000000..baa6540
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t06.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Uint64()
+  external int x;
+}
+
+class U2 extends Union {
+  @Int16()
+  external int x;
+}
+
+class U3 extends Union {
+  @Uint16()
+  external int x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.equals(-1, u2.ref.x);
+
+    Pointer<U3> u3 = new Pointer.fromAddress(u1.address);
+    Expect.equals(65535, u3.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A05_t07.dart b/LibTest/ffi/Union/Union_A05_t07.dart
new file mode 100644
index 0000000..98d0f2a
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t07.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Uint64()
+  external int x;
+}
+
+class U2 extends Union {
+  @Int8()
+  external int x;
+}
+
+class U3 extends Union {
+  @Uint8()
+  external int x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 0xFFFFFFFFFFFFFFFF;
+
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.equals(-1, u2.ref.x);
+
+    Pointer<U3> u3 = new Pointer.fromAddress(u1.address);
+    Expect.equals(255, u3.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A05_t08.dart b/LibTest/ffi/Union/Union_A05_t08.dart
new file mode 100644
index 0000000..8b35bc8
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A05_t08.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion All field declarations in a Union subclass declaration must
+/// either have type int or float and be annotated with a NativeType
+/// representing the native type, or must be of type Pointer.
+///
+/// @description Checks that 'Union' subtype value depends on annotation
+/// @author sgrekhov@unipro.ru
+
+import "dart:ffi";
+import "package:ffi/ffi.dart";
+import "../../../Utils/expect.dart";
+
+class U1 extends Union {
+  @Double()
+  external double x;
+}
+
+class U2 extends Union {
+  @Float()
+  external double x;
+}
+
+void main() {
+  Pointer<U1> u1 = calloc<U1>();
+  try {
+    u1.ref.x = 3.14;
+    Pointer<U2> u2 = new Pointer.fromAddress(u1.address);
+    Expect.notEquals(3.14, u2.ref.x);
+
+    u2.ref.x = 3.14;
+    Expect.notEquals(3.14, u1.ref.x);
+  } finally {
+    calloc.free(u1);
+  }
+}
diff --git a/LibTest/ffi/Union/Union_A06_t01.dart b/LibTest/ffi/Union/Union_A06_t01.dart
new file mode 100644
index 0000000..513c80f
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A06_t01.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion Union subclasses cannot be empty
+///
+/// @description Checks that it is a compile error if Union subclass is empty
+/// @author sgrekhov@unipro.ru
+/// @issue 44935
+/// @issue 46199
+
+import "dart:ffi";
+
+  class U1 extends Union {
+//^^^^^^^^^^^^^^^^^^^^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+  }
+
+void main() {
+  U1? u1;
+}
diff --git a/LibTest/ffi/Union/Union_A07_t01.dart b/LibTest/ffi/Union/Union_A07_t01.dart
new file mode 100644
index 0000000..44d8de5
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A07_t01.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion Union cannot be implemented or used as a mixin
+///
+/// @description Checks that it is a compile error if Union is implemented
+/// @author sgrekhov@unipro.ru
+/// @issue 44935
+
+import "dart:ffi";
+
+class U1 implements Union {
+//                  ^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+void main() {
+  U1? u1;
+}
diff --git a/LibTest/ffi/Union/Union_A07_t02.dart b/LibTest/ffi/Union/Union_A07_t02.dart
new file mode 100644
index 0000000..0ec89da
--- /dev/null
+++ b/LibTest/ffi/Union/Union_A07_t02.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2021, 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.
+
+/// @assertion Union cannot be implemented or used as a mixin
+///
+/// @description Checks that it is a compile error if Union is used as a mixin
+/// @author sgrekhov@unipro.ru
+/// @issue 44935
+
+import "dart:ffi";
+
+class U1 extends Object with Union {
+//                           ^^^^^
+// [analyzer] unspecified
+// [cfe] unspecified
+}
+
+void main() {
+  U1? u1;
+}