[tests] Enum shorthands language tests - context types in ??, cascades, and collection literals for simple identifiers.

Follow up tests from Erik's comment here: https://dart-review.googlesource.com/c/sdk/+/393606/comments/16e214b1_4bbfad8f

This CL adds language tests for enum shorthands used in expressions where the context type is propagated down, for simple identifiers (no selector chains yet).

Once I do make tests for selector chains, I might reorganize the tests, but this will do for now.

Bug: https://github.com/dart-lang/sdk/issues/57038
Change-Id: Id4b6924611559c45817ecada491b6a8f05be3561
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/396703
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
diff --git a/tests/language/enum_shorthands/enum_shorthand_helper.dart b/tests/language/enum_shorthands/enum_shorthand_helper.dart
index c7d5bff..094e116 100644
--- a/tests/language/enum_shorthands/enum_shorthand_helper.dart
+++ b/tests/language/enum_shorthands/enum_shorthand_helper.dart
@@ -6,10 +6,11 @@
 
 // SharedOptions=--enable-experiment=enum-shorthands
 
-enum Color { blue, red, green }
+enum Color { red, green, blue }
 
 class Integer {
   static Integer get one => Integer(1);
+  static Integer get two => Integer(2);
   static const Integer constOne = const Integer._(1);
   static const Integer constTwo = const Integer._(2);
   final int integer;
@@ -19,18 +20,20 @@
 
 extension type IntegerExt(int integer) {
   static IntegerExt get one => IntegerExt(1);
+  static IntegerExt get two => IntegerExt(2);
   static const IntegerExt constOne = const IntegerExt._(1);
   static const IntegerExt constTwo = const IntegerExt._(2);
   const IntegerExt._(this.integer);
 }
 
 mixin IntegerMixin on Integer {
-  static IntegerMixin get mixinOne => IntegerWithMixin(1);
-  static const IntegerMixin mixinConstOne = const IntegerWithMixin._(1);
-  static const IntegerMixin mixinConstTwo = const IntegerWithMixin._(2);
+  static IntegerMixin get mixinOne => _IntegerWithMixin(1);
+  static IntegerMixin get mixinTwo => _IntegerWithMixin(2);
+  static const IntegerMixin mixinConstOne = const _IntegerWithMixin._(1);
+  static const IntegerMixin mixinConstTwo = const _IntegerWithMixin._(2);
 }
 
-class IntegerWithMixin extends Integer with IntegerMixin {
-  const IntegerWithMixin(int integer) : this._(integer);
-  const IntegerWithMixin._(super.integer) : super._();
+class _IntegerWithMixin extends Integer with IntegerMixin {
+  const _IntegerWithMixin(int integer) : this._(integer);
+  const _IntegerWithMixin._(super.integer) : super._();
 }
diff --git a/tests/language/enum_shorthands/simple/simple_identifier_cascade_test.dart b/tests/language/enum_shorthands/simple/simple_identifier_cascade_test.dart
new file mode 100644
index 0000000..47bb2cf
--- /dev/null
+++ b/tests/language/enum_shorthands/simple/simple_identifier_cascade_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2024, 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.
+
+// Context type is propagated down in cascades.
+
+// SharedOptions=--enable-experiment=enum-shorthands
+
+import '../enum_shorthand_helper.dart';
+
+class Cascade {
+  late Color color;
+  late Integer integer;
+  late IntegerExt integerExt;
+  late IntegerMixin integerMixin;
+}
+
+class CascadeCollection {
+  late List<Color> colorList;
+  late Set<Color> colorSet;
+  late Map<Color, Color> colorMap;
+  late Map<Color, (Color, Color)> colorMap2;
+
+  late List<Integer> integerList;
+  late Set<Integer> integerSet;
+  late Map<Integer, Integer> integerMap;
+  late Map<Integer, (Integer, Integer)> integerMap2;
+
+  late List<IntegerExt> integerExtList;
+  late Set<IntegerExt> integerExtSet;
+  late Map<IntegerExt, IntegerExt> integerExtMap;
+  late Map<IntegerExt, (IntegerExt, IntegerExt)> integerExtMap2;
+
+  late List<IntegerMixin> integerMixinList;
+  late Set<IntegerMixin> integerMixinSet;
+  late Map<IntegerMixin, IntegerMixin> integerMixinMap;
+  late Map<IntegerMixin, (IntegerMixin, IntegerMixin)> integerMixinMap2;
+}
+
+class CascadeMethod {
+  void color(Color color) => print(color);
+  void integer(Integer integer) => print(integer);
+  void integerExt(IntegerExt integer) => print(integer);
+  void integerMixin(IntegerMixin integer) => print(integer);
+}
+
+void main() {
+  Cascade()
+    ..color = .red
+    ..integer = .one
+    ..integerExt = .one
+    ..integerMixin = .mixinOne;
+
+  dynamic mayBeNull = null;
+  Cascade()
+    ..color = mayBeNull ?? .red
+    ..integer = mayBeNull ?? .one
+    ..integerExt = mayBeNull ?? .one
+    ..integerMixin = mayBeNull ?? .mixinOne;
+
+  CascadeCollection()
+    // Enum
+    ..colorList = [.blue, .green, .red]
+    ..colorSet = {.blue, .red}
+    ..colorMap = {.blue: .blue, .green: .red}
+    ..colorMap2 = {.red: (.blue, .green)}
+    // Class
+    ..integerList = [.one, .two, .one]
+    ..integerSet = {.one, .two}
+    ..integerMap = {.one: .two, .two: .two}
+    ..integerMap2 = {
+      .one: (.one, .two),
+      .two: (.two, .two),
+    }
+    // Extension type
+    ..integerExtList = [.one, .two, .one]
+    ..integerExtSet = {.one, .two}
+    ..integerExtMap = {
+      .one: .two,
+      .two: .two,
+    }
+    ..integerExtMap2 = {
+      .one: (.one, .two),
+      .two: (.two, .two),
+    }
+    // Mixin
+    ..integerMixinList = [
+      .mixinOne,
+      .mixinTwo,
+      .mixinOne,
+    ]
+    ..integerMixinSet = {.mixinOne, .mixinTwo}
+    ..integerMixinMap = {
+      .mixinOne: .mixinTwo,
+      .mixinTwo: .mixinTwo,
+    }
+    ..integerMixinMap2 = {
+      .mixinOne: (.mixinOne, .mixinTwo),
+      .mixinTwo: (.mixinTwo, .mixinTwo),
+    };
+
+  CascadeMethod()
+    ..color(.red)
+    ..integer(.one)
+    ..integerExt(.one)
+    ..integerMixin(.mixinOne);
+
+  Color color = .blue..toString();
+  Integer integer = .one..toString();
+  IntegerExt integerExt = .one..toString();
+  IntegerMixin integerMixin = .mixinOne..toString();
+}
diff --git a/tests/language/enum_shorthands/simple/simple_identifier_collection_literal_test.dart b/tests/language/enum_shorthands/simple/simple_identifier_collection_literal_test.dart
new file mode 100644
index 0000000..9971973
--- /dev/null
+++ b/tests/language/enum_shorthands/simple/simple_identifier_collection_literal_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2024, 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.
+
+// Context type is propagated down in collection literals.
+
+// SharedOptions=--enable-experiment=enum-shorthands
+
+import '../enum_shorthand_helper.dart';
+
+void main() {
+  // Enum
+  var colorList = <Color>[.blue, .green, .red];
+  var colorSet = <Color>{.blue, .red};
+  var colorMap = <Color, Color>{.blue: .blue, .green: .red};
+  var colorMap2 = <Color, (Color, Color)>{.red: (.blue, .green)};
+
+  // Class
+  var integerList = <Integer>[.one, .two, .one];
+  var integerSet = <Integer>{.one, .two};
+  var integerMap = <Integer, Integer>{
+    .one: .two,
+    .two: .two,
+  };
+  var integerMap2 = <Integer, (Integer, Integer)>{
+    .one: (.one, .two),
+    .two: (.two, .two),
+  };
+
+  // Extension type
+  var integerExtList = <IntegerExt>[
+    .one,
+    .two,
+    .one,
+  ];
+  var integerExtSet = <IntegerExt>{.one, .two};
+  var integerExtMap = <IntegerExt, IntegerExt>{
+    .one: .two,
+    .two: .two,
+  };
+  var integerExtMap2 = <IntegerExt, (IntegerExt, IntegerExt)>{
+    .one: (.one, .two),
+    .two: (.two, .two),
+  };
+
+  // Mixin
+  var integerMixinList = <IntegerMixin>[
+    .mixinOne,
+    .mixinTwo,
+    .mixinOne,
+  ];
+  var integerMixinSet = <IntegerMixin>{
+    .mixinOne,
+    .mixinTwo,
+  };
+  var integerMixinMap = <IntegerMixin, IntegerMixin>{
+    .mixinOne: .mixinTwo,
+    .mixinTwo: .mixinTwo,
+  };
+  var integerMixinMap2 = <IntegerMixin, (IntegerMixin, IntegerMixin)>{
+    .mixinOne: (.mixinOne, .mixinTwo),
+    .mixinTwo: (.mixinTwo, .mixinTwo),
+  };
+}
diff --git a/tests/language/enum_shorthands/simple/simple_identifier_if_null_test.dart b/tests/language/enum_shorthands/simple/simple_identifier_if_null_test.dart
new file mode 100644
index 0000000..db28813
--- /dev/null
+++ b/tests/language/enum_shorthands/simple/simple_identifier_if_null_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2024, 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.
+
+// Context type is propagated down in an if-null `??` expression.
+
+// SharedOptions=--enable-experiment=enum-shorthands
+
+import '../enum_shorthand_helper.dart';
+import 'package:expect/expect.dart';
+
+Color colorTest(Color? color) => color ?? .blue;
+
+Integer integerTest(Integer? integer) => integer ?? .one;
+
+IntegerExt integerExtTest(IntegerExt? integer) => integer ?? .one;
+
+IntegerMixin integerMixinTest(IntegerMixin? integer) =>
+    integer ?? .mixinOne;
+
+void main() {
+  // Enum
+  Expect.equals(colorTest(null), Color.blue);
+  Expect.equals(colorTest(Color.red), Color.red);
+
+  // Class
+  Expect.equals(integerTest(null), Integer.one);
+  Expect.equals(integerTest(Integer.two), Integer.two);
+
+  // Extension type
+  Expect.equals(integerExtTest(null), IntegerExt.one);
+  Expect.equals(integerExtTest(IntegerExt.two), IntegerExt.two);
+
+  // Mixin
+  Expect.equals(integerMixinTest(null), IntegerMixin.mixinOne);
+  Expect.equals(integerMixinTest(IntegerMixin.mixinTwo), IntegerMixin.mixinTwo);
+}