Skip to content

Commit

Permalink
lookup arg parse handle = in value (#281)
Browse files Browse the repository at this point in the history
* convert tests to pytest

* lookup arg parser support `=` in value, add more tests for parse

* update changelog
  • Loading branch information
ITProKyle authored May 15, 2020
1 parent 39c7f6b commit a6141db
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 59 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

### Fixed
- the value of `environments` is once again used to determine if a serverless module should be skipped
- lookup argument values can now contain `=` without raising _"too many values to unpack"_

## [1.7.3] - 2020-04-29
### Fixed
Expand Down
2 changes: 1 addition & 1 deletion runway/lookups/handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ def _parse_args(cls, args):
"""
split_args = args.split(',')
return {key.strip(): value.strip() for key, value in
[arg.split('=') for arg in split_args]}
[arg.split('=', 1) for arg in split_args]}

@classmethod
def load(cls, value, parser=None, **kwargs):
Expand Down
106 changes: 48 additions & 58 deletions tests/lookups/handlers/test_base.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
"""Tests for lookup handler base class."""
# pytest: disable=no-self-use
# pylint: disable=no-self-use
import json
from unittest import TestCase

import pytest
import yaml

from runway.lookups.handlers.base import LookupHandler
from runway.util import MutableMap


class TestLookupHandler(TestCase):
class TestLookupHandler(object):
"""Tests for LookupHandler."""

def test_abstract_handle(self):
"""Handle should not be implimented."""
with self.assertRaises(NotImplementedError):
with pytest.raises(NotImplementedError):
LookupHandler.handle(None, None)

def test_dependencies(self):
Expand Down Expand Up @@ -63,7 +63,7 @@ def test_format_results(self):
mute_map, get='nested.bool', transform='str'
) == '"True"'

with self.assertRaises(TypeError):
with pytest.raises(TypeError):
LookupHandler.format_results(['something'], get='key')

def test_load_no_parser(self):
Expand All @@ -76,37 +76,34 @@ def test_load_list(self):
assert LookupHandler.load(json.dumps(value), parser='json') == value
assert LookupHandler.load(yaml.dump(value), parser='yaml') == value

def test_parse(self):
"""Basic value parsing."""
expected_query = 'my_query'

result_query, result_args = LookupHandler.parse(expected_query)

self.assertEqual(result_query, expected_query)
self.assertEqual(result_args, {})

def test_parse_args(self):
"""Parse query and args from value."""
expected_args = {
'key1': 'val1'
}
expected_query = 'my_query'
value = '{}::{}'.format(expected_query, ','.join([
'{}={}'.format(key, val) for key, val in expected_args.items()
]))

result_query, result_args = LookupHandler.parse(value)

self.assertEqual(result_query, expected_query)
self.assertEqual(result_args, expected_args)
@pytest.mark.parametrize('query, raw_args, expected_args', [
('query', None, {}),
('query', 'key1=val1', {'key1': 'val1'}),
('query.something', 'key1=val1,key2=val2', {'key1': 'val1',
'key2': 'val2'}),
('query.something', 'key1=val1, key2=val2', {'key1': 'val1',
'key2': 'val2'}),
('query-something', 'key1=val-1', {'key1': 'val-1'}),
('query:something', 'key1=val:1', {'key1': 'val:1'}),
('query=something', 'key1=val=1', {'key1': 'val=1'}),
('query==something', 'key1=val==1', {'key1': 'val==1'}),
])
def test_parse(self, query, raw_args, expected_args):
"""Test parse."""
value = '{}::{}'.format(query, raw_args)
result_query, result_args = LookupHandler.parse(value if raw_args
else query)
assert result_query == query
assert result_args == expected_args

def test_transform_bool_to_bool(self):
"""Bool should be returned as is."""
result_true = LookupHandler.transform(True, to_type='bool')
result_false = LookupHandler.transform(False, to_type='bool')

self.assertTrue(result_true)
self.assertFalse(result_false)
assert isinstance(result_true, bool) and isinstance(result_false, bool)
assert result_true
assert not result_false

def test_transform_no_type(self):
"""Test transform with no type."""
Expand All @@ -121,52 +118,45 @@ def test_transform_str_to_bool(self):
result_true = LookupHandler.transform('true', to_type='bool')
result_false = LookupHandler.transform('false', to_type='bool')

self.assertTrue(result_true)
self.assertFalse(result_false)
assert isinstance(result_true, bool) and isinstance(result_false, bool)
assert result_true
assert not result_false

def test_transform_type_check(self):
"""Transform to bool type check."""
with self.assertRaises(TypeError, msg='dict should raise an error'):
with pytest.raises(TypeError):
LookupHandler.transform({'key1': 'val1'}, to_type='bool')

with self.assertRaises(TypeError, msg='list should raise an error'):
with pytest.raises(TypeError):
LookupHandler.transform(['li1'], to_type='bool')

with self.assertRaises(TypeError, msg='number should raise an error'):
with pytest.raises(TypeError):
LookupHandler.transform(10, to_type='bool')

with self.assertRaises(TypeError, msg='float should raise an error'):
with pytest.raises(TypeError):
LookupHandler.transform(10.0, to_type='bool')

with self.assertRaises(TypeError, msg='NoneType should raise an error'):
with pytest.raises(TypeError):
LookupHandler.transform(None, to_type='bool')

def test_transform_str_direct(self):
"""Test types that are directly transformed to strings."""
self.assertEqual(LookupHandler.transform('test', 'str'), 'test')
self.assertEqual(LookupHandler.transform({'key1': 'val1'}, 'str'),
json.dumps(json.dumps({'key1': 'val1'}, indent=0)))
self.assertEqual(LookupHandler.transform(True, 'str'), '"True"')
assert LookupHandler.transform('test', 'str') == 'test'
assert LookupHandler.transform({'key1': 'val1'}, 'str') == \
json.dumps(json.dumps({'key1': 'val1'}, indent=0))
assert LookupHandler.transform(True, 'str') == '"True"'

def test_transform_str_list(self):
"""Test list type joined to create string."""
self.assertEqual(
LookupHandler.transform(['val1', 'val2'], to_type='str'),
'val1,val2'
)
self.assertEqual(
LookupHandler.transform(set(['val', 'val']), to_type='str'),
'val'
)
self.assertEqual(
LookupHandler.transform(('val1', 'val2'), to_type='str'),
'val1,val2'
)
assert LookupHandler.transform(['val1', 'val2'],
to_type='str') == 'val1,val2'
assert LookupHandler.transform(set(['val', 'val']),
to_type='str') == 'val'
assert LookupHandler.transform(('val1', 'val2'),
to_type='str') == 'val1,val2'

def test_transform_str_list_delimiter(self):
"""Test list to string with a specified delimiter."""
self.assertEqual(
LookupHandler.transform(['val1', 'val2'], to_type='str',
delimiter='|'),
'val1|val2'
)
assert LookupHandler.transform(
['val1', 'val2'], to_type='str', delimiter='|'
) == 'val1|val2'

0 comments on commit a6141db

Please sign in to comment.