# We usually do not check the actual JS output from the compiler, but since # JSX is not natively supported by Node, we do it in this case. test 'self closing', -> eqJS '''
''', '''
; ''' test 'self closing formatting', -> eqJS '''
''', '''
; ''' test 'self closing multiline', -> eqJS '''
''', '''
; ''' test 'reserved-word self closing', -> eqJS ''' ''', ''' ; ''' test 'regex attribute', -> eqJS '''
asds/} /> ''', '''
asds/} />; ''' test 'string attribute', -> eqJS '''
''', '''
; ''' test 'simple attribute', -> eqJS '''
''', '''
; ''' test 'assignment attribute', -> eqJS '''
''', ''' var y;
; ''' test 'object attribute', -> eqJS '''
''', '''
; ''' test 'attribute without value', -> eqJS '''
''', '''
; ''' test 'reserved-word attribute without value', -> eqJS '''
''', '''
; ''' test 'reserved-word attribute with value', -> eqJS '''
''', '''
; ''' test 'attribute with namespace', -> eqJS ''' ''', ''' ; ''' test 'attribute with double namespace disallowed', -> throwsCompileError '' test 'attribute with member expression disallowed', -> throwsCompileError '' test 'paired', -> eqJS '''
''', '''
; ''' test 'simple content', -> eqJS '''
Hello world
''', '''
Hello world
; ''' test 'content interpolation', -> eqJS '''
Hello {42}
''', '''
Hello {42}
; ''' test 'nested tag', -> eqJS '''
''', '''
; ''' test 'tag inside interpolation formatting', -> eqJS '''
Hello {}
''', '''
Hello
; ''' test 'tag inside interpolation, tags are callable', -> eqJS '''
Hello { x}
''', '''
Hello {(x)}
; ''' test 'tags inside interpolation, tags trigger implicit calls', -> eqJS '''
Hello {f }
''', '''
Hello {f()}
; ''' test 'regex in interpolation', -> eqJS '''
asds/}>
{/>asdsad ''', '''
asds/}>
{/>asdsad; ''' test 'interpolation in string attribute value', -> eqJS '''
''', '''
; ''' # Unlike in `coffee-react-transform`. test 'bare numbers not allowed', -> throwsCompileError '
' test 'bare expressions not allowed', -> throwsCompileError '
' test 'bare complex expressions not allowed', -> throwsCompileError '
' test 'unescaped opening tag angle bracket disallowed', -> throwsCompileError '<<' test 'space around equal sign', -> eqJS '''
''', '''
; ''' # The following tests were adopted from James Friend’s # [https://github.com/jsdf/coffee-react-transform](https://github.com/jsdf/coffee-react-transform). test 'ambiguous tag-like expression', -> throwsCompileError 'x = a c' test 'ambiguous tag', -> eqJS ''' a c ''', ''' a( c ); ''' test 'escaped CoffeeScript attribute', -> eqJS ''' ''', ''' ; ''' test 'escaped CoffeeScript attribute over multiple lines', -> eqJS ''' ''', ''' ; ''' test 'multiple line escaped CoffeeScript with nested JSX', -> eqJS ''' { for n in a
a asf
  • { n+1 }
  • }
    ''', ''' var n; {(function() { var i, len, results; results = []; for (i = 0, len = a.length; i < len; i++) { n = a[i]; results.push(); } return results; })()}
    ; ''' test 'nested JSX within an attribute, with object attr value', -> eqJS ''' } /> ''', ''' } /> ; ''' test 'complex nesting', -> eqJS '''
    ''', '''
    ; ''' test 'multiline tag with nested JSX within an attribute', -> eqJS ''' } > blah blah blah ''', ''' var name; }> blah blah blah ; ''' test 'escaped CoffeeScript with nested object literals', -> eqJS ''' blah blah blah { {'a' : {}, 'asd': 'asd'} } ''', ''' blah blah blah {{ 'a': {}, 'asd': 'asd' }} ; ''' test 'multiline tag attributes with escaped CoffeeScript', -> eqJS ''' ''', ''' ; ''' test 'lots of attributes', -> eqJS ''' ''', ''' ; ''' # TODO: fix partially indented JSX # test 'multiline elements', -> # eqJS ''' #
    # test = /432/gm # this is a regex # 6 /432/gm # this is division # } # > #
    #
    #
    #
    #
    #
    #
    #
    #
    # ''', ''' # bla # ''' test 'complex regex', -> eqJS ''' /\\/\\/\\>\\// ''', ''' ; /\\/\\/\\>\\//; ''' test 'heregex', -> eqJS ''' test = /432/gm # this is a regex 6 /432/gm # this is division {test = //} this is a regex containing something which looks like a tag REGEX = /// ^ (/ (?! [\s=] ) # comment comment comment [^ [ / \n \\ ]* # comment comment (?: (?: \\[\s\S] # comment comment | \[ # comment comment [^ \] \n \\ ]* (?: \\[\s\S] [^ \] \n \\ ]* )* tag ] ) [^ [ / \n \\ ]* )* /) ([imgy]{0,4}) (?!\w) /// ''', ''' var REGEX, test; test = /432/gm; // this is a regex 6 / 432 / gm; // this is division {test = //} this is a regex containing something which looks like a tag ; ; REGEX = /^(\\/(?![s=])[^[\\/ ]*(?:(?:\\[sS]|[[^] ]*(?:\\[sS][^] ]*)*tag<\\/Tag>])[^[\\/ ]*)*\\/)([imgy]{0,4})(?!w)/; // comment comment comment // comment comment // comment comment // comment comment ; ''' test 'comment within JSX is not treated as comment', -> eqJS ''' # i am not a comment ''', ''' # i am not a comment ; ''' test 'comment at start of JSX escape', -> eqJS ''' {# i am a comment "i am a string" } ''', ''' {// i am a comment "i am a string"} ; ''' test 'comment at end of JSX escape', -> eqJS ''' {"i am a string" # i am a comment } ''', ''' {"i am a string" // i am a comment } ; ''' test 'JSX comment cannot be used inside interpolation', -> throwsCompileError ''' {# i am a comment} ''' test 'comment syntax cannot be used inline', -> throwsCompileError ''' {#comment inline} ''' test 'string within JSX is ignored', -> eqJS ''' "i am not a string" 'nor am i' ''', ''' "i am not a string" 'nor am i' ; ''' test 'special chars within JSX are ignored', -> eqJS """ a,/';][' a\''@$%^&˚¬∑˜˚∆å∂¬˚*()*&^%$>> '"''"'''\'\'m' i """, """ a,/';][' a''@$%^&˚¬∑˜˚∆å∂¬˚*()*&^%$>> '"''"'''''m' i ; """ test 'html entities (name, decimal, hex) within JSX', -> eqJS ''' &&&€ € €;; ''', ''' &&&€ € €;; ; ''' test 'tag with {{}}', -> eqJS ''' ''', ''' ; ''' test 'tag with member expression', -> eqJS ''' ''', ''' ; ''' test 'tag with lowercase member expression', -> eqJS ''' ''', ''' ; ''' test 'self closing tag with member expression', -> eqJS ''' ''', ''' ; ''' test 'self closing tag with multiple member expressions', -> eqJS ''' ''', ''' ; ''' test 'tag with namespace', -> eqJS ''' ''', ''' ; ''' test 'tag with lowercase namespace', -> eqJS ''' ''', ''' ; ''' test 'self closing tag with namespace', -> eqJS ''' ''', ''' ; ''' test 'self closing tag with namespace and member expression disallowed', -> throwsCompileError ''' ''' test 'self closing tag with spread attribute', -> eqJS ''' ''', ''' ; ''' test 'complex spread attribute', -> eqJS ''' ''', ''' ; ''' test 'multiline spread attribute', -> eqJS ''' ''', ''' ; ''' test 'multiline tag with spread attribute', -> eqJS ''' ''', ''' ; ''' test 'multiline tag with spread attribute first', -> eqJS ''' ''', ''' ; ''' test 'complex multiline spread attribute', -> eqJS '''
    ''', '''
    ; ''' test 'self closing spread attribute on single line', -> eqJS ''' ''', ''' ; ''' test 'self closing spread attribute on new line', -> eqJS ''' ''', ''' ; ''' test 'self closing spread attribute on same line', -> eqJS ''' ''', ''' ; ''' test 'self closing spread attribute on next line', -> eqJS ''' ''', ''' ; ''' test 'empty strings are not converted to true', -> eqJS ''' ''', ''' ; ''' test 'CoffeeScript @ syntax in tag name', -> throwsCompileError ''' <@Component> ''' test 'hyphens in tag names', -> eqJS ''' {text} ''', ''' {text}; ''' test 'closing tags must be closed', -> throwsCompileError ''' a = 3 div = 5 ok a
    div = 5 ok 3
    div = 5 ok (3)
    div = 5 a = [3] ok a[0]
    eqJS ''' a
    ''', ''' a
    ; ''' test 'tag inside JSX works following: number', -> eqJS ''' 3
    ''', ''' 3
    ; ''' test 'tag inside JSX works following: paren', -> eqJS ''' (3)
    ''', ''' (3)
    ; ''' test 'tag inside JSX works following: square bracket', -> eqJS ''' ]
    ''', ''' ]
    ; ''' test 'unspaced less than inside JSX works but is not encouraged', -> eqJS ''' a = 3 div = 5 html = {a ''', ''' var a, div, html; a = 3; div = 5; html = {a < div}; ''' test 'unspaced less than before JSX works but is not encouraged', -> eqJS ''' div = 5 res = 2
    ''', ''' var div, html, res; div = 5; res = 2 < div; html = ; ''' test 'unspaced less than after JSX works but is not encouraged', -> eqJS ''' div = 5 html = res = 2
    ; res = 2 < div; ''' test '#4686: comments inside interpolations that also contain JSX tags', -> eqJS '''
    { # comment
    }
    ''', '''
    { // comment
    }
    ; ''' test '#4686: comments inside interpolations that also contain JSX attributes', -> eqJS '''
    ''', '''
    { // comment
    }
    ; ''' test '#5086: comments inside JSX tags but outside interpolations', -> eqJS '''
    ''', '''
    ; ''' test '#5086: comments inside JSX attributes but outside interpolations', -> eqJS '''
    ''', '''
    ; ''' test '#5086: comments inside nested JSX tags and attributes but outside interpolations', -> eqJS '''
    ''', '''
    ; ''' # https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html test 'JSX fragments: empty fragment', -> eqJS ''' <> ''', ''' <>; ''' test 'JSX fragments: fragment with text nodes', -> eqJS ''' <> Some text.

    A heading

    More text.

    Another heading

    Even more text. ''', ''' <> Some text.

    A heading

    More text.

    Another heading

    Even more text. ; ''' test 'JSX fragments: fragment with component nodes', -> eqJS ''' Component = (props) => ''', ''' var Component; Component = (props) => { return ; }; ''' test '#5055: JSX expression indentation bug', -> eqJS '''
    {someCondition && }
    ''', '''
    {someCondition && }
    ; ''' eqJS '''
    {someString + "abc" }
    ''', '''
    {someString + "abc"}
    ; ''' eqJS '''
    {a ? }
    ''', '''
    {typeof a !== "undefined" && a !== null ? a : }
    ; ''' # JSX is like XML, in that there needs to be a root element; but # technically, adjacent top-level elements where only the last one # is returned (as opposed to a fragment or root element) is permissible # syntax. It’s almost certainly an error, but it’s valid, so need to leave it # to linters to catch. https://github.com/jashkenas/coffeescript/pull/5049 test '“Adjacent” tags on separate lines should still compile', -> eqJS ''' -> ''', ''' (function() { ; return ; }); ''' test '#5352: triple-quoted non-interpolated attribute values', -> eqJS '''
    ''', '''
    ; ''' eqJS """
    """, '''
    ; '''