Skip to content

Commit

Permalink
Extract get_block_string_indentation function
Browse files Browse the repository at this point in the history
  • Loading branch information
Cito committed May 3, 2019
1 parent 230ab92 commit d9a8764
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 10 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ a query language for APIs created by Facebook.
[![Code Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)

The current version 1.0.2 of GraphQL-core-next is up-to-date with GraphQL.js version
14.2.1. All parts of the API are covered by an extensive test suite of currently 1748
14.2.1. All parts of the API are covered by an extensive test suite of currently 1753
unit tests.


Expand Down
36 changes: 28 additions & 8 deletions graphql/language/block_string.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
__all__ = ["dedent_block_string_value", "print_block_string"]
from typing import List

__all__ = [
"dedent_block_string_value",
"print_block_string",
"get_block_string_indentation",
]


def dedent_block_string_value(raw_string: str) -> str:
Expand All @@ -9,28 +15,42 @@ def dedent_block_string_value(raw_string: str) -> str:
This implements the GraphQL spec's BlockStringValue() static algorithm.
"""
# Expand a block string's raw value into independent lines.
lines = raw_string.splitlines()

common_indent = None
for line in lines[1:]:
indent = leading_whitespace(line)
if indent < len(line) and (common_indent is None or indent < common_indent):
common_indent = indent
if common_indent == 0:
break
# Remove common indentation from all lines but first.
common_indent = get_block_string_indentation(lines)

if common_indent:
lines[1:] = [line[common_indent:] for line in lines[1:]]

# Remove leading and trailing blank lines.
while lines and not lines[0].strip():
lines = lines[1:]

while lines and not lines[-1].strip():
lines = lines[:-1]

# Return a string of the lines joined with U+000A.
return "\n".join(lines)


def get_block_string_indentation(lines: List[str]) -> int:
common_indent = None

for line in lines[1:]:
indent = leading_whitespace(line)
if indent == len(line):
continue # skip empty lines

if common_indent is None or indent < common_indent:
common_indent = indent
if common_indent == 0:
break

return 0 if common_indent is None else common_indent


def leading_whitespace(s):
i = 0
n = len(s)
Expand Down
32 changes: 31 additions & 1 deletion tests/language/test_block_string.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from graphql.language.block_string import dedent_block_string_value, print_block_string
from graphql.language.block_string import (
dedent_block_string_value,
print_block_string,
get_block_string_indentation,
)


def join_lines(*args):
Expand Down Expand Up @@ -69,6 +73,32 @@ def does_not_alter_trailing_spaces():
)


def describe_get_block_string_indentation():
def returns_zero_for_an_empty_list():
assert get_block_string_indentation([]) == 0

def do_not_take_first_line_into_account():
assert get_block_string_indentation([" a"]) == 0
assert get_block_string_indentation([" a", " b"]) == 2

def returns_minimal_indentation_length():
assert get_block_string_indentation(["", " a", " b"]) == 1
assert get_block_string_indentation(["", " a", " b"]) == 1
assert get_block_string_indentation(["", " a", " b", "c"]) == 0

def count_both_tab_and_space_as_single_character():
assert get_block_string_indentation(["", "\ta", " b"]) == 1
assert get_block_string_indentation(["", "\t a", " b"]) == 2
assert get_block_string_indentation(["", " \t a", " b"]) == 3

def do_not_take_empty_lines_into_account():
assert get_block_string_indentation((["a", "\t"])) == 0
assert get_block_string_indentation((["a", " "])) == 0
assert get_block_string_indentation((["a", " ", " b"])) == 2
assert get_block_string_indentation((["a", " ", " b"])) == 2
assert get_block_string_indentation((["a", "", " b"])) == 1


def describe_print_block_string():
def by_default_print_block_strings_as_single_line():
s = "one liner"
Expand Down

0 comments on commit d9a8764

Please sign in to comment.