mirror of https://github.com/tc39/test262.git
[generation] Prevent invalid transformation
In order to promote readability of the generated test material, the test generation tool may insert whitespace if the context a given expanded variable calls for it. Avoid inserting such whitespace within literal values that span multiple lines.
This commit is contained in:
parent
975e54de17
commit
da4e798e5b
|
@ -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')
|
||||
|
|
|
@ -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.`;
|
||||
}
|
||||
}());
|
|
@ -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';
|
||||
}
|
||||
}());
|
|
@ -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 ".`;
|
||||
}
|
||||
}());
|
|
@ -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.`;
|
||||
}
|
||||
}());
|
|
@ -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';
|
||||
}
|
||||
}());
|
|
@ -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 ".`;
|
||||
}
|
||||
}());
|
|
@ -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.`;
|
|
@ -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';
|
|
@ -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 ".`;
|
|
@ -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 }*/
|
||||
}
|
||||
}());
|
|
@ -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 }*/
|
||||
}
|
||||
}());
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue