From 677767e487482d6819607faef8ae2ae40f5693e6 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Tue, 2 Jan 2018 23:49:47 +0200 Subject: [PATCH] Fix print of block string with leading space and quotation --- src/language/__tests__/printer-test.js | 87 +++++++++++-------- src/language/__tests__/schema-printer-test.js | 2 +- src/language/printer.js | 11 ++- 3 files changed, 58 insertions(+), 42 deletions(-) diff --git a/src/language/__tests__/printer-test.js b/src/language/__tests__/printer-test.js index 0339098ac0..14b75e32ea 100644 --- a/src/language/__tests__/printer-test.js +++ b/src/language/__tests__/printer-test.js @@ -13,7 +13,11 @@ import { print } from '../printer'; import { join } from 'path'; import dedent from '../../jsutils/dedent'; -describe('Printer', () => { +describe('Printer: Query document', () => { + const kitchenSink = readFileSync(join(__dirname, '/kitchen-sink.graphql'), { + encoding: 'utf8', + }); + it('does not alter ast', () => { const ast = parse(kitchenSink); const astBefore = JSON.stringify(ast); @@ -71,36 +75,53 @@ describe('Printer', () => { `); }); - it('correctly prints single-line block strings with leading space', () => { - const mutationAstWithArtifacts = parse( - '{ field(arg: """ space-led value""") }', - ); - expect(print(mutationAstWithArtifacts)).to.equal(dedent` - { - field(arg: """ space-led value""") - } - `); - }); - - it('correctly prints block strings with a first line indentation', () => { - const mutationAstWithArtifacts = parse(` - { - field(arg: """ - first - line - indentation - """) - } - `); - expect(print(mutationAstWithArtifacts)).to.equal(dedent` - { - field(arg: """ - first - line - indentation - """) - } - `); + describe('block string', () => { + it('correctly prints single-line with leading space', () => { + const mutationAstWithArtifacts = parse( + '{ field(arg: """ space-led value""") }', + ); + expect(print(mutationAstWithArtifacts)).to.equal(dedent` + { + field(arg: """ space-led value""") + } + `); + }); + + it('correctly prints string with a first line indentation', () => { + const mutationAstWithArtifacts = parse(` + { + field(arg: """ + first + line + indentation + """) + } + `); + expect(print(mutationAstWithArtifacts)).to.equal(dedent` + { + field(arg: """ + first + line + indentation + """) + } + `); + }); + + it('correctly prints single-line with leading space and quotation', () => { + const mutationAstWithArtifacts = parse(` + { + field(arg: """ space-led value "quoted string" + """) + } + `); + expect(print(mutationAstWithArtifacts)).to.equal(dedent` + { + field(arg: """ space-led value "quoted string" + """) + } + `); + }); }); it('Experimental: correctly prints fragment defined variables', () => { @@ -119,10 +140,6 @@ describe('Printer', () => { `); }); - const kitchenSink = readFileSync(join(__dirname, '/kitchen-sink.graphql'), { - encoding: 'utf8', - }); - it('prints kitchen sink', () => { const ast = parse(kitchenSink); diff --git a/src/language/__tests__/schema-printer-test.js b/src/language/__tests__/schema-printer-test.js index 1bacb8e586..cb3a3cd4c6 100644 --- a/src/language/__tests__/schema-printer-test.js +++ b/src/language/__tests__/schema-printer-test.js @@ -13,7 +13,7 @@ import { parse } from '../parser'; import { print } from '../printer'; import dedent from '../../jsutils/dedent'; -describe('Printer', () => { +describe('Printer: SDL document', () => { it('prints minimal ast', () => { const ast = { kind: 'ScalarTypeDefinition', diff --git a/src/language/printer.js b/src/language/printer.js index 77ffde567b..a614d4f872 100644 --- a/src/language/printer.js +++ b/src/language/printer.js @@ -236,7 +236,7 @@ function join(maybeArray, separator) { */ function block(array) { return array && array.length !== 0 - ? indent('{\n' + join(array, '\n')) + '\n}' + ? '{\n' + indent(join(array, '\n')) + '\n}' : ''; } @@ -249,7 +249,7 @@ function wrap(start, maybeString, end) { } function indent(maybeString) { - return maybeString && maybeString.replace(/\n/g, '\n '); + return maybeString && ' ' + maybeString.replace(/\n/g, '\n '); } /** @@ -258,9 +258,8 @@ function indent(maybeString) { * a single-line, adding a leading blank line would strip that whitespace. */ function printBlockString(value, isDescription) { + const escaped = value.replace(/"""/g, '\\"""'); return (value[0] === ' ' || value[0] === '\t') && value.indexOf('\n') === -1 - ? `"""${value.replace(/"""/g, '\\"""')}"""` - : isDescription - ? '"""\n' + value.replace(/"""/g, '\\"""') + '\n"""' - : indent('"""\n' + value.replace(/"""/g, '\\"""')) + '\n"""'; + ? `"""${escaped.replace(/"$/, '"\n')}"""` + : `"""\n${isDescription ? escaped : indent(escaped)}\n"""`; }