Merge pull request #884 from jugglinmike/test-generation-indentation

Extend test generation tool
This commit is contained in:
Leo Balter 2017-03-06 14:45:40 -05:00 committed by GitHub
commit da3898d707
19 changed files with 284 additions and 51 deletions

View File

@ -0,0 +1,22 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
desc: Computed values as accessor property names (string literal containing LineContinuation)
template: default
info: |
12.2.6.7 Runtime Semantics: Evaluation
[...]
ComputedPropertyName : [ AssignmentExpression ]
1. Let exprValue be the result of evaluating AssignmentExpression.
2. Let propName be ? GetValue(exprValue).
3. Return ? ToPropertyKey(propName).
---*/
//- declareWith
'line\
Continuation'
//- referenceWith
'lineContinuation'

View File

@ -1,9 +1,11 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
// This file was procedurally generated from the following sources:
// - src/accessor-names/literal-string-line-continuation.case
// - src/accessor-names/default/cls-expr-inst.template
/*---
description: Computed values as accessor property names (string literal containing a line terminator) (Class expression, instance method)
description: Computed values as accessor property names (string literal containing LineContinuation) (Class expression, instance method)
esid: sec-runtime-semantics-classdefinitionevaluation
es6id: 14.5.14
flags: [generated]
info: |
[...]
21. For each ClassElement m in order from methods
@ -26,14 +28,12 @@ var stringSet;
var C = class {
get 'line\
Terminator'
() { return 'get string'; }
Continuation'() { return 'get string'; }
set 'line\
Terminator'
(param) { stringSet = param; }
Continuation'(param) { stringSet = param; }
};
assert.sameValue(C.prototype['lineTerminator'], 'get string');
assert.sameValue(C.prototype['lineContinuation'], 'get string');
C.prototype['lineTerminator'] = 'set string';
C.prototype['lineContinuation'] = 'set string';
assert.sameValue(stringSet, 'set string');

View File

@ -1,9 +1,11 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
// This file was procedurally generated from the following sources:
// - src/accessor-names/literal-string-line-continuation.case
// - src/accessor-names/default/cls-expr-static.template
/*---
description: Computed values as accessor property names (string literal containing a line terminator) (Class expression, static method)
description: Computed values as accessor property names (string literal containing LineContinuation) (Class expression, static method)
esid: sec-runtime-semantics-classdefinitionevaluation
es6id: 14.5.14
flags: [generated]
info: |
[...]
21. For each ClassElement m in order from methods
@ -28,14 +30,12 @@ var stringSet;
var C = class {
static get 'line\
Terminator'
() { return 'get string'; }
Continuation'() { return 'get string'; }
static set 'line\
Terminator'
(param) { stringSet = param; }
Continuation'(param) { stringSet = param; }
};
assert.sameValue(C['lineTerminator'], 'get string');
assert.sameValue(C['lineContinuation'], 'get string');
C['lineTerminator'] = 'set string';
C['lineContinuation'] = 'set string';
assert.sameValue(stringSet, 'set string');

View File

@ -1,9 +1,11 @@
// Copyright (C) 2016 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
// This file was procedurally generated from the following sources:
// - src/accessor-names/literal-string-line-continuation.case
// - src/accessor-names/default/obj.template
/*---
description: Computed values as accessor property names (string literal containing a line terminator) (Object initializer)
description: Computed values as accessor property names (string literal containing LineContinuation) (Object initializer)
esid: sec-object-initializer-runtime-semantics-evaluation
es6id: 12.2.6.8
flags: [generated]
info: |
ObjectLiteral :
{ PropertyDefinitionList }
@ -27,14 +29,12 @@ info: |
var stringSet;
var obj = {
get ['line\
Terminator'
]() { return 'get string'; },
Continuation']() { return 'get string'; },
set ['line\
Terminator'
](param) { stringSet = param; }
Continuation'](param) { stringSet = param; }
};
assert.sameValue(obj['lineTerminator'], 'get string');
assert.sameValue(obj['lineContinuation'], 'get string');
obj['lineTerminator'] = 'set string';
obj['lineContinuation'] = 'set string';
assert.sameValue(stringSet, 'set string');

View File

@ -1,9 +1,11 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
// This file was procedurally generated from the following sources:
// - src/accessor-names/literal-string-line-continuation.case
// - src/accessor-names/default/cls-decl-inst.template
/*---
description: Computed values as accessor property names (string literal containing a line terminator) (Class declaration, instance method)
description: Computed values as accessor property names (string literal containing LineContinuation) (Class declaration, instance method)
esid: sec-runtime-semantics-classdefinitionevaluation
es6id: 14.5.14
flags: [generated]
info: |
[...]
21. For each ClassElement m in order from methods
@ -26,14 +28,12 @@ var stringSet;
class C {
get 'line\
Terminator'
() { return 'get string'; }
Continuation'() { return 'get string'; }
set 'line\
Terminator'
(param) { stringSet = param; }
Continuation'(param) { stringSet = param; }
}
assert.sameValue(C.prototype['lineTerminator'], 'get string');
assert.sameValue(C.prototype['lineContinuation'], 'get string');
C.prototype['lineTerminator'] = 'set string';
C.prototype['lineContinuation'] = 'set string';
assert.sameValue(stringSet, 'set string');

View File

@ -1,9 +1,11 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
// This file was procedurally generated from the following sources:
// - src/accessor-names/literal-string-line-continuation.case
// - src/accessor-names/default/cls-decl-static.template
/*---
description: Computed values as accessor property names (string literal containing a line terminator) (Class declaration, static method)
description: Computed values as accessor property names (string literal containing LineContinuation) (Class declaration, static method)
esid: sec-runtime-semantics-classdefinitionevaluation
es6id: 14.5.14
flags: [generated]
info: |
[...]
21. For each ClassElement m in order from methods
@ -28,14 +30,12 @@ var stringSet;
class C {
static get 'line\
Terminator'
() { return 'get string'; }
Continuation'() { return 'get string'; }
static set 'line\
Terminator'
(param) { stringSet = param; }
Continuation'(param) { stringSet = param; }
}
assert.sameValue(C['lineTerminator'], 'get string');
assert.sameValue(C['lineContinuation'], 'get string');
C['lineTerminator'] = 'set string';
C['lineContinuation'] = 'set string';
assert.sameValue(stringSet, 'set string');

View File

@ -11,18 +11,40 @@ from test import Test
indentPattern = re.compile(r'^(\s*)')
interpolatePattern = re.compile(r'\{\s*(\S+)\s*\}')
def indent(text, prefix = ' '):
def indent(text, prefix = ' ', js_value = False):
'''Prefix a block of text (as defined by the "line break" control
character) with some character sequence.'''
character) with some character sequence.
:param prefix: String value to insert before each line
:param js_value: If True, the text will be interpreted as a JavaScript
value, meaning that indentation will not occur for lines that would
effect the runtime value; defaults to False
'''
if isinstance(text, list):
lines = text
else:
lines = text.split('\n')
indented = map(
lambda line: line if len(line) == 0 else prefix + line,
lines)
indented = [prefix + lines[0]]
str_char = None
for line in lines[1:]:
# Determine if the beginning of the current line is part of some
# previously-opened literal value.
if js_value:
for char in indented[-1]:
if char == str_char:
str_char = None
elif str_char is None and char in '\'"`':
str_char = char
# Do not indent the current line if it is a continuation of a literal
# value or if it is empty.
if str_char or len(line) == 0:
indented.append(line)
else:
indented.append(prefix + line)
return '\n'.join(indented)
@ -90,7 +112,7 @@ class Template:
value = value.replace('\n', '\\\n')
source = source[:region['firstchar']] + \
indent(value, whitespace).lstrip() + \
indent(value, whitespace, True).lstrip() + \
source[region['lastchar']:]
setup = context['regions'].get('setup')

View File

@ -0,0 +1,19 @@
// This file was procedurally generated from the following sources:
// - tools/generation/test/fixtures/indent-code.case
// - tools/generation/test/fixtures/indentation/spaces.template
/*---
description: Multiple lines of code (Preserving "soft" indentation across newlines)
flags: [generated]
---*/
(function() {
'These literals are each contained on a single line...';
"...which means they may be indented...";
`...without effecting the semantics of the generated source code.`;
if (true) {
'These literals are each contained on a single line...';
"...which means they may be indented...";
`...without effecting the semantics of the generated source code.`;
}
}());

View File

@ -0,0 +1,19 @@
// This file was procedurally generated from the following sources:
// - tools/generation/test/fixtures/indent-string-continuation.case
// - tools/generation/test/fixtures/indentation/spaces.template
/*---
description: Multiline string via a line continuation character (Preserving "soft" indentation across newlines)
flags: [generated]
---*/
(function() {
'this string is declared across multiple lines\
\
which disqualifies it as a candidate for indentation';
if (true) {
'this string is declared across multiple lines\
\
which disqualifies it as a candidate for indentation';
}
}());

View File

@ -0,0 +1,21 @@
// This file was procedurally generated from the following sources:
// - tools/generation/test/fixtures/indent-string-template.case
// - tools/generation/test/fixtures/indentation/spaces.template
/*---
description: String template spanning multiple lines (Preserving "soft" indentation across newlines)
flags: [generated]
---*/
(function() {
`this string template is declared across multiple lines
which disqualifies it as a candidate for indentation
it also happens to contain ' and ".`;
if (true) {
`this string template is declared across multiple lines
which disqualifies it as a candidate for indentation
it also happens to contain ' and ".`;
}
}());

View File

@ -0,0 +1,19 @@
// This file was procedurally generated from the following sources:
// - tools/generation/test/fixtures/indent-code.case
// - tools/generation/test/fixtures/indentation/tabs.template
/*---
description: Multiple lines of code (Preserving "hard" indentation across newlines)
flags: [generated]
---*/
(function() {
'These literals are each contained on a single line...';
"...which means they may be indented...";
`...without effecting the semantics of the generated source code.`;
if (true) {
'These literals are each contained on a single line...';
"...which means they may be indented...";
`...without effecting the semantics of the generated source code.`;
}
}());

View File

@ -0,0 +1,19 @@
// This file was procedurally generated from the following sources:
// - tools/generation/test/fixtures/indent-string-continuation.case
// - tools/generation/test/fixtures/indentation/tabs.template
/*---
description: Multiline string via a line continuation character (Preserving "hard" indentation across newlines)
flags: [generated]
---*/
(function() {
'this string is declared across multiple lines\
\
which disqualifies it as a candidate for indentation';
if (true) {
'this string is declared across multiple lines\
\
which disqualifies it as a candidate for indentation';
}
}());

View File

@ -0,0 +1,21 @@
// This file was procedurally generated from the following sources:
// - tools/generation/test/fixtures/indent-string-template.case
// - tools/generation/test/fixtures/indentation/tabs.template
/*---
description: String template spanning multiple lines (Preserving "hard" indentation across newlines)
flags: [generated]
---*/
(function() {
`this string template is declared across multiple lines
which disqualifies it as a candidate for indentation
it also happens to contain ' and ".`;
if (true) {
`this string template is declared across multiple lines
which disqualifies it as a candidate for indentation
it also happens to contain ' and ".`;
}
}());

View File

@ -0,0 +1,11 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
template: indentation
desc: Multiple lines of code
---*/
//- value
'These literals are each contained on a single line...';
"...which means they may be indented...";
`...without effecting the semantics of the generated source code.`;

View File

@ -0,0 +1,11 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
template: indentation
desc: Multiline string via a line continuation character
---*/
//- value
'this string is declared across multiple lines\
\
which disqualifies it as a candidate for indentation';

View File

@ -0,0 +1,12 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
template: indentation
desc: String template spanning multiple lines
---*/
//- value
`this string template is declared across multiple lines
which disqualifies it as a candidate for indentation
it also happens to contain ' and ".`;

View File

@ -0,0 +1,14 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
name: Preserving "soft" indentation across newlines
path: indentation/spaces-
---*/
(function() {
/*{ value }*/
if (true) {
/*{ value }*/
}
}());

View File

@ -0,0 +1,14 @@
// Copyright (C) 2017 Mike Pennisi. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
name: Preserving "hard" indentation across newlines
path: indentation/tabs-
---*/
(function() {
/*{ value }*/
if (true) {
/*{ value }*/
}
}());

View File

@ -59,5 +59,14 @@ class TestGeneration(unittest.TestCase):
self.assertEqual(result['returncode'], 0)
self.compareTrees('negative')
def test_indentation(self):
result = self.fixture('indent-code.case')
self.assertEqual(result['returncode'], 0)
result = self.fixture('indent-string-continuation.case')
self.assertEqual(result['returncode'], 0)
result = self.fixture('indent-string-template.case')
self.assertEqual(result['returncode'], 0)
self.compareTrees('indentation')
if __name__ == '__main__':
unittest.main()