text: /*
   * @flow
   * @lint-ignore-every LINEWRAP1
   */
  
  
  import {suite, test} from '../../tsrc/test/Tester';
  
  export default suite(({addFile, addFiles, addCode}) => [
    test('@csx and @jsx pragma are mutually exclusive', [
      addCode(`
        // @jsx Foo
        // @csx
      `)
        .newErrors(
          `
            test.js:5
              5: // @csx
                    ^^^^ Unexpected @jsx declaration. Only one per file is allowed.
          `,
        ),
    ]),
    test('Should raise an error if JSX references an identifier not in scope', [
      addCode(`
        // @csx
        <Bar x={23} />;
      `)
      .newErrors(
        `
          test.js:5
            5:       <Bar x={23} />;
                      ^^^ Bar. Could not resolve name
        `,
      ),
    ]),
    test('Should raise no errors if JSX references a function with correct types', [
      addCode(`
        // @csx
        type Props = {|x: number|};
        function Bar(props: Props) {}
        <Bar x={23} />;
        <Bar x={23}></Bar>;
      `)
      .noNewErrors(),
    ]),
    test('Should raise no errors if JSX uses a string literal attribute value', [
      addCode(`
        // @csx
        type Props = {|x: string|};
        function Bar(props: Props) {}
        <Bar x="23" />;
      `)
      .noNewErrors(),
    ]),
    test('Should raise an error referencing JSX element if types mismatch', [
      addCode(`
        // @csx
        type Props = {|x: string|};
        function Bar(props: Props) {}
        <Bar x={23} />;
      `)
      .newErrors(
        `
          test.js:7
            7:       <Bar x={23} />;
                     ^^^^^^^^^^^^^^ props. This type is incompatible with the expected param type of
            6:       function Bar(props: Props) {}
                                         ^^^^^ Props
            Property \`x\` is incompatible:
                7:       <Bar x={23} />;
                                 ^^ number. This type is incompatible with
                5:       type Props = {|x: string|};
                                           ^^^^^^ string
        `,
      ),
    ]),
    test('Should raise no errors if a JSX spread provides all required attributes for an inexact type', [
      addCode(`
        // @csx
        type Props = {x: string};
        function Bar(props: Props) {}
        const params = {x: '23'};
        <Bar {...params} />;
      `)
      .noNewErrors(),
    ]),
    test('Should raise no errors if CSX children are passed as spread with list inline', [
      addCode(`
        // @csx
        type Props = {|children: Array<string>|};
        function Foo(props: Props) {}
        <Foo>{...["foo", "bar"]}</Foo>;
      `)
      .noNewErrors(),
    ]),
    test('Should raise no errors if CSX children are passed as spread with variable', [
      addCode(`
        // @csx
        type Props = {|children: Array<string>|};
        function Foo(props: Props) {}
        const arr = ["foo", "bar"];
        <Foo>{...arr}</Foo>;
      `)
      .noNewErrors(),
    ]),
    test('Should raise an error if CSX spread children are not a list', [
      addCode(`
        // @csx
        type Props = {|children: Array<number>|};
        function Foo(props: Props) {}
        const x = 42;
        <Foo>{...x}</Foo>;
      `)
      .newErrors(
        `
          test.js:8
            8:       <Foo>{...x}</Foo>;
                              ^ number. This type is incompatible with
            8:       <Foo>{...x}</Foo>;
                              ^ $Iterable
            Property \`@@iterator\` is incompatible:
                8:       <Foo>{...x}</Foo>;
                                  ^ property \`@@iterator\` of \`$Iterable\`. Property not found in
                8:       <Foo>{...x}</Foo>;
                                  ^ number
        `,
      )
    ]),
    test('Should raise an error if CSX children passed as spread have the wrong type', [
      addCode(`
        // @csx
        type Props = {|children: Array<number>|};
        function Foo(props: Props) {}
        const arr = ["foo"];
        <Foo>{...arr}</Foo>;
      `)
      .newErrors(
        `
          test.js:8
            8:       <Foo>{...arr}</Foo>;
                     ^^^^^ props. This type is incompatible with the expected param type of
            6:       function Foo(props: Props) {}
                                         ^^^^^ Props
            Property \`children\` is incompatible:
                8:       <Foo>{...arr}</Foo>;
                         ^^^^^ JSX element \`Foo\`. Has some incompatible type argument with
                5:       type Props = {|children: Array<number>|};
                                                  ^^^^^^^^^^^^^ array type
                Type argument \`T\` is incompatible:
                    7:       const arr = ["foo"];
                                          ^^^^^ string. This type is incompatible with
                    5:       type Props = {|children: Array<number>|};
                                                            ^^^^^^ number
        `,
      ),
    ]),
    test('Should raise no errors if CSX children are passed as spread with function call', [
      addCode(`
        // @csx
        type Props = {|children: Array<number>|};
        type TProps = {|text: string|};
        function Foo(props: Props) {}
        function Title(props: TProps) { return 42; }
        function get_titles(l) {
          return [];
        }
        var arr = ["foo", "bar"];
        <Foo>{...get_titles(arr)}</Foo>;
      `)
      .noNewErrors(),
    ]),
    test('Should raise no errors if CSX children are passed as spread with other children', [
      addCode(`
        // @csx
        type Props = {|children: Array<string>|};
        function Foo(props: Props) {}
        <Foo>
        {"foobar"}
        {...["foo", "bar"]}
        {"baz"}
        </Foo>;
      `)
      .noNewErrors(),
    ]),
    test('Should raise no errors if a JSX spread provides all required attributes for an exact type', [
      addCode(`
        // @csx
        type Props = {|x: string|};
        function Bar(props: Props) {}
        const params = {x: '23'};
        <Bar {...params} />;
      `)
      .newErrors(
        `
          test.js:8
            8:       <Bar {...params} />;
                     ^^^^^^^^^^^^^^^^^^^ props. Inexact type is incompatible with exact type
            6:       function Bar(props: Props) {}
                                         ^^^^^ Props
        `,
      ),
    ]),
    test('Should raise no errors if two separate JSX spreads together provide all required attributes', [
      addCode(`
        // @csx
        type Props = {x: string, y: number};
        function Bar(props: Props) {}
        const params1 = {x: '23'};
        const params2 = {y: 23};
        <Bar {...params1} {...params2} />;
      `).noNewErrors(),
    ]),
    test('Should raise an error if JSX attributes from a spread do not match parameters', [
      addCode(`
        // @csx
        type Props = {|x: string|};
        function Bar(props: Props) {}
        const params = {x: 23};
        <Bar {...params} />;
      `)
      .newErrors(
        `
          test.js:8
            8:       <Bar {...params} />;
                     ^^^^^^^^^^^^^^^^^^^ props. Inexact type is incompatible with exact type
            6:       function Bar(props: Props) {}
                                         ^^^^^ Props
  
          test.js:8
            8:       <Bar {...params} />;
                     ^^^^^^^^^^^^^^^^^^^ props. This type is incompatible with the expected param type of
            6:       function Bar(props: Props) {}
                                         ^^^^^ Props
            Property \`x\` is incompatible:
                7:       const params = {x: 23};
                                            ^^ number. This type is incompatible with
                5:       type Props = {|x: string|};
                                           ^^^^^^ string
        `,
      ),
    ]),
    test('Should raise no errors for a JSX element with a valid member expression', [
      addCode(`
        // @csx
        type Props = {|x: number|};
        const Foo = {
          Bar: (props: Props) => {},
        };
        <Foo.Bar x={23} />;
      `)
      .noNewErrors(),
    ]),
    test('Should raise an error for JSX with a valid member expression but invalid props', [
      addCode(`
        // @csx
        type Props = {|x: string|};
        const Foo = {
          Bar: (props: Props) => {},
        };
        <Foo.Bar x={23} />;
      `)
      .noNewErrors(), // Should fail but does not.
    ]),
    test('Should raise an error for an invalid JSX member expression', [
      addCode(`
        // @csx
        type Props = {|x: number|};
        const Foo = {
          Bar: (props: Props) => {},
        };
        <Foo.WRONG_KEY x={23} />;
      `)
      .noNewErrors(), // Should fail but does not.
    ]),
    test('Should pass text children as a prop named children', [
      addCode(`
        // @csx
        type Props = {|children: ['Test']|};
        function Bar(props: Props) {}
        <Bar>Test</Bar>
      `)
      .noNewErrors(),
    ]),
    test('Should raise an error if you pass children to a function with no children prop', [
      addCode(`
        // @csx
        type Props = {||};
        function Bar(props: Props) {}
        <Bar>Test</Bar>
      `)
      .newErrors(
        `
          test.js:7
            7:       <Bar>Test</Bar>
                     ^^^^^ props. This type is incompatible with the expected param type of
            6:       function Bar(props: Props) {}
                                         ^^^^^ Props
            Property \`children\` is incompatible:
                7:       <Bar>Test</Bar>
                         ^^^^^ property \`children\`. Property not found in
                6:       function Bar(props: Props) {}
                                             ^^^^^ Props
        `,
      ),
    ]),
    test('Should raise an error if you pass a JSX child that returns an invalid type', [
      addCode(`
        // @csx
        type FooProps = {|children: Array<string>|};
        function Foo(props: FooProps) {}
        type BarProps = {||};
        function Bar(props: BarProps): number {return 0;}
        <Foo><Bar /></Foo>
      `)
      .newErrors(
        `
          test.js:9
            9:       <Foo><Bar /></Foo>
                     ^^^^^ props. This type is incompatible with the expected param type of
            6:       function Foo(props: FooProps) {}
                                         ^^^^^^^^ FooProps
            Property \`children\` is incompatible:
                9:       <Foo><Bar /></Foo>
                         ^^^^^ JSX element \`Foo\`. Has some incompatible type argument with
                5:       type FooProps = {|children: Array<string>|};
                                                     ^^^^^^^^^^^^^ array type
                Type argument \`T\` is incompatible:
                    9:       <Foo><Bar /></Foo>
                                  ^^^^^^^ number. This type is incompatible with
                    5:       type FooProps = {|children: Array<string>|};
                                                               ^^^^^^ string
        `,
      ),
    ]),
    test('Should strip whitespace from multiline strings', [
      addCode(`
        // @csx
        type Props = {|children: ['Facebook has many products']|};
        function Bar(props: Props) {}
        <Bar>
          Facebook
               has
          many
            products
        </Bar>
      `)
      .noNewErrors(),
    ]),
    test('Should correctly handle JSX expression children', [
      addCode(`
        // @csx
        type Props = {|children: ['A', 'B']|};
        function Bar(props: Props) {}
        <Bar>{'A'}{'B'}</Bar>
      `)
      .noNewErrors(),
    ]),
    test('Should raise an error if JSX expression children have an incorrect type', [
      addCode(`
        // @csx
        type Props = {|children: ['A']|};
        function Bar(props: Props) {}
        <Bar>{42}</Bar>
      `)
      .newErrors(
        `
          test.js:7
            7:       <Bar>{42}</Bar>
                     ^^^^^ props. This type is incompatible with the expected param type of
            6:       function Bar(props: Props) {}
                                         ^^^^^ Props
            Property \`children\` is incompatible:
                7:       <Bar>{42}</Bar>
                         ^^^^^ JSX element \`Bar\`. Has some incompatible tuple element with
                5:       type Props = {|children: ['A']|};
                                                  ^^^^^ tuple type
                The first tuple element is incompatible:
                    7:       <Bar>{42}</Bar>
                                   ^^ number. This type is incompatible with
                    5:       type Props = {|children: ['A']|};
                                                       ^^^ string literal \`A\`
        `,
      ),
    ]),
  ]);
  