diff --git a/src/utils/CodeBuilder.js b/src/utils/CodeBuilder.js new file mode 100644 index 0000000000..269b413538 --- /dev/null +++ b/src/utils/CodeBuilder.js @@ -0,0 +1,29 @@ +const LINE = {}; +const BLOCK = {}; + +export default class CodeBuilder { + constructor () { + this.result = ''; + this.last = null; + } + + addLine ( line ) { + if ( this.last === BLOCK ) { + this.result += `\n\n${line}`; + } else { + this.result += `\n${line}`; + } + + this.last = LINE; + } + + addBlock ( block ) { + this.result += `\n\n${block}`; + + this.last = BLOCK; + } + + toString () { + return this.result.trim(); + } +} diff --git a/src/utils/__test__.js b/src/utils/__test__.js index f403af2f74..7768021a1d 100644 --- a/src/utils/__test__.js +++ b/src/utils/__test__.js @@ -1,5 +1,6 @@ import * as assert from 'assert'; import deindent from './deindent.js'; +import CodeBuilder from './CodeBuilder.js'; describe( 'deindent', () => { it( 'deindents a simple string', () => { @@ -34,3 +35,87 @@ describe( 'deindent', () => { assert.equal( deindented, `before\n\tline one\n\tline two\nafter` ); }); }); + +describe( 'CodeBuilder', () => { + it( 'creates an empty block', () => { + const builder = new CodeBuilder(); + assert.equal( builder.toString(), '' ); + }); + + it( 'creates a block with a line', () => { + const builder = new CodeBuilder(); + + builder.addLine( 'var answer = 42;' ); + assert.equal( builder.toString(), 'var answer = 42;' ); + }); + + it( 'creates a block with two lines', () => { + const builder = new CodeBuilder(); + + builder.addLine( 'var problems = 99;' ); + builder.addLine( 'var answer = 42;' ); + assert.equal( builder.toString(), 'var problems = 99;\nvar answer = 42;' ); + }); + + it( 'adds newlines around blocks', () => { + const builder = new CodeBuilder(); + + builder.addLine( '// line 1' ); + builder.addLine( '// line 2' ); + builder.addBlock( deindent` + if ( foo ) { + bar(); + } + ` ); + builder.addLine( '// line 3' ); + builder.addLine( '// line 4' ); + + assert.equal( builder.toString(), deindent` + // line 1 + // line 2 + + if ( foo ) { + bar(); + } + + // line 3 + // line 4 + ` ); + }); + + it( 'nests codebuilders with correct indentation', () => { + const child = new CodeBuilder(); + + child.addBlock( deindent` + var obj = { + answer: 42 + }; + ` ); + + const builder = new CodeBuilder(); + + builder.addLine( '// line 1' ); + builder.addLine( '// line 2' ); + builder.addBlock( deindent` + if ( foo ) { + ${child} + } + ` ); + builder.addLine( '// line 3' ); + builder.addLine( '// line 4' ); + + assert.equal( builder.toString(), deindent` + // line 1 + // line 2 + + if ( foo ) { + var obj = { + answer: 42 + }; + } + + // line 3 + // line 4 + ` ); + }); +});