text: /*
   * @flow
   */
  
  import type Suite from "flow-dev-tools/src/test/Suite.js";
  import {suite, test} from 'flow-dev-tools/src/test/Tester';
  
  export default (suite(({addFile, addFiles, addCode}) => [
    test('X ~> A', [
      // literal A
      addCode('({p: new A}: RWA);').noNewErrors(),
      addCode('({p: new A}: dRWA);').noNewErrors(),
  
      // A
      addCode('(rwA: RWA);').noNewErrors(),
      addCode('(drwA: dRWA);').noNewErrors(),
  
      // +A
      addCode('(roA: RWA);')
        .newErrors(
          `
            test.js:50
             50: (roA: RWA);
                  ^^^ Cannot cast \`roA\` to \`RWA\` because property \`p\` is read-only in \`ROA\` [1] but writable in \`RWA\` [2]. [incompatible-variance]
              References:
               17:     declare var roA: ROA;
                                        ^^^ [1]
               50: (roA: RWA);
                         ^^^ [2]
          `,
        ),
      addCode('(droA: dRWA);')
        .newErrors(
          `
            test.js:52
             52: (droA: dRWA);
                  ^^^^ Cannot cast \`droA\` to \`dRWA\` because an index signature declaring the expected key / value type is read-only in \`dROA\` [1] but writable in \`dRWA\` [2]. [incompatible-variance]
              References:
               34:     declare var droA: dROA;
                                         ^^^^ [1]
               52: (droA: dRWA);
                          ^^^^ [2]
          `,
        ),
  
      // -A
      addCode('(woA: RWA);')
        .newErrors(
          `
            test.js:54
             54: (woA: RWA);
                  ^^^ Cannot cast \`woA\` to \`RWA\` because property \`p\` is write-only in \`WOA\` [1] but readable in \`RWA\` [2]. [incompatible-variance]
              References:
               18:     declare var woA: WOA;
                                        ^^^ [1]
               54: (woA: RWA);
                         ^^^ [2]
          `,
        ),
      addCode('(dwoA: dRWA);')
        .newErrors(
          `
            test.js:56
             56: (dwoA: dRWA);
                  ^^^^ Cannot cast \`dwoA\` to \`dRWA\` because an index signature declaring the expected key / value type is write-only in \`dWOA\` [1] but readable in \`dRWA\` [2]. [incompatible-variance]
              References:
               35:     declare var dwoA: dWOA;
                                         ^^^^ [1]
               56: (dwoA: dRWA);
                          ^^^^ [2]
          `,
        ),
  
  
      // literal B
      addCode('({p: new B}: RWA);').noNewErrors(),
      addCode('({p: new B}: dRWA);').noNewErrors(),
  
      // B
      addCode('(rwB: RWA);')
        .newErrors(
          `
            test.js:62
             62: (rwB: RWA);
                  ^^^ Cannot cast \`rwB\` to \`RWA\` because \`B\` [1] is incompatible with \`A\` [2] in property \`p\`. [incompatible-cast]
              References:
               12:     type RWB = {|p: B|}
                                       ^ [1]
                9:     type RWA = {|p: A|}
                                       ^ [2]
          `,
        ),
      addCode('(drwB: dRWA);')
        .newErrors(
          `
            test.js:64
             64: (drwB: dRWA);
                  ^^^^ Cannot cast \`drwB\` to \`dRWA\` because \`B\` [1] is incompatible with \`A\` [2] in the indexer property. [incompatible-cast]
              References:
               29:     type dRWB = {[string]: B};
                                              ^ [1]
               26:     type dRWA = {[string]: A};
                                              ^ [2]
          `,
        ),
  
      // +B
      addCode('(roB: RWA);')
        .newErrors(
          `
            test.js:66
             66: (roB: RWA);
                  ^^^ Cannot cast \`roB\` to \`RWA\` because property \`p\` is read-only in \`ROB\` [1] but writable in \`RWA\` [2]. [incompatible-variance]
              References:
               21:     declare var roB: ROB;
                                        ^^^ [1]
               66: (roB: RWA);
                         ^^^ [2]
          `,
        ),
      addCode('(droB: dRWA);')
        .newErrors(
          `
            test.js:68
             68: (droB: dRWA);
                  ^^^^ Cannot cast \`droB\` to \`dRWA\` because an index signature declaring the expected key / value type is read-only in \`dROB\` [1] but writable in \`dRWA\` [2]. [incompatible-variance]
              References:
               38:     declare var droB: dROB;
                                         ^^^^ [1]
               68: (droB: dRWA);
                          ^^^^ [2]
          `,
        ),
  
      // -B
      addCode('(woB: RWA);')
        .newErrors(
          `
            test.js:70
             70: (woB: RWA);
                  ^^^ Cannot cast \`woB\` to \`RWA\` because property \`p\` is write-only in \`WOB\` [1] but readable in \`RWA\` [2]. [incompatible-variance]
              References:
               22:     declare var woB: WOB;
                                        ^^^ [1]
               70: (woB: RWA);
                         ^^^ [2]
  
            test.js:70
             70: (woB: RWA);
                  ^^^ Cannot cast \`woB\` to \`RWA\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
                9:     type RWA = {|p: A|}
                                       ^ [1]
               14:     type WOB = {|-p: B|}
                                        ^ [2]
          `,
        ),
      addCode('(dwoB: dRWA);')
        .newErrors(
          `
            test.js:72
             72: (dwoB: dRWA);
                  ^^^^ Cannot cast \`dwoB\` to \`dRWA\` because an index signature declaring the expected key / value type is write-only in \`dWOB\` [1] but readable in \`dRWA\` [2]. [incompatible-variance]
              References:
               39:     declare var dwoB: dWOB;
                                         ^^^^ [1]
               72: (dwoB: dRWA);
                          ^^^^ [2]
  
            test.js:72
             72: (dwoB: dRWA);
                  ^^^^ Cannot cast \`dwoB\` to \`dRWA\` because \`A\` [1] is incompatible with \`B\` [2] in the indexer property. [incompatible-cast]
              References:
               26:     type dRWA = {[string]: A};
                                              ^ [1]
               31:     type dWOB = {-[string]: B};
                                               ^ [2]
          `,
        ),
    ]),
  
    test('X ~> +A', [
      // literal A
      addCode('({p: new A}: ROA);').noNewErrors(),
      addCode('({p: new A}: dROA);').noNewErrors(),
  
      // A
      addCode('(rwA: ROA);').noNewErrors(),
      addCode('(drwA: dROA);').noNewErrors(),
  
      // +A
      addCode('(roA: ROA);').noNewErrors(),
      addCode('(droA: dROA);').noNewErrors(),
  
      // -A
      addCode('(woA: ROA);')
        .newErrors(
          `
            test.js:54
             54: (woA: ROA);
                  ^^^ Cannot cast \`woA\` to \`ROA\` because property \`p\` is write-only in \`WOA\` [1] but read-only in \`ROA\` [2]. [incompatible-variance]
              References:
               18:     declare var woA: WOA;
                                        ^^^ [1]
               54: (woA: ROA);
                         ^^^ [2]
          `,
        ),
      addCode('(dwoA: dROA);')
        .newErrors(
          `
            test.js:56
             56: (dwoA: dROA);
                  ^^^^ Cannot cast \`dwoA\` to \`dROA\` because an index signature declaring the expected key / value type is write-only in \`dWOA\` [1] but read-only in \`dROA\` [2]. [incompatible-variance]
              References:
               35:     declare var dwoA: dWOA;
                                         ^^^^ [1]
               56: (dwoA: dROA);
                          ^^^^ [2]
          `,
        ),
  
      // literal B
      addCode('({p: new B}: ROA);').noNewErrors(),
      addCode('({p: new B}: dROA);').noNewErrors(),
  
      // B
      addCode('(rwB: ROA);').noNewErrors(),
      addCode('(drwB: dROA);').noNewErrors(),
  
      // +B
      addCode('(roB: ROA);').noNewErrors(),
      addCode('(droB: dROA);').noNewErrors(),
  
      // -B
      addCode('(woB: ROA);')
        .newErrors(
          `
            test.js:70
             70: (woB: ROA);
                  ^^^ Cannot cast \`woB\` to \`ROA\` because property \`p\` is write-only in \`WOB\` [1] but read-only in \`ROA\` [2]. [incompatible-variance]
              References:
               22:     declare var woB: WOB;
                                        ^^^ [1]
               70: (woB: ROA);
                         ^^^ [2]
          `,
        ),
      addCode('(dwoB: dROA);')
        .newErrors(
          `
            test.js:72
             72: (dwoB: dROA);
                  ^^^^ Cannot cast \`dwoB\` to \`dROA\` because an index signature declaring the expected key / value type is write-only in \`dWOB\` [1] but read-only in \`dROA\` [2]. [incompatible-variance]
              References:
               39:     declare var dwoB: dWOB;
                                         ^^^^ [1]
               72: (dwoB: dROA);
                          ^^^^ [2]
          `,
        ),
    ]),
  
    test('X ~> -A', [
      // literal A
      addCode('({p: new A}: WOA);').noNewErrors(),
      addCode('({p: new A}: dWOA);').noNewErrors(),
  
      // A
      addCode('(rwA: WOA);').noNewErrors(),
      addCode('(rwA: dWOA);').noNewErrors(),
  
      // +A
      addCode('(roA: WOA);')
        .newErrors(
          `
            test.js:50
             50: (roA: WOA);
                  ^^^ Cannot cast \`roA\` to \`WOA\` because property \`p\` is read-only in \`ROA\` [1] but write-only in \`WOA\` [2]. [incompatible-variance]
              References:
               17:     declare var roA: ROA;
                                        ^^^ [1]
               50: (roA: WOA);
                         ^^^ [2]
          `,
        ),
      addCode('(droA: dWOA);')
        .newErrors(
          `
            test.js:52
             52: (droA: dWOA);
                  ^^^^ Cannot cast \`droA\` to \`dWOA\` because an index signature declaring the expected key / value type is read-only in \`dROA\` [1] but write-only in \`dWOA\` [2]. [incompatible-variance]
              References:
               34:     declare var droA: dROA;
                                         ^^^^ [1]
               52: (droA: dWOA);
                          ^^^^ [2]
          `,
        ),
  
      // -A
      addCode('(woA: WOA);').noNewErrors(),
      addCode('(dwoA: dWOA);').noNewErrors(),
  
      // literal B
      addCode('({p: new B}: WOA);').noNewErrors(),
      addCode('({p: new B}: dWOA);').noNewErrors(),
  
      // B
      addCode('(rwB: WOA);')
        .newErrors(
          `
            test.js:62
             62: (rwB: WOA);
                  ^^^ Cannot cast \`rwB\` to \`WOA\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               11:     type WOA = {|-p: A|}
                                        ^ [1]
               12:     type RWB = {|p: B|}
                                       ^ [2]
          `,
        ),
      addCode('(drwB: dWOA);')
        .newErrors(
          `
            test.js:64
             64: (drwB: dWOA);
                  ^^^^ Cannot cast \`drwB\` to \`dWOA\` because \`A\` [1] is incompatible with \`B\` [2] in the indexer property. [incompatible-cast]
              References:
               28:     type dWOA = {-[string]: A};
                                               ^ [1]
               29:     type dRWB = {[string]: B};
                                              ^ [2]
          `,
        ),
  
      // +B
      addCode('(roB: WOA);')
        .newErrors(
          `
            test.js:66
             66: (roB: WOA);
                  ^^^ Cannot cast \`roB\` to \`WOA\` because property \`p\` is read-only in \`ROB\` [1] but write-only in \`WOA\` [2]. [incompatible-variance]
              References:
               21:     declare var roB: ROB;
                                        ^^^ [1]
               66: (roB: WOA);
                         ^^^ [2]
          `,
        ),
      addCode('(droB: dWOA);')
        .newErrors(
          `
            test.js:68
             68: (droB: dWOA);
                  ^^^^ Cannot cast \`droB\` to \`dWOA\` because an index signature declaring the expected key / value type is read-only in \`dROB\` [1] but write-only in \`dWOA\` [2]. [incompatible-variance]
              References:
               38:     declare var droB: dROB;
                                         ^^^^ [1]
               68: (droB: dWOA);
                          ^^^^ [2]
          `,
        ),
  
      // -B
      addCode('(woB: WOA);')
        .newErrors(
          `
            test.js:70
             70: (woB: WOA);
                  ^^^ Cannot cast \`woB\` to \`WOA\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               11:     type WOA = {|-p: A|}
                                        ^ [1]
               14:     type WOB = {|-p: B|}
                                        ^ [2]
          `,
        ),
      addCode('(dwoB: dWOA);')
        .newErrors(
          `
            test.js:72
             72: (dwoB: dWOA);
                  ^^^^ Cannot cast \`dwoB\` to \`dWOA\` because \`A\` [1] is incompatible with \`B\` [2] in the indexer property. [incompatible-cast]
              References:
               28:     type dWOA = {-[string]: A};
                                               ^ [1]
               31:     type dWOB = {-[string]: B};
                                               ^ [2]
          `,
        ),
    ]),
  
    test('X ~> B', [
      // literal A
      addCode('({p: new A}: RWB);')
        .newErrors(
          `
            test.js:42
             42: ({p: new A}: RWB);
                      ^^^^^ Cannot cast object literal to \`RWB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               42: ({p: new A}: RWB);
                        ^^^^^ [1]
               12:     type RWB = {|p: B|}
                                       ^ [2]
          `,
        ),
      addCode('({p: new A}: dRWB);')
        .newErrors(
          `
            test.js:44
             44: ({p: new A}: dRWB);
                      ^^^^^ Cannot cast object literal to \`dRWB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               44: ({p: new A}: dRWB);
                        ^^^^^ [1]
               29:     type dRWB = {[string]: B};
                                              ^ [2]
          `,
        ),
  
      // A
      addCode('(rwA: RWB);')
        .newErrors(
          `
            test.js:46
             46: (rwA: RWB);
                  ^^^ Cannot cast \`rwA\` to \`RWB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
                9:     type RWA = {|p: A|}
                                       ^ [1]
               12:     type RWB = {|p: B|}
                                       ^ [2]
          `,
        ),
      addCode('(drwA: dRWB);')
        .newErrors(
          `
            test.js:48
             48: (drwA: dRWB);
                  ^^^^ Cannot cast \`drwA\` to \`dRWB\` because \`A\` [1] is incompatible with \`B\` [2] in the indexer property. [incompatible-cast]
              References:
               26:     type dRWA = {[string]: A};
                                              ^ [1]
               29:     type dRWB = {[string]: B};
                                              ^ [2]
          `,
        ),
  
      // +A
      addCode('(roA: RWB);')
        .newErrors(
          `
            test.js:50
             50: (roA: RWB);
                  ^^^ Cannot cast \`roA\` to \`RWB\` because property \`p\` is read-only in \`ROA\` [1] but writable in \`RWB\` [2]. [incompatible-variance]
              References:
               17:     declare var roA: ROA;
                                        ^^^ [1]
               50: (roA: RWB);
                         ^^^ [2]
  
            test.js:50
             50: (roA: RWB);
                  ^^^ Cannot cast \`roA\` to \`RWB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               10:     type ROA = {|+p: A|}
                                        ^ [1]
               12:     type RWB = {|p: B|}
                                       ^ [2]
          `,
        ),
      addCode('(droA: dRWB);')
        .newErrors(
          `
            test.js:52
             52: (droA: dRWB);
                  ^^^^ Cannot cast \`droA\` to \`dRWB\` because an index signature declaring the expected key / value type is read-only in \`dROA\` [1] but writable in \`dRWB\` [2]. [incompatible-variance]
              References:
               34:     declare var droA: dROA;
                                         ^^^^ [1]
               52: (droA: dRWB);
                          ^^^^ [2]
  
            test.js:52
             52: (droA: dRWB);
                  ^^^^ Cannot cast \`droA\` to \`dRWB\` because \`A\` [1] is incompatible with \`B\` [2] in the indexer property. [incompatible-cast]
              References:
               27:     type dROA = {+[string]: A};
                                               ^ [1]
               29:     type dRWB = {[string]: B};
                                              ^ [2]
          `,
        ),
  
      // -A
      addCode('(woA: RWB);')
        .newErrors(
          `
            test.js:54
             54: (woA: RWB);
                  ^^^ Cannot cast \`woA\` to \`RWB\` because property \`p\` is write-only in \`WOA\` [1] but readable in \`RWB\` [2]. [incompatible-variance]
              References:
               18:     declare var woA: WOA;
                                        ^^^ [1]
               54: (woA: RWB);
                         ^^^ [2]
          `,
        ),
      addCode('(dwoA: dRWB);')
        .newErrors(
          `
            test.js:56
             56: (dwoA: dRWB);
                  ^^^^ Cannot cast \`dwoA\` to \`dRWB\` because an index signature declaring the expected key / value type is write-only in \`dWOA\` [1] but readable in \`dRWB\` [2]. [incompatible-variance]
              References:
               35:     declare var dwoA: dWOA;
                                         ^^^^ [1]
               56: (dwoA: dRWB);
                          ^^^^ [2]
          `,
        ),
    ]),
  
    test('X ~> +B', [
      // literal A
      addCode('({p: new A}: ROB);')
        .newErrors(
          `
            test.js:42
             42: ({p: new A}: ROB);
                      ^^^^^ Cannot cast object literal to \`ROB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               42: ({p: new A}: ROB);
                        ^^^^^ [1]
               13:     type ROB = {|+p: B|}
                                        ^ [2]
          `,
        ),
      addCode('({p: new A}: dROB);')
        .newErrors(
          `
            test.js:44
             44: ({p: new A}: dROB);
                      ^^^^^ Cannot cast object literal to \`dROB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               44: ({p: new A}: dROB);
                        ^^^^^ [1]
               30:     type dROB = {+[string]: B};
                                               ^ [2]
          `,
        ),
  
      // A
      addCode('(rwA: ROB);')
        .newErrors(
          `
            test.js:46
             46: (rwA: ROB);
                  ^^^ Cannot cast \`rwA\` to \`ROB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
                9:     type RWA = {|p: A|}
                                       ^ [1]
               13:     type ROB = {|+p: B|}
                                        ^ [2]
          `,
        ),
      addCode('(drwA: dROB);')
        .newErrors(
          `
            test.js:48
             48: (drwA: dROB);
                  ^^^^ Cannot cast \`drwA\` to \`dROB\` because \`A\` [1] is incompatible with \`B\` [2] in the indexer property. [incompatible-cast]
              References:
               26:     type dRWA = {[string]: A};
                                              ^ [1]
               30:     type dROB = {+[string]: B};
                                               ^ [2]
          `,
        ),
  
      // +A
      addCode('(roA: ROB);')
        .newErrors(
          `
            test.js:50
             50: (roA: ROB);
                  ^^^ Cannot cast \`roA\` to \`ROB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
              References:
               10:     type ROA = {|+p: A|}
                                        ^ [1]
               13:     type ROB = {|+p: B|}
                                        ^ [2]
          `,
        ),
      addCode('(droA: dROB);')
        .newErrors(
          `
            test.js:52
             52: (droA: dROB);
                  ^^^^ Cannot cast \`droA\` to \`dROB\` because \`A\` [1] is incompatible with \`B\` [2] in the indexer property. [incompatible-cast]
              References:
               27:     type dROA = {+[string]: A};
                                               ^ [1]
               30:     type dROB = {+[string]: B};
                                               ^ [2]
          `,
        ),
  
      // -A
      addCode('(woA: ROB);')
        .newErrors(
          `
            test.js:54
             54: (woA: ROB);
                  ^^^ Cannot cast \`woA\` to \`ROB\` because property \`p\` is write-only in \`WOA\` [1] but read-only in \`ROB\` [2]. [incompatible-variance]
              References:
               18:     declare var woA: WOA;
                                        ^^^ [1]
               54: (woA: ROB);
                         ^^^ [2]
          `,
        ),
      addCode('(dwoA: dROB);')
        .newErrors(
          `
            test.js:56
             56: (dwoA: dROB);
                  ^^^^ Cannot cast \`dwoA\` to \`dROB\` because an index signature declaring the expected key / value type is write-only in \`dWOA\` [1] but read-only in \`dROB\` [2]. [incompatible-variance]
              References:
               35:     declare var dwoA: dWOA;
                                         ^^^^ [1]
               56: (dwoA: dROB);
                          ^^^^ [2]
          `,
        ),
    ]),
  
    test('X ~> -B', [
      // literal A
      addCode('({p: new A}: WOB);').noNewErrors(),
      addCode('({p: new A}: dWOB);').noNewErrors(),
  
      // A
      addCode('(rwA: WOB);').noNewErrors(),
      addCode('(drwA: dWOB);').noNewErrors(),
  
      // +A
      addCode('(roA: WOB);')
        .newErrors(
          `
            test.js:50
             50: (roA: WOB);
                  ^^^ Cannot cast \`roA\` to \`WOB\` because property \`p\` is read-only in \`ROA\` [1] but write-only in \`WOB\` [2]. [incompatible-variance]
              References:
               17:     declare var roA: ROA;
                                        ^^^ [1]
               50: (roA: WOB);
                         ^^^ [2]
          `,
        ),
      addCode('(droA: dWOB);')
        .newErrors(
          `
            test.js:52
             52: (droA: dWOB);
                  ^^^^ Cannot cast \`droA\` to \`dWOB\` because an index signature declaring the expected key / value type is read-only in \`dROA\` [1] but write-only in \`dWOB\` [2]. [incompatible-variance]
              References:
               34:     declare var droA: dROA;
                                         ^^^^ [1]
               52: (droA: dWOB);
                          ^^^^ [2]
          `,
        ),
  
      // -A
      addCode('(woA: WOB);').noNewErrors(),
      addCode('(dwoA: dWOB);').noNewErrors(),
    ]),
  
    test('unification', [
      // Note: these tests don't reuse the type aliases from the prelude because
      // doing so results in "naive" unification instead of rec_unify.
  
      addCode('(([rwA]: Array<{p:A}>): Array<{p:A}>);')
        .noNewErrors(),
  
      addCode('(([roA]: Array<{+p:A}>): Array<{p:A}>);')
        .newErrors(
          `
            test.js:44
             44: (([roA]: Array<{+p:A}>): Array<{p:A}>);
                                ^^^^^^ Cannot cast array literal to array type because property \`p\` is read-only in object type [1] but writable in object type [2] in array element. [incompatible-variance]
              References:
               44: (([roA]: Array<{+p:A}>): Array<{p:A}>);
                                  ^^^^^^ [1]
               44: (([roA]: Array<{+p:A}>): Array<{p:A}>);
                                                  ^^^^^ [2]
          `,
        ),
  
      addCode('(([woA]: Array<{-p:A}>): Array<{p:A}>);')
        .newErrors(
          `
            test.js:46
             46: (([woA]: Array<{-p:A}>): Array<{p:A}>);
                                ^^^^^^ Cannot cast array literal to array type because property \`p\` is write-only in object type [1] but readable in object type [2] in array element. [incompatible-variance]
              References:
               46: (([woA]: Array<{-p:A}>): Array<{p:A}>);
                                  ^^^^^^ [1]
               46: (([woA]: Array<{-p:A}>): Array<{p:A}>);
                                                  ^^^^^ [2]
          `,
        ),
  
      addCode('(([rwA]: Array<{p:A}>): Array<{+p:A}>);')
        .newErrors(
          `
            test.js:48
             48: (([rwA]: Array<{p:A}>): Array<{+p:A}>);
                                ^^^^^ Cannot cast array literal to array type because property \`p\` is writable in object type [1] but read-only in object type [2] in array element. [incompatible-variance]
              References:
               48: (([rwA]: Array<{p:A}>): Array<{+p:A}>);
                                  ^^^^^ [1]
               48: (([rwA]: Array<{p:A}>): Array<{+p:A}>);
                                                 ^^^^^^ [2]
          `,
        ),
  
      addCode('(([roA]: Array<{+p:A}>): Array<{+p:A}>);')
        .noNewErrors(),
  
      addCode('(([woA]: Array<{-p:A}>): Array<{+p:A}>);')
        .newErrors(
          `
            test.js:52
             52: (([woA]: Array<{-p:A}>): Array<{+p:A}>);
                                ^^^^^^ Cannot cast array literal to array type because property \`p\` is write-only in object type [1] but read-only in object type [2] in array element. [incompatible-variance]
              References:
               52: (([woA]: Array<{-p:A}>): Array<{+p:A}>);
                                  ^^^^^^ [1]
               52: (([woA]: Array<{-p:A}>): Array<{+p:A}>);
                                                  ^^^^^^ [2]
          `,
        ),
  
      addCode('(([rwA]: Array<{p:A}>): Array<{-p:A}>);')
        .newErrors(
          `
            test.js:54
             54: (([rwA]: Array<{p:A}>): Array<{-p:A}>);
                                ^^^^^ Cannot cast array literal to array type because property \`p\` is readable in object type [1] but write-only in object type [2] in array element. [incompatible-variance]
              References:
               54: (([rwA]: Array<{p:A}>): Array<{-p:A}>);
                                  ^^^^^ [1]
               54: (([rwA]: Array<{p:A}>): Array<{-p:A}>);
                                                 ^^^^^^ [2]
          `,
        ),
  
      addCode('(([roA]: Array<{+p:A}>): Array<{-p:A}>);')
        .newErrors(
          `
            test.js:56
             56: (([roA]: Array<{+p:A}>): Array<{-p:A}>);
                                ^^^^^^ Cannot cast array literal to array type because property \`p\` is read-only in object type [1] but write-only in object type [2] in array element. [incompatible-variance]
              References:
               56: (([roA]: Array<{+p:A}>): Array<{-p:A}>);
                                  ^^^^^^ [1]
               56: (([roA]: Array<{+p:A}>): Array<{-p:A}>);
                                                  ^^^^^^ [2]
          `,
        ),
  
      addCode('(([woA]: Array<{-p:A}>): Array<{-p:A}>);')
        .noNewErrors(),
    ]),
  
    test('$Shape', [
      // A ~> A
      addCode('(rwA: $Shape<RWA>);').noNewErrors(),
  
      // +A ~> A
      addCode('(roA: $Shape<RWA>);').noNewErrors(),
  
      // -A ~> A
      addCode('(woA: $Shape<RWA>);').
        newErrors(
         `
           test.js:46
            46: (woA: $Shape<RWA>);
                 ^^^ Cannot cast \`woA\` to \`RWA\` because property \`p\` is not readable. [cannot-read]
         `,
       ),
  
      // B ~> A
      addCode('(rwB: $Shape<RWA>);').noNewErrors(),
  
      // +B ~> A
      addCode('(roB: $Shape<RWA>);').noNewErrors(),
  
      // -B ~> A
      addCode('(woB: $Shape<RWA>);').
        newErrors(
         `
           test.js:52
            52: (woB: $Shape<RWA>);
                 ^^^ Cannot cast \`woB\` to \`RWA\` because property \`p\` is not readable. [cannot-read]
         `,
       ),
  
      // A ~> B
      addCode('(rwA: $Shape<RWB>);').
        newErrors(
         `
           test.js:54
            54: (rwA: $Shape<RWB>);
                 ^^^ Cannot cast \`rwA\` to \`RWB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
             References:
               9:     type RWA = {|p: A|}
                                      ^ [1]
              12:     type RWB = {|p: B|}
                                      ^ [2]
         `,
       ),
  
      // +A ~> B
      addCode('(roA: $Shape<RWB>);').
        newErrors(
         `
           test.js:56
            56: (roA: $Shape<RWB>);
                 ^^^ Cannot cast \`roA\` to \`RWB\` because \`A\` [1] is incompatible with \`B\` [2] in property \`p\`. [incompatible-cast]
             References:
              10:     type ROA = {|+p: A|}
                                       ^ [1]
              12:     type RWB = {|p: B|}
                                      ^ [2]
         `,
       ),
  
      // -A ~> B
      addCode('(woA: $Shape<RWB>);').
        newErrors(
         `
           test.js:58
            58: (woA: $Shape<RWB>);
                 ^^^ Cannot cast \`woA\` to \`RWB\` because property \`p\` is not readable. [cannot-read]
         `,
       ),
    ]),
  
  ]).beforeEach(({addCode}) => [
    addCode(`
      class A {}
      class B extends A {};
  
      // named properties
  
      type RWA = {|p: A|}
      type ROA = {|+p: A|}
      type WOA = {|-p: A|}
      type RWB = {|p: B|}
      type ROB = {|+p: B|}
      type WOB = {|-p: B|}
  
      declare var rwA: RWA;
      declare var roA: ROA;
      declare var woA: WOA;
  
      declare var rwB: RWB;
      declare var roB: ROB;
      declare var woB: WOB;
  
      // dictionaries
  
      type dRWA = {[string]: A};
      type dROA = {+[string]: A};
      type dWOA = {-[string]: A};
      type dRWB = {[string]: B};
      type dROB = {+[string]: B};
      type dWOB = {-[string]: B};
  
      declare var drwA: dRWA;
      declare var droA: dROA;
      declare var dwoA: dWOA;
  
      declare var drwB: dRWB;
      declare var droB: dROB;
      declare var dwoB: dWOB;
    `),
  ]): Suite);
  