def test_string(self): self.assertEqual( base_matchers.HasItem(1, base_matchers.Bind('a')).match( _FAKE_CONTEXT, 'xy'), matcher.MatchInfo( match.StringMatch('xy'), {'a': matcher.BoundValue(match.StringMatch('y'))}))
def create_match( parsed: PythonParsedFile, matched: Any ) -> Union[LexicalASTMatch, match.StringMatch, match.ObjectMatch]: """Construct the most precise match for an object. This does a type check on `matched` to see if it has lexical information, but ideally this should be knowable at compile-time (if only Python had templates and template specialization). Args: parsed: A ParsedFile. matched: An arbitrary matched object. Returns: A LexicalASTMatch if obj is an AST node with lexical information, a match.StringMatch if matched is a string, or a match.ObjectMatch otherwise. """ if _is_lexical_match(matched): return LexicalASTMatch(matched, parsed.text, matched.first_token, matched.last_token) elif isinstance(matched, six.string_types): return match.StringMatch(string=matched) else: return match.ObjectMatch(matched)
def test_string_match(self): self.assertEqual( formatting.rewrite_templates( parsed_file.ParsedFile('abc', path='path', pragmas=()), collections.OrderedDict([ ('foo', match.SpanMatch('abc', (0, 3))), ('bar', match.StringMatch('xyz')) ]), {'foo': formatting.ShTemplate(r'$bar')}), {'foo': 'xyz'})
def test_negative_index(self): container = ['xyz'] self.assertEqual( base_matchers.HasItem(-1, base_matchers.Bind('a')).match( _FAKE_CONTEXT, container), matcher.MatchInfo( match.ObjectMatch(container), {'a': matcher.BoundValue(match.StringMatch('xyz'))}))
def test_invalid_syntax(self): parsed = matcher.parse_ast('x') m = base_matchers.Bind('x', ast_matchers.Name()) [matchinfo] = matcher.find_iter(m, parsed) template = syntactic_template.PythonTemplate('$x') with self.assertRaises(formatting.RewriteError): template.substitute_match(parsed, matchinfo.match, {'x': match.StringMatch('x y')}),
def test_simple(self): for nonempty_container in (('x', 'y'), ['x', 'y'], {1: 'y'}): with self.subTest(nonempty_container=nonempty_container): self.assertEqual( base_matchers.HasItem(1, base_matchers.Bind('a')).match( _FAKE_CONTEXT, nonempty_container), matcher.MatchInfo( match.ObjectMatch(nonempty_container), {'a': matcher.BoundValue(match.StringMatch('y'))}))
def test_autoparen_outer(self): parsed = matcher.parse_ast('x * 2') m = base_matchers.Bind('x', ast_matchers.Name()) [matchinfo] = matcher.find_iter(m, parsed) template = syntactic_template.PythonTemplate('$x') self.assertEqual( template.substitute_match(parsed, matchinfo.match, {'x': match.StringMatch('x + y')}), '(x + y)', )
def test_submatcher_extraction(self): """Tests that the return values of submatchers are sent to the generator.""" class ValueReturningMatcher(matcher.Matcher): def _match(self, context, candidate): del candidate # unused return matcher.MatchInfo( matcher.create_match(context.parsed_file, 'hello world'), {}) class TestMatcher(matcher.Matcher): @matcher.accumulating_matcher def _match(self, context, candidate): results.append( (yield ValueReturningMatcher().match(context, candidate))) results = [] TestMatcher().match(_FAKE_CONTEXT, 0) self.assertEqual(results, [match.StringMatch('hello world')])
def testStringMatch(self): self.assertEqual( match.StringMatch('hello world'), matcher.create_match(_FAKE_CONTEXT.parsed_file, 'hello world'))
def _match(self, context, candidate): del context, candidate # unused return matcher.MatchInfo(match.StringMatch(self.string))