Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: typo in specification_parser #288

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions tools/specification_parser/specification_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def find_rfc_2119_keyword(content):
) is not None:
return rfc_2119_keyword_regex

def parsed_content_to_heirarchy(parsed_content):
def parsed_content_to_hierarchy(parsed_content):
'Turns a bunch of headline & content pairings into a tree of requirements'
content_tree = []
headline_stack = []
Expand Down Expand Up @@ -183,7 +183,7 @@ def parse(markdown_file_path):
with open(markdown_file_path, "r") as markdown_file:
content_finder = re.compile(r'^(?P<level>####+)(?P<headline>[^\n]+)\n+?.*?\n+?(?P<rest>>\s[^#?]*)', re.MULTILINE)
parsed = content_finder.findall(markdown_file.read())
return parsed_content_to_heirarchy(parsed)
return parsed_content_to_hierarchy(parsed)

def write_json_specifications(requirements):
for md_absolute_file_path, requirement_sections in requirements.items():
Expand Down
10 changes: 5 additions & 5 deletions tools/specification_parser/specification_parser_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from specification_parser import (
find_markdown_file_paths,
parse,
parsed_content_to_heirarchy,
parsed_content_to_hierarchy,
gen_node
)

Expand All @@ -22,7 +22,7 @@ def test_parses_content(self):
# another outer headline
'''
parsed_content = content_finder.findall(content)
self.assertEqual(None, parsed_content_to_heirarchy(parsed_content))
self.assertEqual(None, parsed_content_to_hierarchy(parsed_content))

def test_parses_content__with_keywords__no_title(self):
# parsed_content = [('#', ' Hooks', '\n\n'), ('##', ' Overview', '\n\nHooks are a mechanism whereby application developers can add arbitrary behavior\nto flag evaluation. They operate similarly to middleware in many web frameworks.\n\n'), ('###', ' Definitions', '\n\n**Hook**: Application author/integrator-supplied logic that is called by the OpenFeature framework at a specific stage.\n**Stage**: An explicit portion of the flag evaluation lifecycle. e.g. `before` being "before the evaluation is run.\n**Invocation**: A single call to evaluate a flag. `client.getBooleanValue(..)` is an invocation.\n**API**: The global API singleton.\n\n'), ('###', ' Hook context', '\n\nHook context exists to provide hooks with information about the invocation.\n\n'), ('######', ' Requirement 1.1', '\n\n> Hook context **MUST** provide: the flag key, evaluation context, default value and a list of executed hooks by stage.\n\n\n'), ('#####', ' Condition 1.2', '\n\n> If the language type system differentiates between strings, numbers, booleans, and structures.\n\n'), ('######', ' Condition 1.2.1', '\n\n> Condition: You **MUST** provide `flag type`.\n\n\n'), ('#####', ' Requirement 1.2', '\n\n> Hook context **SHOULD** provide: provider, client\n\n\n'), ('#####', ' Requirement 1.3', '\n\n> flag key, flag type, default value properties **MUST** be immutable. If the language does not support immutability, the hook **MUST NOT** modify these properties.\n\n'), ('#####', ' Requirement 1.4', '\n\n> The evaluation context **MUST** be mutable only within the `before` hook.\n\n'), ('###', ' HookHints', '\n\n'), ('#####', ' Requirement 2.1', '\n\n> HookHints **MUST** be a map of objects.\n\n\n'), ('#####', ' Condition 2.2', '\n\n> The implementation language supports a mechanism for marking data as immutable.\n\n'), ('######', ' 2.2.1', '\n\n> Condition: HookHints **MUST** be immutable.\n\n\n'), ('###', ' Hook creation and parameters', '\n\n\n'), ('#####', ' Requirement 3.1', '\n\n> Hooks **MUST** specify at least one stage.\n\n'), ('#####', ' Requirement 3.2', '\n\n> The `before` stage **MUST** run before flag evaluation occurs. It accepts a `hook context` (required) and `state` (optional) as parameters and returns either a `HookContext` or nothing.\n\n```\nHookContext|void before(HookContext, HookHints)\n```\n\n'), ('#####', ' Requirement 3.3', '\n\n> The `after` stage **MUST** run after flag evaluation occurs. It accepts a `hook context` (required), `flag evaluation details` (required) and `HookHints` (optional). It has no return value.\n\n'), ('#####', ' Requirement 3.4', '\n\n> The `error` hook **MUST** run when errors are encountered in the `before` stage, the `after` stage or during flag evaluation. It accepts `hook context` (required), `exception` for what went wrong (required), and `HookHints` (optional). It has no return value.\n\n'), ('#####', ' Requirement 3.5', '\n\n> The `finally` hook **MUST** run after the `before`, `after`, and `error` stages. It accepts a `hook context` (required) and `HookHints` (optional). There is no return value.\n\n'), ('#####', ' Condition 3.6', '\n\n> `finally` is a reserved word in the language.\n\n'), ('######', ' 3.6.1', '\n\n> Condition: If `finally` is a reserved word in the language, `finallyAfter` **SHOULD** be used.\n\n'), ('###', ' Hook registration & ordering', '\n\n'), ('#####', ' Requirement 4.1', "\n\n> The API, Client and invocation **MUST** have a method for registering hooks which accepts `flag evaluation options`\n\n```js\nOpenFeature.addHooks(new Hook1());\n\n//...\n\nClient client = OpenFeature.getClient();\nclient.addHooks(new Hook2());\n`\n//...\n\nclient.getValue('my-flag', 'defaultValue', new Hook3());\n```\n\n"), ('#####', ' Requirement 4.2', '\n\n> Hooks **MUST** be evaluated in the following order:\n> - before: API, Client, Invocation\n> - after: Invocation, Client, API\n> - error (if applicable): Invocation, Client, API\n> - finally: Invocation, Client, API> If an error occurs in the `finally` hook, it **MUST NOT** trigger the `error` hook.\n\n'), ('#####', ' Requirement 4.3', '\n\n> If an error occurs in the `before` or `after` hooks, the `error` hooks **MUST** be invoked.\n\n'), ('#####', ' Requirement 4.4', '\n\n> If an error occurs during the evaluation of `before` or `after` hooks, any remaining hooks in the `before` or `after` stages **MUST NOT** be invoked.\n\n'), ('#####', ' Requirement 4.5', '\n\n> If an error is encountered in the error stage, it **MUST NOT** be returned to the user.\n\n\n'), ('###', ' [Flag evaluation options](../types.md#evaluation-options)', "\n\nUsage might looks something like:\n\n```python\nval = client.get_boolean_value('my-key', False, evaluation_options={\n 'hooks': new MyHook(),\n 'hook_hints': {'side-item': 'onion rings'}\n})\n```\n\n"), ('#####', ' Requirement 5.1', '\n\n> `Flag evalution options` **MUST** contain a list of hooks to evaluate.\n\n'), ('#####', ' Requirement 5.2', '\n\n> `Flag evaluation options` **MAY** contain `HookHints`, a map of data to be provided to hook invocations.\n\n'), ('#####', ' Requirement 5.3', '\n\n> `HookHints` **MUST** be passed to each hook through a parameter. It is merged into the object in the precedence order API -> Client -> Invocation (last wins).\n\n```python\nhook_hints = {}\nfor source in [API, Client, Invocation]:\n for key, value in source:\n hook-hints[key] = value\n```\n\n'), ('#####', ' Requirement 5.4', '\n\n> The hook **MUST NOT** alter the `HookHints` object.\n\n'), ('###', ' Hook evaluation', '\n\n'), ('#####', ' Requirement 6.1', '\n\n> `HookHints` **MUST** passed between each hook.\n')]
Expand All @@ -34,7 +34,7 @@ def test_parses_content__with_keywords__no_title(self):
# another outer headline
'''
parsed_content = content_finder.findall(content)
self.assertEqual(None, parsed_content_to_heirarchy(parsed_content))
self.assertEqual(None, parsed_content_to_hierarchy(parsed_content))

def test_parses_content__with_title__no_keywords(self):
# parsed_content = [('#', ' Hooks', '\n\n'), ('##', ' Overview', '\n\nHooks are a mechanism whereby application developers can add arbitrary behavior\nto flag evaluation. They operate similarly to middleware in many web frameworks.\n\n'), ('###', ' Definitions', '\n\n**Hook**: Application author/integrator-supplied logic that is called by the OpenFeature framework at a specific stage.\n**Stage**: An explicit portion of the flag evaluation lifecycle. e.g. `before` being "before the evaluation is run.\n**Invocation**: A single call to evaluate a flag. `client.getBooleanValue(..)` is an invocation.\n**API**: The global API singleton.\n\n'), ('###', ' Hook context', '\n\nHook context exists to provide hooks with information about the invocation.\n\n'), ('######', ' Requirement 1.1', '\n\n> Hook context **MUST** provide: the flag key, evaluation context, default value and a list of executed hooks by stage.\n\n\n'), ('#####', ' Condition 1.2', '\n\n> If the language type system differentiates between strings, numbers, booleans, and structures.\n\n'), ('######', ' Condition 1.2.1', '\n\n> Condition: You **MUST** provide `flag type`.\n\n\n'), ('#####', ' Requirement 1.2', '\n\n> Hook context **SHOULD** provide: provider, client\n\n\n'), ('#####', ' Requirement 1.3', '\n\n> flag key, flag type, default value properties **MUST** be immutable. If the language does not support immutability, the hook **MUST NOT** modify these properties.\n\n'), ('#####', ' Requirement 1.4', '\n\n> The evaluation context **MUST** be mutable only within the `before` hook.\n\n'), ('###', ' HookHints', '\n\n'), ('#####', ' Requirement 2.1', '\n\n> HookHints **MUST** be a map of objects.\n\n\n'), ('#####', ' Condition 2.2', '\n\n> The implementation language supports a mechanism for marking data as immutable.\n\n'), ('######', ' 2.2.1', '\n\n> Condition: HookHints **MUST** be immutable.\n\n\n'), ('###', ' Hook creation and parameters', '\n\n\n'), ('#####', ' Requirement 3.1', '\n\n> Hooks **MUST** specify at least one stage.\n\n'), ('#####', ' Requirement 3.2', '\n\n> The `before` stage **MUST** run before flag evaluation occurs. It accepts a `hook context` (required) and `state` (optional) as parameters and returns either a `HookContext` or nothing.\n\n```\nHookContext|void before(HookContext, HookHints)\n```\n\n'), ('#####', ' Requirement 3.3', '\n\n> The `after` stage **MUST** run after flag evaluation occurs. It accepts a `hook context` (required), `flag evaluation details` (required) and `HookHints` (optional). It has no return value.\n\n'), ('#####', ' Requirement 3.4', '\n\n> The `error` hook **MUST** run when errors are encountered in the `before` stage, the `after` stage or during flag evaluation. It accepts `hook context` (required), `exception` for what went wrong (required), and `HookHints` (optional). It has no return value.\n\n'), ('#####', ' Requirement 3.5', '\n\n> The `finally` hook **MUST** run after the `before`, `after`, and `error` stages. It accepts a `hook context` (required) and `HookHints` (optional). There is no return value.\n\n'), ('#####', ' Condition 3.6', '\n\n> `finally` is a reserved word in the language.\n\n'), ('######', ' 3.6.1', '\n\n> Condition: If `finally` is a reserved word in the language, `finallyAfter` **SHOULD** be used.\n\n'), ('###', ' Hook registration & ordering', '\n\n'), ('#####', ' Requirement 4.1', "\n\n> The API, Client and invocation **MUST** have a method for registering hooks which accepts `flag evaluation options`\n\n```js\nOpenFeature.addHooks(new Hook1());\n\n//...\n\nClient client = OpenFeature.getClient();\nclient.addHooks(new Hook2());\n`\n//...\n\nclient.getValue('my-flag', 'defaultValue', new Hook3());\n```\n\n"), ('#####', ' Requirement 4.2', '\n\n> Hooks **MUST** be evaluated in the following order:\n> - before: API, Client, Invocation\n> - after: Invocation, Client, API\n> - error (if applicable): Invocation, Client, API\n> - finally: Invocation, Client, API> If an error occurs in the `finally` hook, it **MUST NOT** trigger the `error` hook.\n\n'), ('#####', ' Requirement 4.3', '\n\n> If an error occurs in the `before` or `after` hooks, the `error` hooks **MUST** be invoked.\n\n'), ('#####', ' Requirement 4.4', '\n\n> If an error occurs during the evaluation of `before` or `after` hooks, any remaining hooks in the `before` or `after` stages **MUST NOT** be invoked.\n\n'), ('#####', ' Requirement 4.5', '\n\n> If an error is encountered in the error stage, it **MUST NOT** be returned to the user.\n\n\n'), ('###', ' [Flag evaluation options](../types.md#evaluation-options)', "\n\nUsage might looks something like:\n\n```python\nval = client.get_boolean_value('my-key', False, evaluation_options={\n 'hooks': new MyHook(),\n 'hook_hints': {'side-item': 'onion rings'}\n})\n```\n\n"), ('#####', ' Requirement 5.1', '\n\n> `Flag evalution options` **MUST** contain a list of hooks to evaluate.\n\n'), ('#####', ' Requirement 5.2', '\n\n> `Flag evaluation options` **MAY** contain `HookHints`, a map of data to be provided to hook invocations.\n\n'), ('#####', ' Requirement 5.3', '\n\n> `HookHints` **MUST** be passed to each hook through a parameter. It is merged into the object in the precedence order API -> Client -> Invocation (last wins).\n\n```python\nhook_hints = {}\nfor source in [API, Client, Invocation]:\n for key, value in source:\n hook-hints[key] = value\n```\n\n'), ('#####', ' Requirement 5.4', '\n\n> The hook **MUST NOT** alter the `HookHints` object.\n\n'), ('###', ' Hook evaluation', '\n\n'), ('#####', ' Requirement 6.1', '\n\n> `HookHints` **MUST** passed between each hook.\n')]
Expand All @@ -47,7 +47,7 @@ def test_parses_content__with_title__no_keywords(self):
'''
parsed_content = content_finder.findall(content)

output = parsed_content_to_heirarchy(parsed_content)
output = parsed_content_to_hierarchy(parsed_content)
self.assertEqual([
{
'id': '1.1',
Expand All @@ -74,7 +74,7 @@ def test_parses_content__siblings(self):
'''
parsed_content = content_finder.findall(content)

output = parsed_content_to_heirarchy(parsed_content)
output = parsed_content_to_hierarchy(parsed_content)
self.assertEqual([
{
'id': '1.1',
Expand Down
Loading