diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..013dd20 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[report] +show_missing = True diff --git a/graphql_query_string_builder/__init__.py b/graphql_query_string_builder/__init__.py index e69de29..eb0432b 100644 --- a/graphql_query_string_builder/__init__.py +++ b/graphql_query_string_builder/__init__.py @@ -0,0 +1,6 @@ +from graphql_query_string_builder.query import Query + + +__all__ = [ + 'Query', +] diff --git a/graphql_query_string_builder/exceptions.py b/graphql_query_string_builder/exceptions.py new file mode 100644 index 0000000..ca18c3f --- /dev/null +++ b/graphql_query_string_builder/exceptions.py @@ -0,0 +1,6 @@ +class GraphqlQueryStringBuilderException(Exception): + pass + + +class ImproperlyConfiguredException(GraphqlQueryStringBuilderException): + pass diff --git a/graphql_query_string_builder/query.py b/graphql_query_string_builder/query.py new file mode 100644 index 0000000..b497c57 --- /dev/null +++ b/graphql_query_string_builder/query.py @@ -0,0 +1,41 @@ +from graphql_query_string_builder.exceptions import ImproperlyConfiguredException + + +class Query(object): + def __init__(self, auto_camel_case=True, **kwargs): + self.auto_camel_case = auto_camel_case + + def _camel_case_string(self, s): + parts = s.split('_') + if len(parts) == 1: + return s + first_part = parts[0] + rest = parts[1:] + camel = [r.title() for r in rest] + return ''.join([first_part] + camel) + + def render_query_string(self, **kwargs): + query_parameters = dict(kwargs) + if len(query_parameters) != 1: + raise ImproperlyConfiguredException( + 'You can only pass in a single kwarg to `render_query_string` at this time', + ) + assert len(query_parameters) == 1 # TODO Switch this to a better exception + key = list(kwargs.keys())[0] + value = list(kwargs.values())[0] + if self.auto_camel_case: + # TODO Camel case values too + key = self._camel_case_string(key) + return str(QueryStringBuilder(key=key, value=value)) + + +class QueryStringBuilder(object): + def __init__(self, key, value): + self.key = key + self.value = value + + def __str__(self): + return 'query {{ {key} {{ {values} }}}}'.format( + key=self.key, + values=' '.join(self.value), + ) diff --git a/graphql_query_string_builder/tests/test_query_string_builder.py b/graphql_query_string_builder/tests/test_query_string_builder.py index 77ea872..2b73486 100644 --- a/graphql_query_string_builder/tests/test_query_string_builder.py +++ b/graphql_query_string_builder/tests/test_query_string_builder.py @@ -1,6 +1,32 @@ from unittest import TestCase +from graphql_query_string_builder import Query +from graphql_query_string_builder.exceptions import ImproperlyConfiguredException + class QueryStringBuilderTestCase(TestCase): - def test(self): - pass + def test_query_string_is_built(self): + query = Query() + self.assertEqual( + query.render_query_string(foo=['id', 'bar']), + 'query { foo { id bar }}', + ) + + def test_camel_case_happens_by_default(self): + query = Query() + self.assertEqual( + query.render_query_string(foo_bar_baz=['id', 'bar']), + 'query { fooBarBaz { id bar }}', + ) + + def test_disabling_camel_case_removes_camel_case(self): + query = Query(auto_camel_case=False) + self.assertEqual( + query.render_query_string(foo_bar_baz=['id', 'bar']), + 'query { foo_bar_baz { id bar }}', + ) + + def test_only_one_kwarg_can_be_passed_to_render_query_string(self): + query = Query() + with self.assertRaises(ImproperlyConfiguredException): + query.render_query_string(foo=1, bar=2) diff --git a/tox.ini b/tox.ini index 5944fe5..efd65a3 100644 --- a/tox.ini +++ b/tox.ini @@ -23,13 +23,13 @@ skipsdist = True # Coverage for python 2.7 and and 3.6 only [testenv:py27-coverage] commands = - nosetests --with-doctest --with-coverage --cover-package graphql_query_string_builder [] + nosetests --with-doctest --with-coverage --cover-erase --cover-branches --cover-package graphql_query_string_builder [] [testenv:py34-coverage] commands = - nosetests --with-doctest --with-coverage --cover-package graphql_query_string_builder [] + nosetests --with-doctest --with-coverage --cover-erase --cover-branches --cover-package graphql_query_string_builder [] [testenv:py36-coverage] commands = - nosetests --with-doctest --with-coverage --cover-package graphql_query_string_builder [] + nosetests --with-doctest --with-coverage --cover-erase --cover-branches --cover-package graphql_query_string_builder [] [testenv:py27pep8] basepython = python2.7