import { expect } from 'chai' ; import { describe , it } from 'mocha' ; import { dedentBlockStringLines , isPrintableAsBlockString , printBlockString , } from '../blockString' ; function joinLines ( ... args ) { return args . join ( '\n' ) ; } describe ( 'dedentBlockStringLines' , ( ) => { function expectDedent ( lines ) { return expect ( dedentBlockStringLines ( lines ) ) ; } it ( 'handles empty string' , ( ) => { expectDedent ( [ '' ] ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'does not dedent first line' , ( ) => { expectDedent ( [ '  a' ] ) . to . deep . equal ( [ '  a' ] ) ; expectDedent ( [ ' a' , '  b' ] ) . to . deep . equal ( [ ' a' , 'b' ] ) ; } ) ; it ( 'removes minimal indentation length' , ( ) => { expectDedent ( [ '' , ' a' , '  b' ] ) . to . deep . equal ( [ 'a' , ' b' ] ) ; expectDedent ( [ '' , '  a' , ' b' ] ) . to . deep . equal ( [ ' a' , 'b' ] ) ; expectDedent ( [ '' , '  a' , ' b' , 'c' ] ) . to . deep . equal ( [ '  a' , ' b' , 'c' ] ) ; } ) ; it ( 'dedent both tab and space as single character' , ( ) => { expectDedent ( [ '' , '\ta' , '          b' ] ) . to . deep . equal ( [ 'a' , '         b' ] ) ; expectDedent ( [ '' , '\t a' , '          b' ] ) . to . deep . equal ( [ 'a' , '        b' ] ) ; expectDedent ( [ '' , ' \t a' , '          b' ] ) . to . deep . equal ( [ 'a' , '       b' ] ) ; } ) ; it ( 'dedent do not take empty lines into account' , ( ) => { expectDedent ( [ 'a' , '' , ' b' ] ) . to . deep . equal ( [ 'a' , '' , 'b' ] ) ; expectDedent ( [ 'a' , ' ' , '  b' ] ) . to . deep . equal ( [ 'a' , '' , 'b' ] ) ; } ) ; it ( 'removes uniform indentation from a string' , ( ) => { const lines = [ '' , '    Hello,' , '      World!' , '' , '    Yours,' , '      GraphQL.' , ] ; expectDedent ( lines ) . to . deep . equal ( [ 'Hello,' , '  World!' , '' , 'Yours,' , '  GraphQL.' , ] ) ; } ) ; it ( 'removes empty leading and trailing lines' , ( ) => { const lines = [ '' , '' , '    Hello,' , '      World!' , '' , '    Yours,' , '      GraphQL.' , '' , '' , ] ; expectDedent ( lines ) . to . deep . equal ( [ 'Hello,' , '  World!' , '' , 'Yours,' , '  GraphQL.' , ] ) ; } ) ; it ( 'removes blank leading and trailing lines' , ( ) => { const lines = [ '  ' , '        ' , '    Hello,' , '      World!' , '' , '    Yours,' , '      GraphQL.' , '        ' , '  ' , ] ; expectDedent ( lines ) . to . deep . equal ( [ 'Hello,' , '  World!' , '' , 'Yours,' , '  GraphQL.' , ] ) ; } ) ; it ( 'retains indentation from first line' , ( ) => { const lines = [ '    Hello,' , '      World!' , '' , '    Yours,' , '      GraphQL.' , ] ; expectDedent ( lines ) . to . deep . equal ( [ '    Hello,' , '  World!' , '' , 'Yours,' , '  GraphQL.' , ] ) ; } ) ; it ( 'does not alter trailing spaces' , ( ) => { const lines = [ '               ' , '    Hello,     ' , '      World!   ' , '               ' , '    Yours,     ' , '      GraphQL. ' , '               ' , ] ; expectDedent ( lines ) . to . deep . equal ( [ 'Hello,     ' , '  World!   ' , '           ' , 'Yours,     ' , '  GraphQL. ' , ] ) ; } ) ; } ) ; describe ( 'isPrintableAsBlockString' , ( ) => { function expectPrintable ( str ) { return expect ( isPrintableAsBlockString ( str ) ) . to . equal ( true ) ; } function expectNonPrintable ( str ) { return expect ( isPrintableAsBlockString ( str ) ) . to . equal ( false ) ; } it ( 'accepts valid strings' , ( ) => { expectPrintable ( '' ) ; expectPrintable ( ' a' ) ; expectPrintable ( '\t"\n"' ) ; expectNonPrintable ( '\t"\n \n\t"' ) ; } ) ; it ( 'rejects strings with only whitespace' , ( ) => { expectNonPrintable ( ' ' ) ; expectNonPrintable ( '\t' ) ; expectNonPrintable ( '\t ' ) ; expectNonPrintable ( ' \t' ) ; } ) ; it ( 'rejects strings with non-printable characters' , ( ) => { expectNonPrintable ( '\x00' ) ; expectNonPrintable ( 'a\x00b' ) ; } ) ; it ( 'rejects strings with only empty lines' , ( ) => { expectNonPrintable ( '\n' ) ; expectNonPrintable ( '\n\n' ) ; expectNonPrintable ( '\n\n\n' ) ; expectNonPrintable ( ' \n  \n' ) ; expectNonPrintable ( '\t\n\t\t\n' ) ; } ) ; it ( 'rejects strings with carriage return' , ( ) => { expectNonPrintable ( '\r' ) ; expectNonPrintable ( '\n\r' ) ; expectNonPrintable ( '\r\n' ) ; expectNonPrintable ( 'a\rb' ) ; } ) ; it ( 'rejects strings with leading empty lines' , ( ) => { expectNonPrintable ( '\na' ) ; expectNonPrintable ( ' \na' ) ; expectNonPrintable ( '\t\na' ) ; expectNonPrintable ( '\n\na' ) ; } ) ; it ( 'rejects strings with trailing empty lines' , ( ) => { expectNonPrintable ( 'a\n' ) ; expectNonPrintable ( 'a\n ' ) ; expectNonPrintable ( 'a\n\t' ) ; expectNonPrintable ( 'a\n\n' ) ; } ) ; } ) ; describe ( 'printBlockString' , ( ) => { function expectBlockString ( str ) { return { toEqual ( expected ) { const { readable , minimize } = typeof expected === 'string' ? { readable : expected , minimize : expected } : expected ; expect ( printBlockString ( str ) ) . to . equal ( readable ) ; expect ( printBlockString ( str , { minimize : true } ) ) . to . equal ( minimize ) ; } , } ; } it ( 'does not escape characters' , ( ) => { const str = '" \\ / \b \f \n \r \t' ; expectBlockString ( str ) . toEqual ( { readable : '"""\n' + str + '\n"""' , minimize : '"""\n' + str + '"""' , } ) ; } ) ; it ( 'by default print block strings as single line' , ( ) => { const str = 'one liner' ; expectBlockString ( str ) . toEqual ( '"""one liner"""' ) ; } ) ; it ( 'by default print block strings ending with triple quotation as multi-line' , ( ) => { const str = 'triple quotation """' ; expectBlockString ( str ) . toEqual ( { readable : '"""\ntriple quotation \\"""\n"""' , minimize : '"""triple quotation \\""""""' , } ) ; } ) ; it ( 'correctly prints single-line with leading space' , ( ) => { const str = '    space-led string' ; expectBlockString ( str ) . toEqual ( '"""    space-led string"""' ) ; } ) ; it ( 'correctly prints single-line with leading space and trailing quotation' , ( ) => { const str = '    space-led value "quoted string"' ; expectBlockString ( str ) . toEqual ( '"""    space-led value "quoted string"\n"""' ) ; } ) ; it ( 'correctly prints single-line with trailing backslash' , ( ) => { const str = 'backslash \\' ; expectBlockString ( str ) . toEqual ( { readable : '"""\nbackslash \\\n"""' , minimize : '"""backslash \\\n"""' , } ) ; } ) ; it ( 'correctly prints multi-line with internal indent' , ( ) => { const str = 'no indent\n with indent' ; expectBlockString ( str ) . toEqual ( { readable : '"""\nno indent\n with indent\n"""' , minimize : '"""\nno indent\n with indent"""' , } ) ; } ) ; it ( 'correctly prints string with a first line indentation' , ( ) => { const str = joinLines ( '    first  ' , '  line     ' , 'indentation' , '     string' ) ; expectBlockString ( str ) . toEqual ( { readable : joinLines ( '"""' , '    first  ' , '  line     ' , 'indentation' , '     string' , '"""' ) , minimize : joinLines ( '"""    first  ' , '  line     ' , 'indentation' , '     string"""' ) , } ) ; } ) ; } ) ;