Fixed #32 : concept groups are not correctly updated
Fixed #35 : Refactor test helper class (CNC, CC, CIO) Fixed #36 : Concept values are not used when declared with variable expression Fixed #37 : Objects in memory lose their values are restart Fixed #38 : func(a=b, c) (which is not allowed) raise an exception
This commit is contained in:
+842
-31
@@ -1,13 +1,16 @@
|
||||
import ast
|
||||
from dataclasses import dataclass
|
||||
from typing import Union
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept
|
||||
from core.builtin_helpers import CreateObjectIdentifiers
|
||||
from core.concept import CC, Concept, ConceptParts, DoNotResolve, CIO, CMV
|
||||
from core.concept import Concept, ConceptParts, DoNotResolve, AllConceptParts
|
||||
from core.rule import Rule
|
||||
from core.tokenizer import Tokenizer, TokenKind, Token
|
||||
from core.utils import get_text_from_tokens, tokens_index
|
||||
from parsers.BaseNodeParser import scnode, utnode, cnode, SCWC, CNC, short_cnode, CN, UTN, \
|
||||
SCN, RN, UnrecognizedTokensNode, SourceCodeNode
|
||||
from core.utils import get_text_from_tokens, tokens_index, str_concept
|
||||
from parsers.BaseNodeParser import UnrecognizedTokensNode, SourceCodeNode, RuleNode, ConceptNode, \
|
||||
SourceCodeWithConceptNode
|
||||
from parsers.FunctionParser import FunctionNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
from parsers.SyaNodeParser import SyaConceptParserHelper
|
||||
from parsers.expressions import NameExprNode, AndNode, OrNode, NotNode, VariableNode, ComparisonNode, ComparisonType
|
||||
@@ -115,6 +118,825 @@ class NIN: # for NOT INT
|
||||
source = None
|
||||
|
||||
|
||||
class CC:
|
||||
"""
|
||||
Concept class for test purpose
|
||||
CC means concept for compiled (or concept with compiled)
|
||||
It matches a concept if the compiles are equals
|
||||
"""
|
||||
|
||||
# The only properties that are testes are concept_key and compiled
|
||||
# The other properties (concept, source, start and end)
|
||||
# are used in tests/parsers/parsers_utils.py to help creating helper objects
|
||||
|
||||
def __init__(self, concept, source=None, exclude_body=False, **kwargs):
|
||||
self.concept_key = concept.key if isinstance(concept, Concept) else concept
|
||||
self.compiled = kwargs
|
||||
self.concept = concept if isinstance(concept, Concept) else None
|
||||
self.source = source # to use when the key is different from the sub str to search when filling start and stop
|
||||
self.start = None # for debug purpose, indicate where the concept starts
|
||||
self.end = None # for debug purpose, indicate where the concept ends
|
||||
self.exclude_body = exclude_body
|
||||
|
||||
if "body" in self.compiled:
|
||||
self.compiled[ConceptParts.BODY] = self.compiled["body"]
|
||||
del self.compiled["body"]
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if isinstance(other, Concept):
|
||||
if other.key != self.concept_key:
|
||||
return False
|
||||
if self.exclude_body:
|
||||
to_compare = {k: v for k, v in other.get_compiled().items() if k != ConceptParts.BODY}
|
||||
else:
|
||||
to_compare = other.get_compiled()
|
||||
if self.compiled == to_compare:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
if not isinstance(other, CC):
|
||||
return False
|
||||
|
||||
if self.concept_key != other.concept_key:
|
||||
return False
|
||||
|
||||
return self.compiled == other.compiled
|
||||
|
||||
def __hash__(self):
|
||||
if self.concept:
|
||||
return hash(self.concept)
|
||||
return hash(self.concept_key)
|
||||
|
||||
def __repr__(self):
|
||||
if self.concept:
|
||||
txt = f"CC(concept='{self.concept}'"
|
||||
else:
|
||||
txt = f"CC(concept_key='{self.concept_key}'"
|
||||
|
||||
for k, v in self.compiled.items():
|
||||
txt += f", {k}='{v}'"
|
||||
return txt + ")"
|
||||
|
||||
def fix_pos(self, node):
|
||||
start = node.start if hasattr(node, "start") else \
|
||||
node[0] if isinstance(node, tuple) else None
|
||||
end = node.end if hasattr(node, "end") else \
|
||||
node[1] if isinstance(node, tuple) else None
|
||||
|
||||
if start is not None:
|
||||
if self.start is None or start < self.start:
|
||||
self.start = start
|
||||
|
||||
if end is not None:
|
||||
if self.end is None or end > self.end:
|
||||
self.end = end
|
||||
return self
|
||||
|
||||
def transform_real_obj(self, other, to_compare_delegate):
|
||||
"""
|
||||
Transform other into CNC, to ease the comparison
|
||||
:param other:
|
||||
:param to_compare_delegate:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(other, CC):
|
||||
return other
|
||||
|
||||
if isinstance(other, Concept):
|
||||
if self.exclude_body:
|
||||
compiled = {k: v for k, v in other.get_compiled().items() if k != ConceptParts.BODY}
|
||||
else:
|
||||
compiled = other.get_compiled()
|
||||
|
||||
self_compile_to_use = self.compiled or compiled
|
||||
|
||||
compiled = to_compare_delegate(self_compile_to_use, compiled, to_compare_delegate)
|
||||
return CC(other,
|
||||
self.source,
|
||||
self.exclude_body,
|
||||
**compiled)
|
||||
|
||||
raise NotImplementedError(f"CC, {other=}")
|
||||
|
||||
|
||||
class CB:
|
||||
"""
|
||||
Concept with body only
|
||||
Test class that tests only the body of the concept
|
||||
"""
|
||||
|
||||
def __init__(self, concept: Union[str, Concept], body: object):
|
||||
self.concept_key = concept.key if isinstance(concept, Concept) else concept
|
||||
self.concept = concept if isinstance(concept, Concept) else None
|
||||
self.body = body
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, CB):
|
||||
return False
|
||||
|
||||
return self.concept_key == other.concept_key and self.body == other.body
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.concept, self.body))
|
||||
|
||||
def __repr__(self):
|
||||
concept_debug = f"concept={self.concept}" if self.concept else f"concept_key={self.concept_key}"
|
||||
return f"CB({concept_debug}, body='{self.body}')"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
if isinstance(other, CB):
|
||||
return other
|
||||
|
||||
if isinstance(other, Concept):
|
||||
concept = other.key if not self.concept else other
|
||||
if isinstance(other.body, Concept):
|
||||
body = get_test_obj_delegate(other.body, self.body, get_test_obj_delegate)
|
||||
else:
|
||||
body = other.body
|
||||
return CB(concept, body)
|
||||
|
||||
raise NotImplementedError(f"CB, {other=}")
|
||||
|
||||
|
||||
class CV:
|
||||
"""
|
||||
Concept with all values
|
||||
Test class that tests all the values (not the metadata, so not the properties) of a concept
|
||||
"""
|
||||
|
||||
def __init__(self, concept, **kwargs):
|
||||
self.concept_key = concept.key if isinstance(concept, Concept) else concept
|
||||
self.concept = concept if isinstance(concept, Concept) else None
|
||||
self.values = {}
|
||||
for k, v in kwargs.items():
|
||||
if f"#{k}#" in AllConceptParts:
|
||||
self.values[f"#{k}#"] = v
|
||||
else:
|
||||
self.values[k] = v
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, CV):
|
||||
return False
|
||||
|
||||
return self.concept_key == other.concept_key and self.values == other.values
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.concept_key, self.values))
|
||||
|
||||
def __repr__(self):
|
||||
concept_debug = f"concept={self.concept}" if self.concept else f"concept_key={self.concept_key}"
|
||||
return f"CV({concept_debug}, values={self.values})"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
if isinstance(other, CV):
|
||||
return other
|
||||
|
||||
if isinstance(other, Concept):
|
||||
concept = other.key if not self.concept else other
|
||||
values = get_test_obj_delegate(other.values(), self.values, get_test_obj_delegate)
|
||||
return CV(concept, **values)
|
||||
|
||||
raise NotImplementedError(f"CV, {other=}")
|
||||
|
||||
|
||||
class CMV:
|
||||
"""
|
||||
Concept with metadata variables
|
||||
CMV stands for Concept Metadata Variables
|
||||
Test class that only compare the key and the metadata variables
|
||||
"""
|
||||
|
||||
def __init__(self, concept, **kwargs):
|
||||
self.concept_key = concept.key if isinstance(concept, Concept) else concept
|
||||
self.concept = concept if isinstance(concept, Concept) else None
|
||||
self.variables = kwargs
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if not isinstance(other, CMV):
|
||||
return False
|
||||
|
||||
if self.concept_key != other.concept_key:
|
||||
return False
|
||||
|
||||
return self.variables == other.variables
|
||||
|
||||
def __hash__(self):
|
||||
if self.concept:
|
||||
return hash(self.concept)
|
||||
return hash(self.concept_key)
|
||||
|
||||
def __repr__(self):
|
||||
if self.concept:
|
||||
txt = f"CMV(concept='{self.concept}'"
|
||||
else:
|
||||
txt = f"CMV(concept_key='{self.concept_key}'"
|
||||
|
||||
for k, v in self.variables.items():
|
||||
txt += f", {k}='{v}'"
|
||||
return txt + ")"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
if isinstance(other, CMV):
|
||||
return other
|
||||
|
||||
if isinstance(other, Concept):
|
||||
concept = other.key if not self.concept else other
|
||||
variables = {name: value for name, value in other.get_metadata().variables}
|
||||
return CMV(concept, **variables)
|
||||
|
||||
raise NotImplementedError(f"CMV, {other=}")
|
||||
|
||||
|
||||
class CIO:
|
||||
"""
|
||||
Concept id only
|
||||
only test the id
|
||||
"""
|
||||
|
||||
def __init__(self, concept, source=None):
|
||||
if isinstance(concept, str):
|
||||
self.concept_name = concept
|
||||
self.concept_id = None
|
||||
self.concept = None
|
||||
elif isinstance(concept, Concept):
|
||||
self.concept_id = concept.id
|
||||
self.concept = concept
|
||||
self.source = source
|
||||
self.start = None
|
||||
self.end = None
|
||||
|
||||
def set_concept(self, concept):
|
||||
self.concept = concept
|
||||
self.concept_id = concept.id
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if not isinstance(other, CIO):
|
||||
return False
|
||||
|
||||
return self.concept_id == other.concept_id
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.concept_id)
|
||||
|
||||
def __repr__(self):
|
||||
return f"CIO(concept='{self.concept}')" if self.concept else f"CIO(name='{self.concept_name}')"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
if isinstance(other, CIO):
|
||||
return other
|
||||
|
||||
if isinstance(other, Concept):
|
||||
return CIO(other)
|
||||
|
||||
raise NotImplementedError(f"CIO, {other=}")
|
||||
|
||||
|
||||
class HelperWithPos:
|
||||
def __init__(self, start=None, end=None):
|
||||
self.start = start
|
||||
self.end = end
|
||||
|
||||
self.start_is_fixed = start is not None
|
||||
self.end_is_fixed = end is not None
|
||||
|
||||
def fix_pos(self, node):
|
||||
if not self.start_is_fixed:
|
||||
start = node.start if hasattr(node, "start") else \
|
||||
node[0] if isinstance(node, tuple) else None
|
||||
|
||||
if start is not None and (self.start is None or start < self.start):
|
||||
self.start = start
|
||||
|
||||
if not self.end_is_fixed:
|
||||
end = node.end if hasattr(node, "end") else \
|
||||
node[1] if isinstance(node, tuple) else None
|
||||
|
||||
if end is not None and (self.end is None or end > self.end):
|
||||
self.end = end
|
||||
return self
|
||||
|
||||
|
||||
class SCN(HelperWithPos):
|
||||
"""
|
||||
SourceCodeNode tester class
|
||||
It matches with SourceCodeNode but with less constraints
|
||||
|
||||
SCN == SourceCodeNode if source, start, end (start and end are not validated when None)
|
||||
"""
|
||||
|
||||
def __init__(self, source, start=None, end=None):
|
||||
super().__init__(start, end)
|
||||
self.source = source
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if isinstance(other, SourceCodeNode):
|
||||
if self.source != other.source:
|
||||
return False
|
||||
if self.start is not None and self.start != other.start:
|
||||
return False
|
||||
if self.end is not None and self.end != other.end:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if not isinstance(other, SCN):
|
||||
return False
|
||||
|
||||
return self.source == other.source and \
|
||||
self.start == other.start and \
|
||||
self.end == other.end
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.source, self.start, self.end))
|
||||
|
||||
def __repr__(self):
|
||||
txt = f"SCN(source='{self.source}'"
|
||||
if self.start is not None:
|
||||
txt += f", start={self.start}"
|
||||
if self.end is not None:
|
||||
txt += f", end={self.end}"
|
||||
return txt + ")"
|
||||
|
||||
def transform_real_obj(self, other, to_compare_delegate):
|
||||
"""
|
||||
Transform other into CNC, to ease the comparison
|
||||
:param other:
|
||||
:param to_compare_delegate:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(other, SCN):
|
||||
return other
|
||||
|
||||
if isinstance(other, SourceCodeNode):
|
||||
return SCN(other.source,
|
||||
other.start if self.start is not None else None,
|
||||
other.end if self.end is not None else None)
|
||||
|
||||
raise NotImplementedError(f"SCN, {other=}")
|
||||
|
||||
|
||||
class SCWC(HelperWithPos):
|
||||
"""
|
||||
SourceNodeWithConcept tester class
|
||||
It matches with a SourceNodeWithConcept
|
||||
but it's easier to instantiate during the tests
|
||||
"""
|
||||
|
||||
def __init__(self, first, last, *args):
|
||||
super().__init__(None, None)
|
||||
self.first = first
|
||||
self.last = last
|
||||
self.content = list(args)
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if isinstance(other, SourceCodeWithConceptNode):
|
||||
if self.first != other.first:
|
||||
return False
|
||||
|
||||
if self.last != other.last:
|
||||
return False
|
||||
|
||||
if len(self.content) != len(other.nodes):
|
||||
return False
|
||||
|
||||
for self_node, other_node in zip(self.content, other.nodes):
|
||||
if self_node != other_node:
|
||||
return False
|
||||
|
||||
# at last
|
||||
return True
|
||||
|
||||
if not isinstance(other, SCWC):
|
||||
return False
|
||||
|
||||
return (self.start == other.start and
|
||||
self.end == other.end and
|
||||
self.first == other.first and
|
||||
self.last == other.last and
|
||||
self.content == other.content)
|
||||
|
||||
def __repr__(self):
|
||||
txt = "SCWC("
|
||||
if self.start is not None:
|
||||
txt += f"start={self.start}"
|
||||
if self.end is not None:
|
||||
txt += f", end={self.end}"
|
||||
for item in [self.first, self.last, *self.content]:
|
||||
txt += f", {item}"
|
||||
return txt + ")"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
"""
|
||||
Transform other into CNC, to ease the comparison
|
||||
:param other:
|
||||
:param get_test_obj_delegate:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(other, SCWC):
|
||||
return other
|
||||
|
||||
if isinstance(other, SourceCodeWithConceptNode):
|
||||
first = get_test_obj_delegate(other.first, self.first)
|
||||
last = get_test_obj_delegate(other.last, self.last)
|
||||
content = [get_test_obj_delegate(r, t) for r, t in zip(other.nodes, self.content)]
|
||||
res = SCWC(first, last, *content)
|
||||
res.start = other.start
|
||||
res.end = other.end
|
||||
return res
|
||||
|
||||
raise NotImplementedError(f"SCWC, {other=}")
|
||||
|
||||
@property
|
||||
def source(self):
|
||||
"""
|
||||
this code is a copy and paste from SourceCodeWithConceptNode.pseudo_fix_source
|
||||
TODO: create a common function or whatever...
|
||||
:return:
|
||||
"""
|
||||
source = self.first.source if hasattr(self.first, "source") else self.first
|
||||
for n in self.content:
|
||||
source += " "
|
||||
if hasattr(n, "source"):
|
||||
source += n.source
|
||||
elif hasattr(n, "concept"):
|
||||
source += str(n.concept)
|
||||
else:
|
||||
source += " unknown"
|
||||
source += self.last.source if hasattr(self.last, "source") else self.last
|
||||
return source
|
||||
|
||||
|
||||
class CN(HelperWithPos):
|
||||
"""
|
||||
ConceptNode tester class
|
||||
It matches with ConceptNode but with less constraints
|
||||
|
||||
CN == ConceptNode if concept key, start, end and source are the same
|
||||
"""
|
||||
|
||||
def __init__(self, concept, source=None, start=None, end=None):
|
||||
"""
|
||||
|
||||
:param concept: Concept or concept_key (only the key is used anyway)
|
||||
:param start:
|
||||
:param end:
|
||||
:param source:
|
||||
"""
|
||||
super().__init__(start, end)
|
||||
self.concept_key = concept.key if isinstance(concept, Concept) else concept
|
||||
self.source = source
|
||||
self.concept = concept if isinstance(concept, Concept) else None
|
||||
|
||||
def fix_source(self, str_tokens):
|
||||
self.source = "".join(str_tokens)
|
||||
return self
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if not isinstance(other, CN):
|
||||
return False
|
||||
|
||||
return self.concept_key == other.concept_key and \
|
||||
self.start == other.start and \
|
||||
self.end == other.end and \
|
||||
self.source == other.source
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.concept_key, self.start, self.end, self.source))
|
||||
|
||||
def __repr__(self):
|
||||
if self.concept:
|
||||
txt = f"CN(concept='{self.concept}'"
|
||||
else:
|
||||
txt = f"CN(concept_key='{self.concept_key}'"
|
||||
txt += f", source='{self.source}'"
|
||||
if self.start is not None:
|
||||
txt += f", start={self.start}"
|
||||
if self.end is not None:
|
||||
txt += f", end={self.end}"
|
||||
return txt + ")"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
"""
|
||||
Transform other into CNC, to ease the comparison
|
||||
:param other:
|
||||
:param get_test_obj_delegate:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(other, CN):
|
||||
return other
|
||||
|
||||
if isinstance(other, ConceptNode):
|
||||
return CN(other.concept,
|
||||
other.source if self.source is not None else None,
|
||||
other.start if self.start is not None else None,
|
||||
other.end if self.end is not None else None)
|
||||
|
||||
raise NotImplementedError(f"CN, {other=}")
|
||||
|
||||
|
||||
class CNC(CN):
|
||||
"""
|
||||
ConceptNode for Compiled tester class
|
||||
It matches with ConceptNode
|
||||
But focuses on the 'compiled' property of the concept
|
||||
|
||||
CNC == ConceptNode if CNC.get_compiled() == ConceptNode.concept.get_compiled()
|
||||
"""
|
||||
|
||||
def __init__(self, concept_key, source=None, start=None, end=None, exclude_body=False, **kwargs):
|
||||
super().__init__(concept_key, source, start, end)
|
||||
self.compiled = kwargs
|
||||
self.exclude_body = exclude_body
|
||||
if "body" in self.compiled:
|
||||
self.compiled[ConceptParts.BODY] = self.compiled["body"]
|
||||
del self.compiled["body"]
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if not isinstance(other, CNC):
|
||||
return False
|
||||
|
||||
return self.concept_key == other.concept_key and \
|
||||
self.start == other.start and \
|
||||
self.end == other.end and \
|
||||
self.source == other.source and \
|
||||
self.compiled == other.compiled
|
||||
|
||||
def __repr__(self):
|
||||
if self.concept:
|
||||
txt = f"CNC(concept='{self.concept}'"
|
||||
else:
|
||||
txt = f"CNC(concept_key='{self.concept_key}'"
|
||||
txt += f", source='{self.source}'"
|
||||
if self.start is not None:
|
||||
txt += f", start={self.start}"
|
||||
if self.end is not None:
|
||||
txt += f", end={self.end}"
|
||||
|
||||
for k, v in self.compiled.items():
|
||||
txt += f", {k}='{v}'"
|
||||
return txt + ")"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
"""
|
||||
Transform other into CNC, to ease the comparison
|
||||
:param other:
|
||||
:param get_test_obj_delegate:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(other, CNC):
|
||||
return other
|
||||
|
||||
if isinstance(other, ConceptNode):
|
||||
if self.exclude_body:
|
||||
compiled = {k: v for k, v in other.concept.get_compiled().items() if k != ConceptParts.BODY}
|
||||
else:
|
||||
compiled = other.concept.get_compiled()
|
||||
|
||||
self_compile_to_use = self.compiled or compiled
|
||||
|
||||
compiled = get_test_obj_delegate(self_compile_to_use, compiled, get_test_obj_delegate)
|
||||
return CNC(other.concept,
|
||||
other.source if self.source is not None else None,
|
||||
other.start if self.start is not None else None,
|
||||
other.end if self.end is not None else None,
|
||||
self.exclude_body,
|
||||
**compiled)
|
||||
|
||||
raise NotImplementedError(f"CNC, {other=}")
|
||||
|
||||
|
||||
class UTN(HelperWithPos):
|
||||
"""
|
||||
Tester class for UnrecognizedTokenNode
|
||||
compare the source, and start, end if defined
|
||||
"""
|
||||
|
||||
def __init__(self, source, start=None, end=None):
|
||||
"""
|
||||
:param source:
|
||||
:param start:
|
||||
:param end:
|
||||
"""
|
||||
super().__init__(start, end)
|
||||
self.source = source
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if isinstance(other, UnrecognizedTokensNode):
|
||||
return self.start == other.start and \
|
||||
self.end == other.end and \
|
||||
self.source == other.source
|
||||
|
||||
if not isinstance(other, UTN):
|
||||
return False
|
||||
|
||||
return self.start == other.start and \
|
||||
self.end == other.end and \
|
||||
self.source == other.source
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.source, self.start, self.end))
|
||||
|
||||
def __repr__(self):
|
||||
txt = f"UTN(source='{self.source}'"
|
||||
if self.start is not None:
|
||||
txt += f", start={self.start}"
|
||||
if self.end is not None:
|
||||
txt += f", end={self.end}"
|
||||
return txt + ")"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
"""
|
||||
Transform other into CNC, to ease the comparison
|
||||
:param other:
|
||||
:param get_test_obj_delegate:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(other, UTN):
|
||||
return other
|
||||
|
||||
if isinstance(other, UnrecognizedTokensNode):
|
||||
return UTN(other.source,
|
||||
other.start,
|
||||
other.end)
|
||||
|
||||
raise NotImplementedError(f"UTN, {other=}")
|
||||
|
||||
|
||||
class RN(HelperWithPos):
|
||||
"""
|
||||
Helper class to test RuleNode
|
||||
"""
|
||||
|
||||
def __init__(self, rule, source=None, start=None, end=None):
|
||||
"""
|
||||
|
||||
:param source:
|
||||
:param start:
|
||||
:param end:
|
||||
"""
|
||||
super().__init__(start, end)
|
||||
self.rule_id = rule.id if isinstance(rule, Rule) else rule
|
||||
self.source = source or str_concept((None, self.rule_id), prefix="r:") if self.rule_id else None
|
||||
self.rule = rule if isinstance(rule, Rule) else None
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if not isinstance(other, RN):
|
||||
return False
|
||||
|
||||
return self.rule_id == other.rule_id and \
|
||||
self.start == other.start and \
|
||||
self.end == other.end and \
|
||||
self.source == other.source
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.rule_id, self.start, self.end, self.source))
|
||||
|
||||
def __repr__(self):
|
||||
if self.rule:
|
||||
txt = f"RN(rule='{self.rule}'"
|
||||
else:
|
||||
txt = f"RN(rule_id='{self.rule_id}'"
|
||||
txt += f", source='{self.source}'"
|
||||
if self.start is not None:
|
||||
txt += f", start={self.start}"
|
||||
if self.end is not None:
|
||||
txt += f", end={self.end}"
|
||||
return txt + ")"
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
"""
|
||||
Transform other into CNC, to ease the comparison
|
||||
:param other:
|
||||
:param get_test_obj_delegate:
|
||||
:return:
|
||||
"""
|
||||
|
||||
if isinstance(other, RN):
|
||||
return other
|
||||
|
||||
if isinstance(other, RuleNode):
|
||||
return RN(other.rule,
|
||||
other.source if self.source is not None else None,
|
||||
other.start if self.start is not None else None,
|
||||
other.end if self.end is not None else None)
|
||||
|
||||
raise NotImplementedError(f"RN, {other=}")
|
||||
|
||||
|
||||
class FN:
|
||||
"""
|
||||
Test class only
|
||||
It matches with FunctionNode but with less constraints
|
||||
|
||||
Thereby,
|
||||
FN("first", "last", ["param1," ...]) can be compared to
|
||||
FunctionNode(NameExprNode("first"), NameExprNode("second"), [FunctionParameter(NamesNodes("param1"), NamesNodes(", ")])
|
||||
|
||||
Note that FunctionParameter can easily be defined with a single string
|
||||
* "param" -> FunctionParameter(NameExprNode("param"), None)
|
||||
* "param, " -> FunctionParameter(NameExprNode("param"), NameExprNode(", "))
|
||||
For more complicated situations, you can use a tuple (value, sep) to define the value part and the separator part
|
||||
"""
|
||||
|
||||
def __init__(self, first, last, parameters):
|
||||
self.first = first
|
||||
self.last = last
|
||||
self.parameters = []
|
||||
for param in parameters:
|
||||
if isinstance(param, tuple):
|
||||
self.parameters.append(param)
|
||||
elif isinstance(param, str) and (pos := param.find(",")) != -1:
|
||||
self.parameters.append((param[:pos], param[pos:]))
|
||||
else:
|
||||
self.parameters.append((param, None))
|
||||
|
||||
def __repr__(self):
|
||||
res = self.first
|
||||
for param in self.parameters:
|
||||
if param[1]:
|
||||
res += f"{param[0]}{param[1]} "
|
||||
else:
|
||||
res += f"{param[0]}"
|
||||
return res + self.last
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if isinstance(other, FN):
|
||||
return self.first == other.first and self.last == other.last and self.parameters == other.parameters
|
||||
|
||||
# if isinstance(other, FunctionNode):
|
||||
# if self.first != other.first.value or self.last != other.last.value:
|
||||
# return False
|
||||
# if len(self.parameters) != len(other.parameters):
|
||||
# return False
|
||||
# for self_parameter, other_parameter in zip(self.parameters, other.parameters):
|
||||
# value = other_parameter.value.value if isinstance(self_parameter[0], str) else other_parameter.value
|
||||
# sep = other_parameter.separator.value if other_parameter.separator else None
|
||||
# if self_parameter[0] != value or self_parameter[1] != sep:
|
||||
# return False
|
||||
#
|
||||
# return True
|
||||
|
||||
return False
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.first, self.last, self.parameters))
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
if isinstance(other, FN):
|
||||
return other
|
||||
|
||||
if isinstance(other, FunctionNode):
|
||||
params = []
|
||||
for self_parameter, other_parameter in zip(self.parameters, other.parameters):
|
||||
if isinstance(self_parameter[0], str):
|
||||
value = other_parameter.value.value
|
||||
else:
|
||||
value = get_test_obj_delegate(other_parameter.value, self_parameter[0])
|
||||
sep = other_parameter.separator.value if other_parameter.separator else None
|
||||
params.append((value, sep))
|
||||
|
||||
return FN(other.first.value, other.last.value, params)
|
||||
|
||||
raise NotImplementedError(f"FN, {other=}")
|
||||
|
||||
|
||||
comparison_type_mapping = {
|
||||
"EQ": ComparisonType.EQUALS,
|
||||
"NEQ": ComparisonType.NOT_EQUAlS,
|
||||
@@ -260,7 +1082,7 @@ def get_node(
|
||||
if isinstance(sub_expr, ReturnValueConcept):
|
||||
return sub_expr
|
||||
|
||||
if isinstance(sub_expr, (scnode, utnode, DoNotResolve)):
|
||||
if isinstance(sub_expr, DoNotResolve):
|
||||
return sub_expr
|
||||
|
||||
if isinstance(sub_expr, CIO):
|
||||
@@ -272,18 +1094,6 @@ def get_node(
|
||||
sub_expr.end = node.end
|
||||
return sub_expr
|
||||
|
||||
if isinstance(sub_expr, cnode):
|
||||
# for cnode, map the concept key to the one from concepts_maps if needed
|
||||
if sub_expr.concept_key.startswith("#"):
|
||||
return cnode(
|
||||
concepts_map[sub_expr.concept_key[1:]].key,
|
||||
sub_expr.start,
|
||||
sub_expr.end,
|
||||
sub_expr.source
|
||||
)
|
||||
else:
|
||||
return sub_expr
|
||||
|
||||
if isinstance(sub_expr, SCWC):
|
||||
sub_expr.first = get_node(concepts_map, expression_as_tokens, sub_expr.first, sya=sya)
|
||||
sub_expr.last = get_node(concepts_map, expression_as_tokens, sub_expr.last, sya=sya)
|
||||
@@ -342,10 +1152,6 @@ def get_node(
|
||||
sub_expr.fix_pos(node)
|
||||
return sub_expr
|
||||
|
||||
if isinstance(sub_expr, short_cnode):
|
||||
return get_node(concepts_map, expression_as_tokens, sub_expr.source,
|
||||
concept_key=sub_expr.concept_key, skip=skip, is_bnf=True, sya=sya)
|
||||
|
||||
if isinstance(sub_expr, tuple):
|
||||
return get_node(concepts_map, expression_as_tokens, sub_expr[0],
|
||||
concept_key=concept_key, skip=sub_expr[1], is_bnf=is_bnf, sya=sya)
|
||||
@@ -364,11 +1170,11 @@ def get_node(
|
||||
if sya and len(concept_found.get_metadata().variables) > 0 and not is_bnf:
|
||||
return SyaConceptParserHelper(concept_found, start, start + length - 1)
|
||||
elif init_empty_body:
|
||||
node = CNC(concept_found, start, start + length - 1, source=sub_expr, exclude_body=exclude_body)
|
||||
node = CNC(concept_found, sub_expr, start, start + length - 1, exclude_body=exclude_body)
|
||||
init_body(node, concept_found, sub_expr)
|
||||
return node
|
||||
else:
|
||||
return CN(concept_found, start, start + length - 1, source=sub_expr)
|
||||
return CN(concept_found, sub_expr, start, start + length - 1)
|
||||
else:
|
||||
# else an UnrecognizedTokensNode
|
||||
return UTN(sub_expr, start, start + length - 1)
|
||||
@@ -489,27 +1295,32 @@ def get_rete_conditions(*conditions_as_string):
|
||||
return AndConditions(res)
|
||||
|
||||
|
||||
def get_test_obj(test_obj, real_obj, to_compare_delegate=None):
|
||||
def get_test_obj(real_obj, test_obj, get_test_obj_delegate=None):
|
||||
"""
|
||||
From a production object (Concept, ConceptNode, ....)
|
||||
Create a test object (CNC, CC ...) that can be used to validate the unit tests
|
||||
:param test_obj:
|
||||
:param real_obj:
|
||||
:param to_compare_delegate:
|
||||
:param get_test_obj_delegate:
|
||||
:return:
|
||||
"""
|
||||
if isinstance(test_obj, list):
|
||||
if len(test_obj) != len(real_obj):
|
||||
raise Exception(f"Not the same size ! {test_obj=}, {real_obj=}")
|
||||
return [get_test_obj(t, r) for t, r in zip(test_obj, real_obj)]
|
||||
raise Exception(f"Not the same size ! {real_obj=}, {test_obj=}")
|
||||
return [get_test_obj(r, t) for r, t in zip(real_obj, test_obj)]
|
||||
|
||||
if isinstance(test_obj, dict):
|
||||
if len(test_obj) != len(real_obj):
|
||||
raise Exception(f"Not the same size ! {test_obj=}, {real_obj=}")
|
||||
raise Exception(f"Not the same size ! {real_obj=}, {test_obj=}")
|
||||
|
||||
return {k: get_test_obj(v, real_obj[k]) for k, v in test_obj.items()}
|
||||
return {k: get_test_obj(real_obj[k], v) for k, v in test_obj.items()}
|
||||
|
||||
if not hasattr(test_obj, "to_compare"):
|
||||
if not hasattr(test_obj, "transform_real_obj"):
|
||||
return real_obj
|
||||
|
||||
return test_obj.to_compare(real_obj, get_test_obj)
|
||||
return test_obj.transform_real_obj(real_obj, get_test_obj)
|
||||
|
||||
|
||||
def compare_with_test_object(actual, expected):
|
||||
to_compare = get_test_obj(actual, expected)
|
||||
assert to_compare == expected
|
||||
|
||||
+148
-142
@@ -4,11 +4,11 @@ import pytest
|
||||
|
||||
import tests.parsers.parsers_utils
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts, DoNotResolve, CC, DEFINITION_TYPE_BNF
|
||||
from core.concept import Concept, ConceptParts, DoNotResolve, DEFINITION_TYPE_BNF
|
||||
from core.global_symbols import NotInit
|
||||
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from parsers.BaseNodeParser import CNC, UTN, CN, NoMatchingTokenError, SCN
|
||||
from parsers.BaseNodeParser import NoMatchingTokenError
|
||||
from parsers.BnfDefinitionParser import BnfDefinitionParser
|
||||
from parsers.BnfNodeParser import StrMatch, TerminalNode, NonTerminalNode, Sequence, OrderedChoice, \
|
||||
Optional, ZeroOrMore, OneOrMore, ConceptExpression, UnOrderedChoice, BnfNodeParser, RegExMatch, \
|
||||
@@ -16,6 +16,7 @@ from parsers.BnfNodeParser import StrMatch, TerminalNode, NonTerminalNode, Seque
|
||||
from tests.BaseTest import BaseTest
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.evaluators.EvaluatorTestsUtils import python_ret_val
|
||||
from tests.parsers.parsers_utils import CNC, CN, UTN, CC, SCN, get_test_obj, compare_with_test_object
|
||||
|
||||
cmap = {
|
||||
"one": Concept("one"),
|
||||
@@ -210,7 +211,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(bnf_parsers_helpers) == len(expected_array)
|
||||
for parser_helper, expected_sequence in zip(bnf_parsers_helpers, expected_array):
|
||||
to_compare = tests.parsers.parsers_utils.get_test_obj(expected_sequence, parser_helper.sequence)
|
||||
to_compare = tests.parsers.parsers_utils.get_test_obj(parser_helper.sequence, expected_sequence)
|
||||
# assert parser_helper.sequence == expected_sequence
|
||||
assert to_compare == expected_sequence
|
||||
|
||||
@@ -305,7 +306,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one two three", [CNC("foo", source="one two three")]),
|
||||
("one two three", [CNC("foo", "one two three")]),
|
||||
("one two", []),
|
||||
("one two four", []),
|
||||
])
|
||||
@@ -345,7 +346,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
parser.reset_parser(context, ParserInput(text))
|
||||
bnf_parsers_helpers = parser.get_concepts_sequences(context)
|
||||
assert bnf_parsers_helpers[0].sequence == expected_array
|
||||
transformed = get_test_obj(bnf_parsers_helpers[0].sequence, expected_array)
|
||||
assert transformed == expected_array
|
||||
assert not bnf_parsers_helpers[0].has_unrecognized
|
||||
|
||||
# but I cannot parse
|
||||
@@ -362,8 +364,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
text = "one two three one two"
|
||||
expected = [
|
||||
CNC("foo", source="one two three"),
|
||||
CNC("bar", source="one two", start=6, end=8)]
|
||||
CNC("foo", "one two three"),
|
||||
CNC("bar", "one two", 6, 8)]
|
||||
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@@ -406,8 +408,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("ok thirty one", [CNC("foo", source="ok thirty one")]),
|
||||
("ok twenty one", [CNC("foo", source="ok twenty one")]),
|
||||
("ok thirty one", [CNC("foo", "ok thirty one")]),
|
||||
("ok twenty one", [CNC("foo", "ok twenty one")]),
|
||||
("ok one", []),
|
||||
])
|
||||
def test_i_can_mix_sequence_and_ordered(self, text, expected):
|
||||
@@ -421,7 +423,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("twenty one", [CNC("foo", source="twenty one")]),
|
||||
("twenty one", [CNC("foo", "twenty one")]),
|
||||
("twenty three", []), # three does not exist
|
||||
("twenty four", []), # four exists but should not be seen
|
||||
])
|
||||
@@ -435,8 +437,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("twenty thirty", [CNC("foo", source="twenty thirty")]),
|
||||
("one", [CNC("foo", source="one")]),
|
||||
("twenty thirty", [CNC("foo", "twenty thirty")]),
|
||||
("one", [CNC("foo", "one")]),
|
||||
])
|
||||
def test_i_can_mix_ordered_choices_and_sequences(self, text, expected):
|
||||
my_map = {
|
||||
@@ -448,8 +450,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one", [CNC("foo", source="one")]),
|
||||
("one two", [CNC("foo", source="one two")]),
|
||||
("one", [CNC("foo", "one")]),
|
||||
("one two", [CNC("foo", "one two")]),
|
||||
("three", []),
|
||||
|
||||
])
|
||||
@@ -463,7 +465,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one", [CNC("foo", source="one")]),
|
||||
("one", [CNC("foo", "one")]),
|
||||
("", []),
|
||||
("two", []),
|
||||
])
|
||||
@@ -475,8 +477,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("twenty one", [CNC("foo", source="twenty one")]),
|
||||
("one", [CNC("foo", source="one")]),
|
||||
("twenty one", [CNC("foo", "twenty one")]),
|
||||
("one", [CNC("foo", "one")]),
|
||||
])
|
||||
def test_i_can_match_sequence_starting_with_optional(self, text, expected):
|
||||
my_map = {
|
||||
@@ -489,8 +491,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one two three", [CNC("foo", source="one two three")]),
|
||||
("one two", [CNC("foo", source="one two")]),
|
||||
("one two three", [CNC("foo", "one two three")]),
|
||||
("one two", [CNC("foo", "one two")]),
|
||||
])
|
||||
def test_i_can_match_sequence_ending_with_optional(self, text, expected):
|
||||
my_map = {
|
||||
@@ -504,8 +506,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one two three", [CNC("foo", source="one two three")]),
|
||||
("one three", [CNC("foo", source="one three")]),
|
||||
("one two three", [CNC("foo", "one two three")]),
|
||||
("one three", [CNC("foo", "one three")]),
|
||||
])
|
||||
def test_i_can_match_sequence_with_optional_in_between(self, text, expected):
|
||||
my_map = {
|
||||
@@ -521,8 +523,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("", []),
|
||||
("two", []),
|
||||
("one", [CNC("foo", source="one")]),
|
||||
("one one", [CNC("foo", source="one one")]),
|
||||
("one", [CNC("foo", "one")]),
|
||||
("one one", [CNC("foo", "one one")]),
|
||||
])
|
||||
def test_i_can_match_zero_or_more(self, text, expected):
|
||||
my_map = {
|
||||
@@ -532,9 +534,9 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("two", [CNC("foo", source="two")]),
|
||||
("one two", [CNC("foo", source="one two")]),
|
||||
("one one two", [CNC("foo", source="one one two")]),
|
||||
("two", [CNC("foo", "two")]),
|
||||
("one two", [CNC("foo", "one two")]),
|
||||
("one one two", [CNC("foo", "one one two")]),
|
||||
])
|
||||
def test_i_can_match_sequence_and_zero_or_more(self, text, expected):
|
||||
my_map = {
|
||||
@@ -548,7 +550,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one, one , one", [CNC("foo", source="one, one , one")]),
|
||||
("one, one , one", [CNC("foo", "one, one , one")]),
|
||||
])
|
||||
def test_i_can_match_zero_or_more_with_separator(self, text, expected):
|
||||
my_map = {
|
||||
@@ -564,14 +566,14 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
}
|
||||
|
||||
text = "one one one"
|
||||
expected = [CNC("foo", source=text)]
|
||||
expected = [CNC("foo", text)]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("", []),
|
||||
("two", []),
|
||||
("one", [CNC("foo", source="one")]),
|
||||
("one one one", [CNC("foo", source="one one one")]),
|
||||
("one", [CNC("foo", "one")]),
|
||||
("one one one", [CNC("foo", "one one one")]),
|
||||
])
|
||||
def test_i_can_match_one_or_more(self, text, expected):
|
||||
my_map = {
|
||||
@@ -582,8 +584,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("two", []),
|
||||
("one two", [CNC("foo", source="one two")]),
|
||||
("one one two", [CNC("foo", source="one one two")]),
|
||||
("one two", [CNC("foo", "one two")]),
|
||||
("one one two", [CNC("foo", "one one two")]),
|
||||
])
|
||||
def test_i_can_match_sequence_one_and_or_more(self, text, expected):
|
||||
my_map = {
|
||||
@@ -597,7 +599,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one, one , one", [CNC("foo", source="one, one , one")]),
|
||||
("one, one , one", [CNC("foo", "one, one , one")]),
|
||||
])
|
||||
def test_i_can_match_one_or_more_with_separator(self, text, expected):
|
||||
my_map = {
|
||||
@@ -613,18 +615,18 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
}
|
||||
|
||||
text = "one one one"
|
||||
expected = [CNC("foo", source=text)]
|
||||
expected = [CNC("foo", text)]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one two", [
|
||||
[CNC("foo", source="one two")],
|
||||
[CNC("bar", source="one two")]]),
|
||||
[CNC("foo", "one two")],
|
||||
[CNC("bar", "one two")]]),
|
||||
("one two one two", [
|
||||
[CNC("bar", source="one two"), CNC("bar", source="one two")],
|
||||
[CNC("foo", source="one two"), CNC("bar", source="one two")],
|
||||
[CNC("bar", source="one two"), CNC("foo", source="one two")],
|
||||
[CNC("foo", source="one two"), CNC("foo", source="one two")]]),
|
||||
[CNC("bar", "one two"), CNC("bar", "one two")],
|
||||
[CNC("foo", "one two"), CNC("bar", "one two")],
|
||||
[CNC("bar", "one two"), CNC("foo", "one two")],
|
||||
[CNC("foo", "one two"), CNC("foo", "one two")]]),
|
||||
])
|
||||
def test_i_can_have_multiple_results(self, text, expected):
|
||||
my_map = {
|
||||
@@ -635,7 +637,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
}
|
||||
|
||||
text = "one two"
|
||||
expected = [[CNC("foo", source=text)], [CNC("bar", source=text)]]
|
||||
expected = [[CNC("foo", text)], [CNC("bar", text)]]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected, multiple_result=True)
|
||||
|
||||
def test_i_can_refer_to_other_concepts(self):
|
||||
@@ -646,8 +648,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
text = "one two"
|
||||
expected = [
|
||||
[CNC("foo", source=text)],
|
||||
[CN("bar", source=text)] # Do not check the compiled part
|
||||
[CNC("foo", text)],
|
||||
[CN("bar", text)] # Do not check the compiled part
|
||||
]
|
||||
sequences = self.validate_get_concepts_sequences(my_map, text, expected, multiple_result=True)
|
||||
|
||||
@@ -672,8 +674,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
text = "one two"
|
||||
expected = [
|
||||
[CNC("foo", source=text)],
|
||||
[CN("bar", source=text)] # Do not check the compiled part
|
||||
[CNC("foo", text)],
|
||||
[CN("bar", text)] # Do not check the compiled part
|
||||
]
|
||||
sequences = self.validate_get_concepts_sequences(my_map, text, expected, multiple_result=True)
|
||||
|
||||
@@ -698,9 +700,9 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
text = "one two"
|
||||
expected = [
|
||||
[CNC("foo", source=text)],
|
||||
[CN("bar", source=text)], # Do not check the compiled part
|
||||
[CN("baz", source=text)], # Do not check the compiled part
|
||||
[CNC("foo", text)],
|
||||
[CN("bar", text)], # Do not check the compiled part
|
||||
[CN("baz", text)], # Do not check the compiled part
|
||||
]
|
||||
sequences = self.validate_get_concepts_sequences(my_map, text, expected, multiple_result=True)
|
||||
|
||||
@@ -769,7 +771,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
text = "twenty two"
|
||||
|
||||
expected = [CNC("twenties",
|
||||
source="twenty two",
|
||||
"twenty two",
|
||||
twenty=CC("twenty", body=DoNotResolve("twenty")),
|
||||
number=CC("number", source="two", body=DoNotResolve("two"))
|
||||
)]
|
||||
@@ -842,7 +844,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
}
|
||||
|
||||
text = "twenty one"
|
||||
expected = [CN("foo", source="twenty one")]
|
||||
expected = [CN("foo", "twenty one")]
|
||||
sequences = self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
concept_foo = sequences[0].concept
|
||||
assert concept_foo.get_compiled() == {
|
||||
@@ -869,8 +871,9 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
# explicit validations of the compiled
|
||||
concept_foo = sequences[0].concept
|
||||
assert concept_foo.body == NotInit
|
||||
assert concept_foo.get_compiled() == {'number': CC(my_map["number"], body=my_map["two"], two=my_map["two"]),
|
||||
ConceptParts.BODY: DoNotResolve(value='twenty two')}
|
||||
compare_with_test_object(concept_foo.get_compiled(), {
|
||||
'number': CC(my_map["number"], body=my_map["two"], two=my_map["two"]),
|
||||
ConceptParts.BODY: DoNotResolve(value='twenty two')})
|
||||
|
||||
text = "twenty one"
|
||||
expected = [CN("foo", source="twenty one")]
|
||||
@@ -879,14 +882,15 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
# explicit validations of the compiled
|
||||
concept_foo = sequences[0].concept
|
||||
assert concept_foo.body == NotInit
|
||||
assert concept_foo.get_compiled() == {'number': CC(my_map["number"], body=my_map["one"], one=my_map["one"]),
|
||||
ConceptParts.BODY: DoNotResolve(value='twenty one')}
|
||||
compare_with_test_object(concept_foo.get_compiled(), {
|
||||
'number': CC(my_map["number"], body=my_map["one"], one=my_map["one"]),
|
||||
ConceptParts.BODY: DoNotResolve(value='twenty one')})
|
||||
|
||||
@pytest.mark.parametrize("expr, expected", [
|
||||
("one 'car'", [CNC("foo", source="one 'car'", x=python_ret_val("'car'"))]), # python
|
||||
("one bar", [CNC("foo", source="one bar", x=CC("bar"))]), # simple concept
|
||||
("one super car", [CNC("foo", source="one super car", x=CC("super car"))]), # long concept
|
||||
("one shoe", [CNC("foo", source="one shoe", x=CC("thing", source="shoe", body=DoNotResolve("shoe")))]), # bnf
|
||||
("one 'car'", [CNC("foo", "one 'car'", x=python_ret_val("'car'"))]), # python
|
||||
("one bar", [CNC("foo", "one bar", x=CC("bar"))]), # simple concept
|
||||
("one super car", [CNC("foo", "one super car", x=CC("super car"))]), # long concept
|
||||
("one shoe", [CNC("foo", "one shoe", x=CC("thing", source="shoe", body=DoNotResolve("shoe")))]), # bnf
|
||||
])
|
||||
def test_i_can_match_variable_when_ending_with_one_variable(self, expr, expected):
|
||||
my_map = {
|
||||
@@ -910,8 +914,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expr = "one bar plus baz"
|
||||
expected = [
|
||||
[CNC("foo", source="one bar", x=CC("bar")), UTN(" plus "), CN("baz")],
|
||||
[CNC("foo", source="one bar plus baz", x=CC("plus", source="bar plus baz", x="bar", y="baz"))],
|
||||
[CNC("foo", "one bar", x=CC("bar")), UTN(" plus "), CN("baz")],
|
||||
[CNC("foo", "one bar plus baz", x=CC("plus", source="bar plus baz", x="bar", y="baz"))],
|
||||
]
|
||||
|
||||
self.validate_get_concepts_sequences(my_map, expr, expected, multiple_result=True)
|
||||
@@ -925,8 +929,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expr = "one pretty big"
|
||||
expected = [
|
||||
[CNC("foo", source="one pretty big", x=CC("pretty big"))],
|
||||
[CNC("foo", source="one pretty big", x=CC("pbig", source="pretty big"))]
|
||||
[CNC("foo", "one pretty big", x=CC("pretty big"))],
|
||||
[CNC("foo", "one pretty big", x=CC("pbig", source="pretty big"))]
|
||||
]
|
||||
self.validate_get_concepts_sequences(my_map, expr, expected, multiple_result=True)
|
||||
|
||||
@@ -940,16 +944,16 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expr = "one pretty big"
|
||||
expected = [
|
||||
[CNC("foo", source="one pretty big", x=CC("pretty"), y=CC("big"))],
|
||||
[CNC("foo", source="one pretty big", x=CC("pretty2", source="pretty"), y=CC("big"))]
|
||||
[CNC("foo", "one pretty big", x=CC("pretty"), y=CC("big"))],
|
||||
[CNC("foo", "one pretty big", x=CC("pretty2", source="pretty"), y=CC("big"))]
|
||||
]
|
||||
self.validate_get_concepts_sequences(my_map, expr, expected, multiple_result=True)
|
||||
|
||||
@pytest.mark.parametrize("expr, expected", [
|
||||
("'my' shoe", [CNC("foo", source="'my' shoe", x=python_ret_val("'my' "))]), # python
|
||||
("one shoe", [CNC("foo", source="one shoe", x=CC("one"))]), # concept
|
||||
("my little shoe", [CNC("foo", source="my little shoe", x=CC("my little"))]), # long concept
|
||||
("black shoe", [CNC("foo", source="black shoe", x=CC("color", source="black", body=DoNotResolve('black')))]),
|
||||
("'my' shoe", [CNC("foo", "'my' shoe", x=python_ret_val("'my' "))]), # python
|
||||
("one shoe", [CNC("foo", "one shoe", x=CC("one"))]), # concept
|
||||
("my little shoe", [CNC("foo", "my little shoe", x=CC("my little"))]), # long concept
|
||||
("black shoe", [CNC("foo", "black shoe", x=CC("color", source="black", body=DoNotResolve('black')))]),
|
||||
])
|
||||
def test_i_can_match_variable_when_starting_with_one_variable(self, expr, expected):
|
||||
my_map = {
|
||||
@@ -972,9 +976,9 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expr = "tiny but beautiful shoe"
|
||||
expected_res = [
|
||||
CNC("foo",
|
||||
source="tiny but beautiful shoe",
|
||||
"tiny but beautiful shoe",
|
||||
x=CC("but", source="tiny but beautiful", x="tiny", y="beautiful"))]
|
||||
unwanted_res = [CN("tiny"), UTN(" but "), CNC("foo", source="beautiful shoe", x=CC("beautiful"))]
|
||||
unwanted_res = [CN("tiny"), UTN(" but "), CNC("foo", "beautiful shoe", x=CC("beautiful"))]
|
||||
self.validate_get_concepts_sequences(my_map, expr, [unwanted_res, expected_res], multiple_result=True)
|
||||
|
||||
def test_i_can_match_variable_when_starting_with_multiple_variables(self):
|
||||
@@ -992,7 +996,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
unwanted_res = [CN("one"), SCN(" 'one' "), ("one", 1), UTN(" plus "), CN("two")]
|
||||
expected_res = [CNC("foo",
|
||||
source="one 'one' one plus two shoe",
|
||||
"one 'one' one plus two shoe",
|
||||
x=CC("one"),
|
||||
y=python_ret_val(" 'one' "),
|
||||
z=CC("plus", source="one plus two", x="one", y="two"))]
|
||||
@@ -1009,18 +1013,18 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
"one": Concept("one")
|
||||
}
|
||||
text = "one foo bar baz"
|
||||
expected = [CNC("foo", source="one foo bar baz", x=CC("one"))]
|
||||
expected = [CNC("foo", "one foo bar baz", x=CC("one"))]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
@pytest.mark.parametrize("expr, expected", [
|
||||
("one 'pretty' shoe", [CNC("foo", source="one 'pretty' shoe", x=python_ret_val("'pretty' "))]), # python
|
||||
("one little shoe", [CNC("foo", source="one little shoe", x=CC("little"))]), # concept
|
||||
("one very big shoe", [CNC("foo", source="one very big shoe", x=CC("very big"))]), # long concept
|
||||
("one 'pretty' shoe", [CNC("foo", "one 'pretty' shoe", x=python_ret_val("'pretty' "))]), # python
|
||||
("one little shoe", [CNC("foo", "one little shoe", x=CC("little"))]), # concept
|
||||
("one very big shoe", [CNC("foo", "one very big shoe", x=CC("very big"))]), # long concept
|
||||
("one black shoe",
|
||||
[CNC("foo", source="one black shoe", x=CC("color", source="black", body=DoNotResolve('black')))]),
|
||||
[CNC("foo", "one black shoe", x=CC("color", source="black", body=DoNotResolve('black')))]),
|
||||
("one tiny but beautiful shoe",
|
||||
[CNC("foo",
|
||||
source="one tiny but beautiful shoe",
|
||||
"one tiny but beautiful shoe",
|
||||
x=CC("but", source="tiny but beautiful", x="tiny", y="beautiful "))]),
|
||||
])
|
||||
def test_i_can_match_variable_in_between(self, expr, expected):
|
||||
@@ -1043,8 +1047,8 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expr = "one pretty big shoe"
|
||||
expected = [
|
||||
[CNC("foo", source="one pretty big shoe", x=CC("pretty big"))],
|
||||
[CNC("foo", source="one pretty big shoe", x=CC("pbig", source="pretty big"))]
|
||||
[CNC("foo", "one pretty big shoe", x=CC("pretty big"))],
|
||||
[CNC("foo", "one pretty big shoe", x=CC("pbig", source="pretty big"))]
|
||||
]
|
||||
self.validate_get_concepts_sequences(my_map, expr, expected, multiple_result=True)
|
||||
|
||||
@@ -1055,7 +1059,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
"shoe": Concept("shoe")
|
||||
}
|
||||
text = "onyx shoe"
|
||||
expected = [CNC("foo", source="onyx shoe", x=CC("shoe"))]
|
||||
expected = [CNC("foo", "onyx shoe", x=CC("shoe"))]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
def test_i_can_match_variable_and_regex(self):
|
||||
@@ -1065,7 +1069,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
"one": Concept("one")
|
||||
}
|
||||
text = "one onyx"
|
||||
expected = [CNC("foo", source="one onyx", x=CC("one"))]
|
||||
expected = [CNC("foo", "one onyx", x=CC("one"))]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
def test_i_can_reuse_the_same_variable(self):
|
||||
@@ -1083,12 +1087,12 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
# same variable appears only once in the compiled variables
|
||||
text = "one equals one"
|
||||
expected = [CNC("foo", source="one equals one", x=CC("one"))]
|
||||
expected = [CNC("foo", "one equals one", x=CC("one"))]
|
||||
expected_sequence = compute_expected_array(my_map, text, expected)
|
||||
|
||||
parser.reset_parser(context, ParserInput(text))
|
||||
bnf_parsers_helpers = parser.get_concepts_sequences(context)
|
||||
to_compare = tests.parsers.parsers_utils.get_test_obj(expected_sequence, bnf_parsers_helpers[0].sequence)
|
||||
to_compare = tests.parsers.parsers_utils.get_test_obj(bnf_parsers_helpers[0].sequence, expected_sequence)
|
||||
assert to_compare == expected
|
||||
|
||||
def test_i_cannot_match_variable_when_variables_discrepancy(self):
|
||||
@@ -1314,9 +1318,9 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
ConceptExpression(my_map["one"], rule_name="one"))
|
||||
|
||||
@pytest.mark.parametrize("expr, text, expected", [
|
||||
(ZeroOrMore(StrMatch("one"), sep=","), "one,", [CNC("foo", source="one"), UTN(",")]),
|
||||
(StrMatch("one"), "one two", [CNC("foo", source="one"), UTN(" two")]),
|
||||
(StrMatch("one"), "two one", [UTN("two "), CNC("foo", source="one")]),
|
||||
(ZeroOrMore(StrMatch("one"), sep=","), "one,", [CNC("foo", "one"), UTN(",")]),
|
||||
(StrMatch("one"), "one two", [CNC("foo", "one"), UTN(" two")]),
|
||||
(StrMatch("one"), "two one", [UTN("two "), CNC("foo", "one")]),
|
||||
])
|
||||
def test_i_can_recognize_unknown_concepts(self, expr, text, expected):
|
||||
my_map = {
|
||||
@@ -1332,7 +1336,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
}
|
||||
|
||||
text = "one three"
|
||||
expected = [UTN("one "), CNC("three", source="three")]
|
||||
expected = [UTN("one "), CNC("three", "three")]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
def test_i_can_remove_duplicates(self):
|
||||
@@ -1350,12 +1354,12 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
assert len(sequence) == 1
|
||||
|
||||
@pytest.mark.parametrize("parser_input, expected_status, expected", [
|
||||
("baz", True, [CNC("bnf baz", source="baz")]), # the bnf one is chosen
|
||||
("foo bar", True, [CNC("foo then bar", source="foo bar", foo="foo", bar="bar")]),
|
||||
("bar", True, [CNC("foo or bar", source="bar", bar="bar", body="bar")]),
|
||||
("one plus two", True, [CNC("plus", source="one plus two", one="one", two="two")]),
|
||||
("twenty one", True, [CNC("t1", source="twenty one", unit="one")]),
|
||||
("one 'car'", True, [CNC("one thing", source="one 'car'", x=python_ret_val("'car'"), one="one")])
|
||||
("baz", True, [CNC("bnf baz", "baz")]), # the bnf one is chosen
|
||||
("foo bar", True, [CNC("foo then bar", "foo bar", foo="foo", bar="bar")]),
|
||||
("bar", True, [CNC("foo or bar", "bar", bar="bar", body="bar")]),
|
||||
("one plus two", True, [CNC("plus", "one plus two", one="one", two="two")]),
|
||||
("twenty one", True, [CNC("t1", "twenty one", unit="one")]),
|
||||
("one 'car'", True, [CNC("one thing", "one 'car'", x=python_ret_val("'car'"), one="one")])
|
||||
])
|
||||
def test_i_can_parse_simple_expressions(self, parser_input, expected_status, expected):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
@@ -1367,7 +1371,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status == expected_status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_when_multiple_times_the_same_variable(self):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
@@ -1382,7 +1386,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_test_when_expression_references_other_expressions(self):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
@@ -1402,7 +1406,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_bnf_concept_mixed_with_isa_concepts(self):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
@@ -1428,7 +1432,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_bnf_concept_mixed_with_isa_concepts_2(self):
|
||||
# this time, three is a number, and also part of three_four, even if it is not relevant in t3
|
||||
@@ -1450,7 +1454,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_when_starting_by_isa_concept(self):
|
||||
"""
|
||||
@@ -1476,7 +1480,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_fifty_one_thousand(self):
|
||||
"""
|
||||
@@ -1515,10 +1519,10 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert res[0].status
|
||||
assert res[0].value.value == expected_thousands
|
||||
compare_with_test_object(res[0].value.value, expected_thousands)
|
||||
|
||||
assert res[1].status
|
||||
assert res[1].value.value == expected_fifties
|
||||
compare_with_test_object(res[1].value.value, expected_fifties)
|
||||
|
||||
def test_i_can_parse_one_hundred_thousand(self):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
@@ -1565,7 +1569,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_bnf_concept_mixed_with_isa_after_restart(self):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
@@ -1589,7 +1593,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
text = "forty one"
|
||||
expected = CNC("forties",
|
||||
@@ -1607,13 +1611,13 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_when_keyword(self):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
|
||||
parser_input = "def one"
|
||||
expected = [CNC("def number", source="def one", number="one")]
|
||||
expected = [CNC("def number", "def one", number="one")]
|
||||
|
||||
res = parser.parse(context, ParserInput(parser_input))
|
||||
expected_array = compute_expected_array(cmap, parser_input, expected)
|
||||
@@ -1624,7 +1628,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_filter(self):
|
||||
sheerka, context, parser = self.init_parser(init_from_sheerka=True)
|
||||
@@ -1639,7 +1643,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == expected_array
|
||||
compare_with_test_object(concepts_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_descent_grammar(self):
|
||||
my_map = {
|
||||
@@ -1662,17 +1666,17 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == [CNC(expr,
|
||||
term=[CC(term,
|
||||
body=CC(factor, body=DoNotResolve("1")),
|
||||
factor=CC(factor, body=DoNotResolve("1"))),
|
||||
CC(term,
|
||||
body=DoNotResolve("2 * 3"),
|
||||
factor=[
|
||||
CC(factor, body=DoNotResolve("2")),
|
||||
CC(factor, body=DoNotResolve("3")),
|
||||
])],
|
||||
body=DoNotResolve("1 + 2 * 3"))]
|
||||
compare_with_test_object(concepts_nodes, [CNC(expr,
|
||||
term=[CC(term,
|
||||
body=CC(factor, body=DoNotResolve("1")),
|
||||
factor=CC(factor, body=DoNotResolve("1"))),
|
||||
CC(term,
|
||||
body=DoNotResolve("2 * 3"),
|
||||
factor=[
|
||||
CC(factor, body=DoNotResolve("2")),
|
||||
CC(factor, body=DoNotResolve("3")),
|
||||
])],
|
||||
body=DoNotResolve("1 + 2 * 3"))])
|
||||
|
||||
def test_i_can_parse_recursive_descent_grammar(self):
|
||||
my_map = {
|
||||
@@ -1698,25 +1702,27 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
# concepts_nodes = res.value.value is too complicated to be validated
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert concepts_nodes == [CNC(expr,
|
||||
term=CC(term,
|
||||
body=CC(factor, body=DoNotResolve("1")),
|
||||
factor=CC(factor, body=DoNotResolve("1"))),
|
||||
expr=CC(expr,
|
||||
body=CC(term,
|
||||
body=DoNotResolve("2 * 3"),
|
||||
factor=CC(factor, body=DoNotResolve("2")),
|
||||
compare_with_test_object(concepts_nodes, [CNC(expr,
|
||||
term=CC(term,
|
||||
body=CC(factor, body=DoNotResolve("3")),
|
||||
factor=CC(factor, body=DoNotResolve("3")))),
|
||||
term=CC(term,
|
||||
body=DoNotResolve("2 * 3"),
|
||||
factor=CC(factor, body=DoNotResolve("2")),
|
||||
term=CC(term,
|
||||
body=CC(factor, body=DoNotResolve("3")),
|
||||
factor=CC(factor, body=DoNotResolve("3"))))),
|
||||
body=CC(factor, body=DoNotResolve("1")),
|
||||
factor=CC(factor, body=DoNotResolve("1"))),
|
||||
expr=CC(expr,
|
||||
body=CC(term,
|
||||
body=DoNotResolve("2 * 3"),
|
||||
factor=CC(factor, body=DoNotResolve("2")),
|
||||
term=CC(term,
|
||||
body=CC(factor, body=DoNotResolve("3")),
|
||||
factor=CC(factor,
|
||||
body=DoNotResolve("3")))),
|
||||
term=CC(term,
|
||||
body=DoNotResolve("2 * 3"),
|
||||
factor=CC(factor, body=DoNotResolve("2")),
|
||||
term=CC(term,
|
||||
body=CC(factor, body=DoNotResolve("3")),
|
||||
factor=CC(factor,
|
||||
body=DoNotResolve("3"))))),
|
||||
|
||||
body=DoNotResolve("1 + 2 * 3"))]
|
||||
body=DoNotResolve("1 + 2 * 3"))])
|
||||
|
||||
def test_i_can_parse_simple_recursive_grammar(self):
|
||||
my_map = {
|
||||
@@ -1752,14 +1758,14 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
text = "thirty one"
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
assert res.status
|
||||
assert res.value.value == compute_expected_array(cmap, text, [CN("thirties", source=text)])
|
||||
compare_with_test_object(res.value.value, compute_expected_array(cmap, text, [CN("thirties", text)]))
|
||||
|
||||
# add a layer, I still can parse the text
|
||||
sheerka.push_ontology(context, "new layer")
|
||||
parser = BnfNodeParser(sheerka=sheerka)
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
assert res.status
|
||||
assert res.value.value == compute_expected_array(cmap, text, [CN("thirties", source=text)])
|
||||
compare_with_test_object(res.value.value, compute_expected_array(cmap, text, [CN("thirties", text)]))
|
||||
|
||||
def test_i_do_not_eat_unwanted_tokens_at_the_beginning_when_concept_with_variable(self):
|
||||
my_map = {
|
||||
@@ -1772,9 +1778,9 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
text = "two one shoe"
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
assert res.status
|
||||
assert res.value.value == compute_expected_array(my_map, text, [
|
||||
compare_with_test_object(res.value.value, compute_expected_array(my_map, text, [
|
||||
CN("two"),
|
||||
CNC("foo", source="one shoe", x=CC("one"))])
|
||||
CNC("foo", "one shoe", x=CC("one"))]))
|
||||
|
||||
def test_i_do_not_eat_unwanted_tokens_at_the_end_when_concept_with_variable(self):
|
||||
my_map = {
|
||||
@@ -1787,9 +1793,9 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
text = "one bar baz"
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
assert res.status
|
||||
assert res.value.value == compute_expected_array(my_map, text, [
|
||||
CNC("foo", source="one bar", x=CC("bar")),
|
||||
CN("baz")])
|
||||
compare_with_test_object(res.value.value, compute_expected_array(my_map, text, [
|
||||
CNC("foo", "one bar", x=CC("bar")),
|
||||
CN("baz")]))
|
||||
|
||||
@pytest.mark.parametrize("parsing_expression, expected", [
|
||||
(RegExMatch("a"), [RegExDef("a")]),
|
||||
|
||||
@@ -4,13 +4,13 @@ from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, DEFINITION_TYPE_BNF
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import Tokenizer, TokenKind, LexerError
|
||||
from parsers.BaseNodeParser import cnode
|
||||
from parsers.BaseParser import UnexpectedTokenParsingError, UnexpectedEofParsingError
|
||||
from parsers.BnfDefinitionParser import BnfDefinitionParser
|
||||
from parsers.BnfNodeParser import BnfNodeParser, RegExMatch, VariableExpression
|
||||
from parsers.BnfNodeParser import StrMatch, Optional, ZeroOrMore, OrderedChoice, Sequence, \
|
||||
OneOrMore, ConceptExpression
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import CN, compare_with_test_object
|
||||
|
||||
|
||||
class ClassWithName:
|
||||
@@ -226,15 +226,15 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = bnf_parser.parse(context, ParserInput("twenty two"))
|
||||
assert res.status
|
||||
assert res.value.body == [cnode("bar", 0, 2, "twenty two")]
|
||||
compare_with_test_object(res.value.body, [CN("bar", "twenty two", 0, 2)])
|
||||
|
||||
res = bnf_parser.parse(context, ParserInput("thirty one"))
|
||||
assert res.status
|
||||
assert res.value.body == [cnode("bar", 0, 2, "thirty one")]
|
||||
compare_with_test_object(res.value.body, [CN("bar", "thirty one", 0, 2)])
|
||||
|
||||
res = bnf_parser.parse(context, ParserInput("twenty"))
|
||||
assert res.status
|
||||
assert res.value.body == [cnode("foo", 0, 0, "twenty")]
|
||||
compare_with_test_object(res.value.body, [CN("foo", "twenty", 0, 0)])
|
||||
|
||||
def test_i_cannot_parse_when_too_many_concepts(self):
|
||||
sheerka, context, regex_parser, foo1, foo2 = self.init_parser(
|
||||
|
||||
@@ -4,11 +4,10 @@ from dataclasses import dataclass
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts, ReturnValueConcept
|
||||
from core.concept import DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF, Concept, CV
|
||||
from core.concept import DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF, Concept
|
||||
from core.global_symbols import NotInit
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import Keywords, Tokenizer, LexerError
|
||||
from parsers.BaseNodeParser import SCWC
|
||||
from parsers.BaseParser import UnexpectedEofParsingError
|
||||
from parsers.BnfDefinitionParser import BnfDefinitionParser
|
||||
from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch, Sequence, RegExMatch, OneOrMore, \
|
||||
@@ -18,7 +17,7 @@ from parsers.DefConceptParser import UnexpectedTokenParsingError, DefConceptNode
|
||||
from parsers.FunctionParser import FunctionParser
|
||||
from parsers.PythonParser import PythonParser, PythonNode
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array
|
||||
from tests.parsers.parsers_utils import compute_expected_array, SCWC, CV, compare_with_test_object
|
||||
|
||||
|
||||
def get_def_concept(name, where=None, pre=None, post=None, body=None, definition=None, bnf_def=None, ret=None):
|
||||
@@ -265,7 +264,6 @@ class TestDefConceptParser(TestUsingMemoryBasedSheerka):
|
||||
text = """def concept a mult b
|
||||
where a,b
|
||||
pre isinstance(a, int) and isinstance(b, int)
|
||||
post isinstance(res, a)
|
||||
as res = a * b
|
||||
ret a if isinstance(a, Concept) else self
|
||||
"""
|
||||
@@ -276,7 +274,6 @@ ret a if isinstance(a, Concept) else self
|
||||
name="a mult b",
|
||||
where="a,b\n",
|
||||
pre="isinstance(a, int) and isinstance(b, int)\n",
|
||||
post=FN("isinstance(res, a)\n", "isinstance(", ")", ["res", ", ", "a"]),
|
||||
body=PN("res = a * b\n", "exec"),
|
||||
ret="a if isinstance(a, Concept) else self\n"
|
||||
)
|
||||
@@ -542,29 +539,27 @@ from give me the date !
|
||||
|
||||
text = "def concept foo x y where x is a y"
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
expected_body = self.pretval(CV(concepts[0], pre=True), source="x is a y", who="parsers.DefConcept",
|
||||
parser="parsers.ExactConcept")
|
||||
expected = get_def_concept("foo x y", where=expected_body)
|
||||
node = res.value.value
|
||||
|
||||
assert res.status
|
||||
assert res.who == parser.name
|
||||
assert res.value.source == text
|
||||
assert isinstance(res.value, ParserResultConcept)
|
||||
assert node == expected
|
||||
assert isinstance(node, DefConceptNode)
|
||||
assert sheerka.isinstance(node.where, BuiltinConcepts.RETURN_VALUE)
|
||||
compare_with_test_object(node.where.body.body, CV(concepts[0], pre=True))
|
||||
|
||||
text = "def concept foo x y pre x is a y"
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
expected_body = self.pretval(CV(concepts[0], pre=True), source="x is a y", who="parsers.DefConcept",
|
||||
parser="parsers.ExactConcept")
|
||||
expected = get_def_concept("foo x y", pre=expected_body)
|
||||
node = res.value.value
|
||||
|
||||
assert res.status
|
||||
assert res.who == parser.name
|
||||
assert res.value.source == text
|
||||
assert isinstance(res.value, ParserResultConcept)
|
||||
assert node == expected
|
||||
assert isinstance(node, DefConceptNode)
|
||||
assert sheerka.isinstance(node.pre, BuiltinConcepts.RETURN_VALUE)
|
||||
compare_with_test_object(node.pre.body.body, CV(concepts[0], pre=True))
|
||||
|
||||
def test_i_can_parse_bnf_concept_with_regex(self):
|
||||
sheerka, context, parser, number = self.init_parser("number")
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, CMV
|
||||
from core.concept import Concept
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from parsers.ExactConceptParser import ExactConceptParser
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import CMV, compare_with_test_object
|
||||
|
||||
|
||||
def variable_def(concept, prop_name):
|
||||
@@ -97,7 +98,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
assert results[0].status
|
||||
|
||||
concept_found = results[0].value.value
|
||||
assert concept_found == CMV(concept, a="10", b="5")
|
||||
compare_with_test_object(concept_found, CMV(concept, a="10", b="5"))
|
||||
assert concept_found.get_metadata().need_validation
|
||||
assert not concept_found.get_metadata().is_evaluated
|
||||
|
||||
@@ -113,7 +114,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
assert results[0].status
|
||||
|
||||
concept_found = results[0].value.value
|
||||
assert concept_found == CMV(concept, a="10", b="5")
|
||||
compare_with_test_object(concept_found, CMV(concept, a="10", b="5"))
|
||||
assert concept_found.get_metadata().need_validation
|
||||
|
||||
def test_i_can_parse_concept_when_defined_using_from_def(self):
|
||||
@@ -127,7 +128,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
assert concept_found == CMV(plus, a="10", b="5")
|
||||
compare_with_test_object(concept_found, CMV(plus, a="10", b="5"))
|
||||
assert concept_found.get_metadata().need_validation
|
||||
assert not concept_found.get_metadata().is_evaluated
|
||||
|
||||
@@ -157,7 +158,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
assert concept_found == CMV(plus, a="c:one:", b="c:two:")
|
||||
compare_with_test_object(concept_found, CMV(plus, a="c:one:", b="c:two:"))
|
||||
assert concept_found.get_metadata().need_validation
|
||||
assert not concept_found.get_metadata().is_evaluated
|
||||
|
||||
@@ -173,7 +174,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
assert concept_found == CMV(isa, c="z")
|
||||
compare_with_test_object(concept_found, CMV(isa, c="z"))
|
||||
assert concept_found.get_metadata().need_validation
|
||||
assert not concept_found.get_metadata().is_evaluated
|
||||
|
||||
@@ -183,7 +184,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
assert concept_found == CMV(def_concept, a="z")
|
||||
compare_with_test_object(concept_found, CMV(def_concept, a="z"))
|
||||
assert concept_found.get_metadata().need_validation
|
||||
assert not concept_found.get_metadata().is_evaluated
|
||||
|
||||
|
||||
@@ -3,11 +3,10 @@ import ast
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
|
||||
from core.concept import Concept, CMV, DoNotResolve, CC
|
||||
from core.concept import Concept, DoNotResolve
|
||||
from core.rule import Rule
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import TokenKind
|
||||
from parsers.BaseNodeParser import CNC
|
||||
from parsers.BaseParser import UnexpectedEofParsingError, UnexpectedTokenParsingError
|
||||
from parsers.ExpressionParser import ExpressionParser, LeftPartNotFoundError, ParenthesisMismatchError
|
||||
from parsers.PythonParser import PythonNode
|
||||
@@ -15,7 +14,7 @@ from parsers.expressions import TrueifyVisitor, IsAQuestionVisitor, AndNode
|
||||
from sheerkarete.network import ReteNetwork
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array, resolve_test_concept, EXPR, OR, AND, NOT, \
|
||||
get_expr_node_from_test_node, get_rete_conditions
|
||||
get_expr_node_from_test_node, get_rete_conditions, CMV, CNC, CC, compare_with_test_object
|
||||
|
||||
|
||||
class TestExpressionParser(TestUsingMemoryBasedSheerka):
|
||||
@@ -215,9 +214,9 @@ class TestExpressionParser(TestUsingMemoryBasedSheerka):
|
||||
("foo", "foo"),
|
||||
("one two", "one two"),
|
||||
("foo is a bar", CMV("is a", x='foo', y='bar')),
|
||||
("one two is a bar", [CNC("is a", source="one two is a bar", x="one two", y="bar")]),
|
||||
("one two is a bar", [CNC("is a", "one two is a bar", x="one two", y="bar")]),
|
||||
("foo is an foo bar",
|
||||
[CNC("is an", source="foo is an foo bar", x=DoNotResolve(value='foo'), exclude_body=True)]),
|
||||
[CNC("is an", "foo is an foo bar", x=DoNotResolve(value='foo'), exclude_body=True)]),
|
||||
])
|
||||
def test_i_can_get_compiled_expr_from_simple_concepts_expressions(self, expression, expected):
|
||||
concepts_map = {
|
||||
@@ -238,10 +237,10 @@ class TestExpressionParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
if isinstance(expected, list):
|
||||
expected_nodes = compute_expected_array(concepts_map, expression, expected)
|
||||
assert ret.body.body == expected_nodes
|
||||
compare_with_test_object(ret.body.body, expected_nodes)
|
||||
else:
|
||||
expected_concept = resolve_test_concept(concepts_map, expected)
|
||||
assert ret.body.body == expected_concept
|
||||
compare_with_test_object(ret.body.body, expected_concept)
|
||||
|
||||
@pytest.mark.parametrize("expression", [
|
||||
"a == 5",
|
||||
@@ -338,11 +337,11 @@ class TestExpressionParser(TestUsingMemoryBasedSheerka):
|
||||
ret = return_values[0]
|
||||
python_node = ret.body.body
|
||||
assert python_node == expected_python_node
|
||||
assert python_node.objects == {
|
||||
compare_with_test_object(python_node.objects, {
|
||||
"__C__00var0000is0a000var001__1005__C__": CC(is_a, x=cat, y=pet),
|
||||
"__C__00var0000is0an0y__1006__C__": CC(is_an, exclude_body=True, x=DoNotResolve("bird"), animal=animal),
|
||||
"__C__00var0000is0a000var001__1005_1__C__": CMV(is_a, x="dog", y="pet"),
|
||||
}
|
||||
})
|
||||
|
||||
def test_i_can_get_compiled_expr_from_mix(self):
|
||||
sheerka, context, animal, cat, dog, pet, is_a, is_an = self.init_test().with_concepts(
|
||||
@@ -369,11 +368,11 @@ class TestExpressionParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
python_node = ret.body.body
|
||||
assert python_node == expected_python_node
|
||||
assert python_node.objects == {
|
||||
compare_with_test_object(python_node.objects, {
|
||||
"__C__00var0000is0a000var001__1005__C__": CC(is_a, x=cat, y=pet),
|
||||
"__C__00var0000is0an0y__1006__C__": CC(is_an, exclude_body=True, x=DoNotResolve("bird"), animal=animal),
|
||||
"__C__00var0000is0a000var001__1005_1__C__": CMV(is_a, x="dog", y="pet"),
|
||||
}
|
||||
})
|
||||
|
||||
def test_i_can_get_compiled_expr_when_multiple_choices(self):
|
||||
sheerka, context, *concepts = self.init_test().with_concepts(
|
||||
@@ -390,10 +389,10 @@ class TestExpressionParser(TestUsingMemoryBasedSheerka):
|
||||
assert len(return_values) == 2
|
||||
|
||||
ret = return_values[0]
|
||||
assert sheerka.objvalue(ret)[0].concept == CMV(concepts[0], x="a", y="b")
|
||||
compare_with_test_object(sheerka.objvalue(ret)[0].concept, CMV(concepts[0], x="a", y="b"))
|
||||
|
||||
ret = return_values[1]
|
||||
assert sheerka.objvalue(ret)[0].concept == CMV(concepts[1], x="a", y="b")
|
||||
compare_with_test_object(sheerka.objvalue(ret)[0].concept, CMV(concepts[1], x="a", y="b"))
|
||||
|
||||
def test_i_can_get_compiled_expr_from_mix_when_multiple_choices(self):
|
||||
sheerka, context, *concepts = self.init_test().with_concepts(
|
||||
|
||||
@@ -3,10 +3,10 @@ import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from parsers.BaseNodeParser import SCN, SCWC, CN, UTN, CNC, RN
|
||||
from parsers.FunctionParser import FunctionParser, FN
|
||||
from parsers.FunctionParser import FunctionParser
|
||||
from parsers.PythonParser import PythonErrorNode
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array
|
||||
from tests.parsers.parsers_utils import compute_expected_array, SCN, SCWC, CN, UTN, CNC, RN, FN, get_test_obj
|
||||
|
||||
cmap = {
|
||||
"one": Concept("one"),
|
||||
@@ -80,60 +80,73 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
|
||||
parser.parser_input.next_token()
|
||||
|
||||
res = parser.parse_function()
|
||||
|
||||
assert res == expected
|
||||
transformed_res = get_test_obj(res, expected)
|
||||
assert transformed_res == expected
|
||||
|
||||
def test_i_can_parse_function_when_rule(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
expected = FN("func(", ")", ["r:|1:"])
|
||||
|
||||
parser.reset_parser(context, ParserInput("func(r:|1:)"))
|
||||
parser.parser_input.next_token()
|
||||
|
||||
res = parser.parse_function()
|
||||
|
||||
assert res == FN("func(", ")", ["r:|1:"])
|
||||
transformed_res = get_test_obj(res, expected)
|
||||
assert transformed_res == expected
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("func()", SCN("func()")),
|
||||
(" func()", SCN("func()")),
|
||||
("func(one)", SCWC("func(", ")", CN("one"))),
|
||||
("func(one, unknown, two)", SCWC("func(", ")", CN("one"), ", ", UTN("unknown"), (", ", 1), CN("two"))),
|
||||
("func(one, twenty two)", SCWC("func(", ")", "one", ", ", CN("twenties", source="twenty two"))),
|
||||
("func(one, twenty two)", SCWC("func(", ")", "one", ", ", CN("twenties", "twenty two"))),
|
||||
("func(one plus two, three)", SCWC("func(", ")", CNC("plus", a="one", b="two"), ", ", UTN("three"))),
|
||||
("func(func1(one), two)", SCWC("func(", (")", 1), SCWC("func1(", ")", "one"), ", ", "two"))
|
||||
])
|
||||
def test_i_can_parse(self, text, expected):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
resolved_expected = compute_expected_array(cmap, text, [expected])[0]
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
parser_result = res.body
|
||||
expression = res.body.body
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert expression == resolved_expected
|
||||
transformed_expression = get_test_obj(expression, resolved_expected)
|
||||
assert transformed_expression == resolved_expected
|
||||
assert expression.python_node is not None
|
||||
assert expression.return_value is not None
|
||||
|
||||
def test_i_can_parse_when_multiple_results_when_requested(self):
|
||||
# the previous output was
|
||||
# [
|
||||
# SCWC("func(", ")", "one", ", ", "twenty ", "two"),
|
||||
# SCWC("func(", ")", "one", ", ", CN("twenties", "twenty two"))
|
||||
# ]
|
||||
# But the first one is now filtered out, as it's not a valid python function call
|
||||
sheerka, context, parser = self.init_parser()
|
||||
parser.longest_concepts_only = False
|
||||
text = "func(one, twenty two)"
|
||||
expected = [SCWC("func(", ")", "one", ", ", "twenty ", "two"),
|
||||
SCWC("func(", ")", "one", ", ", CN("twenties", source="twenty two"))]
|
||||
all_resolved_expected = compute_expected_array(cmap, text, expected)
|
||||
expected = [SCWC("func(", ")", "one", ", ", CN("twenties", "twenty two"))]
|
||||
resolved_expected = compute_expected_array(cmap, text, expected)
|
||||
|
||||
results = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert len(results) == 2
|
||||
|
||||
for res, resolved_expected in zip(results, all_resolved_expected):
|
||||
parser_result = res.body
|
||||
expressions = res.body.body
|
||||
res = results[0]
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR)
|
||||
assert len(res.body.body) == 1
|
||||
assert (res.body.body[0], PythonErrorNode)
|
||||
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert expressions == resolved_expected
|
||||
res = results[1]
|
||||
parser_result = res.body
|
||||
expressions = res.body.body
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
transformed_expressions = get_test_obj(expressions, resolved_expected[0])
|
||||
assert transformed_expressions == resolved_expected[0]
|
||||
|
||||
def test_i_can_parse_when_the_parameter_is_not_a_concept(self):
|
||||
"""
|
||||
@@ -144,10 +157,15 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
|
||||
text = "func(unknown_concept)"
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
expected = [SCWC("func(", ")", "unknown_concept")]
|
||||
resolved_expected = compute_expected_array(cmap, text, expected)
|
||||
|
||||
assert res.status
|
||||
parsed = res.body.body
|
||||
transformed_parsed = get_test_obj([parsed], resolved_expected)
|
||||
assert transformed_parsed == resolved_expected
|
||||
|
||||
def test_i_cannot_parse_when_the_concept_is_not_found(self):
|
||||
def test_i_can_parse_when_the_concept_is_not_found(self):
|
||||
"""
|
||||
We do not check yet if it's a valid concept
|
||||
If you find a cheap way to do so, simply remove this test
|
||||
@@ -169,37 +187,24 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
parser_result = res.body
|
||||
expression = res.body.body
|
||||
transformed_expression = get_test_obj(expression, resolved_expected)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert expression == resolved_expected
|
||||
assert transformed_expression == resolved_expected
|
||||
assert expression.python_node is not None
|
||||
assert expression.return_value is not None
|
||||
|
||||
# def test_i_cannot_parse_when_rule_not_found(self):
|
||||
# sheerka, context, parser = self.init_parser()
|
||||
# text = "func(r:|fake:)"
|
||||
# expected = SCWC("func(", ")", RN("fake"))
|
||||
# resolved_expected = compute_expected_array(cmap, text, [expected])[0]
|
||||
#
|
||||
# res = parser.parse(context, ParserInput(text))
|
||||
# parser_result = res.body
|
||||
# expression = res.body.body
|
||||
#
|
||||
# assert not res.status
|
||||
# assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert expression == resolved_expected
|
||||
# assert expression.python_node is not None
|
||||
# assert expression.return_value is not None
|
||||
|
||||
@pytest.mark.parametrize("text, expected_error_type", [
|
||||
("one", BuiltinConcepts.NOT_FOR_ME),
|
||||
("$*!", BuiltinConcepts.NOT_FOR_ME),
|
||||
("func(", BuiltinConcepts.ERROR),
|
||||
("func(one", BuiltinConcepts.ERROR),
|
||||
("func(one, two, ", BuiltinConcepts.ERROR),
|
||||
("func(one) and func(two)", BuiltinConcepts.ERROR),
|
||||
("one func(one)", BuiltinConcepts.NOT_FOR_ME),
|
||||
("one", BuiltinConcepts.NOT_FOR_ME), # no function found
|
||||
("$*!", BuiltinConcepts.NOT_FOR_ME), # no function found
|
||||
("func(", BuiltinConcepts.ERROR), # function found, but incomplete
|
||||
("func(one", BuiltinConcepts.ERROR), # function found, but incomplete
|
||||
("func(one, two, ", BuiltinConcepts.ERROR), # function found, but incomplete
|
||||
("func(one) and func(two)", BuiltinConcepts.ERROR), # to many function
|
||||
("one func(one)", BuiltinConcepts.NOT_FOR_ME), # function not found ! (as it is not the first)
|
||||
("func(a=b, c)", BuiltinConcepts.ERROR), # function found, but cannot be parsed
|
||||
("func(one two)", BuiltinConcepts.ERROR), # function found, but cannot be parsed
|
||||
])
|
||||
def test_i_cannot_parse(self, text, expected_error_type):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -209,23 +214,6 @@ class TestFunctionParser(TestUsingMemoryBasedSheerka):
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, expected_error_type)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("func(one two)", SCWC("func(", ")", "one", "two")),
|
||||
])
|
||||
def test_i_can_detect_none_function(self, text, expected):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
resolved_expected = compute_expected_array(cmap, text, [expected])[0]
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
parser_result = res.body
|
||||
expression = res.body.body
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert expression == resolved_expected
|
||||
assert expression.python_node is None
|
||||
assert expression.return_value is None
|
||||
|
||||
@pytest.mark.parametrize("sequence, expected", [
|
||||
(None, None),
|
||||
([["a"]], [["a"]]),
|
||||
|
||||
@@ -7,7 +7,8 @@ from core.concept import Concept
|
||||
from core.rule import Rule
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import Token, TokenKind, Tokenizer
|
||||
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode, RuleNode, SourceCodeNode
|
||||
from core.var_ref import VariableRef
|
||||
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode, RuleNode, VariableNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
from parsers.PythonWithConceptsParser import PythonWithConceptsParser
|
||||
from parsers.UnrecognizedNodeParser import UnrecognizedNodeParser
|
||||
@@ -29,8 +30,12 @@ def ret_val(*args):
|
||||
tokens = [Token(TokenKind.RULE, (None, item.id), 0, 0, 0)]
|
||||
result.append(RuleNode(item, index, index, tokens, f"r:|{item.id}:"))
|
||||
index += 1
|
||||
elif isinstance(item, VariableRef):
|
||||
tokens = list(Tokenizer(item.prop, yield_eof=False))
|
||||
result.append(VariableNode(item.obj, item.prop, index, index + len(tokens) - 1, tokens, f"{item.prop}"))
|
||||
index += len(tokens)
|
||||
else:
|
||||
tokens = list(Tokenizer(item))
|
||||
tokens = list(Tokenizer(item, yield_eof=False))
|
||||
result.append(UnrecognizedTokensNode(index, index + len(tokens) - 1, tokens))
|
||||
index += len(tokens)
|
||||
|
||||
@@ -58,10 +63,10 @@ class TestPythonWithConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
else:
|
||||
assert res is None
|
||||
|
||||
def test_i_can_parse_concepts_and_python(self):
|
||||
def test_i_can_parse_concepts_python_and_variable_ref(self):
|
||||
context = self.get_context()
|
||||
foo = Concept("foo")
|
||||
input_return_value = ret_val(foo, " + 1")
|
||||
input_return_value = ret_val(foo, " + 1 + ", VariableRef(foo, "var_name"))
|
||||
|
||||
parser = PythonWithConceptsParser()
|
||||
result = parser.parse(context, input_return_value.body)
|
||||
@@ -71,12 +76,13 @@ class TestPythonWithConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
assert result.status
|
||||
assert result.who == parser.name
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert wrapper.source == "foo + 1"
|
||||
assert wrapper.source == "foo + 1 + var_name"
|
||||
assert isinstance(return_value, PythonNode)
|
||||
assert return_value.source == "__C__foo__C__ + 1"
|
||||
assert return_value.original_source == "foo + 1"
|
||||
assert return_value.get_dump(return_value.ast_) == to_str_ast("__C__foo__C__ + 1")
|
||||
assert return_value.objects["__C__foo__C__"] == foo
|
||||
assert return_value.source == "__C__foo__C__ + 1 + __V__foo__var_name__V__"
|
||||
assert return_value.original_source == "foo + 1 + var_name"
|
||||
assert return_value.get_dump(return_value.ast_) == to_str_ast("__C__foo__C__ + 1 + __V__foo__var_name__V__")
|
||||
assert return_value.objects == {"__C__foo__C__": foo,
|
||||
"__V__foo__var_name__V__": VariableRef(foo, "var_name")}
|
||||
|
||||
def test_i_can_parse_concepts_and_python_when_concept_is_known(self):
|
||||
context = self.get_context()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, DEFINITION_TYPE_DEF
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from parsers.SequenceNodeParser import SequenceNodeParser
|
||||
from parsers.BaseNodeParser import cnode, utnode, CNC, SCN, CN
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array
|
||||
from tests.parsers.parsers_utils import compute_expected_array, CN, CNC, SCN, get_test_obj, compare_with_test_object, \
|
||||
UTN
|
||||
|
||||
|
||||
class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
@@ -40,8 +40,8 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
(" foo ", ["foo"]),
|
||||
("foo bar", ["foo", "bar"]),
|
||||
("foo bar twenties", ["foo", "bar", "twenties"]),
|
||||
("a plus b", [CN("plus", 0, 4)]),
|
||||
("mult", [CN("mult", 0, 0, "mult")]),
|
||||
("a plus b", [CN("plus", None, 0, 4)]),
|
||||
("mult", [CN("mult", "mult", 0, 0)]),
|
||||
])
|
||||
def test_i_can_parse_simple_sequences(self, text, expected):
|
||||
concepts_map = {
|
||||
@@ -62,7 +62,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected)
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("foo bar", ["foo bar"]),
|
||||
@@ -85,7 +85,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected)
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
@pytest.mark.parametrize("text, expected_status, expected", [
|
||||
("foo bar suffixed one", False, ["foo bar", " suffixed ", "one"]),
|
||||
@@ -123,12 +123,12 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected)
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
@pytest.mark.parametrize("text, expected_status, expected", [
|
||||
(" one two ", True, [cnode("one", 1, 1, "one"), cnode("two", 3, 3, "two")]),
|
||||
(" one x$!# ", False, [cnode("one", 1, 1, "one"), utnode(2, 7, " x$!# ")]),
|
||||
(" foo bar x$!# ", False, [cnode("foo bar", 1, 3, "foo bar"), utnode(4, 9, " x$!# ")]),
|
||||
(" one two ", True, [CN("one", "one", 1, 1), CN("two", "two", 3, 3)]),
|
||||
(" one x$!# ", False, [CN("one", "one", 1, 1), UTN(" x$!# ", 2, 7)]),
|
||||
(" foo bar x$!# ", False, [CN("foo bar", "foo bar", 1, 3), UTN(" x$!# ", 4, 9)]),
|
||||
])
|
||||
def test_i_can_parse_when_surrounded_by_spaces(self, text, expected_status, expected):
|
||||
concepts_map = {
|
||||
@@ -150,7 +150,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected)
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("one two", [["one", "two"], ["one two"]])
|
||||
@@ -173,7 +173,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
assert res.status
|
||||
expected_array = compute_expected_array(concepts_map, text, expected[i])
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_multiple_concepts_when_long_names_and_unrecognized(self):
|
||||
concepts_map = {
|
||||
@@ -204,7 +204,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
assert res.status == expected[0]
|
||||
expected_array = compute_expected_array(concepts_map, text, expected[1])
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_concepts_with_isa(self):
|
||||
concepts_map = {
|
||||
@@ -218,7 +218,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
res = parser.parse(context, ParserInput("one"))
|
||||
lexer_nodes = res.body.body
|
||||
expected_array = compute_expected_array(concepts_map, "one", ["one"])
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_concepts_with_keyword(self):
|
||||
concepts_map = {
|
||||
@@ -231,12 +231,12 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
res = parser.parse(context, ParserInput("a special concept"))
|
||||
lexer_nodes = res.body.body
|
||||
expected_array = compute_expected_array(concepts_map, "a special concept", ["a special concept"])
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
res = parser.parse(context, ParserInput("isa"))
|
||||
lexer_nodes = res.body.body
|
||||
expected_array = compute_expected_array(concepts_map, "isa", ["isa"])
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_concepts_when_sub_tokens(self):
|
||||
concepts_map = {
|
||||
@@ -256,7 +256,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected)
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
compare_with_test_object(lexer_nodes, expected_array)
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"foo",
|
||||
@@ -283,8 +283,8 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("hello foo bar",
|
||||
[
|
||||
(True, [CNC("hello1", source="hello foo ", a="foo "), "bar"]),
|
||||
(True, [CNC("hello2", source="hello foo ", b="foo "), "bar"]),
|
||||
(True, [CNC("hello1", "hello foo ", a="foo "), "bar"]),
|
||||
(True, [CNC("hello2", "hello foo ", b="foo "), "bar"]),
|
||||
]),
|
||||
])
|
||||
def test_i_can_parse_when_unrecognized_yield_multiple_values(self, text, expected):
|
||||
@@ -304,9 +304,10 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
lexer_nodes = res.body.body
|
||||
|
||||
assert res.status == expected[0]
|
||||
expected_array = compute_expected_array(concepts_map, text, expected[1])
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
expected_array = compute_expected_array(concepts_map, text, expected[1])
|
||||
transformed_nodes = get_test_obj(lexer_nodes, expected_array)
|
||||
assert transformed_nodes == expected_array
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("1 + twenty one", [SCN("1 + twenty "), "one"]),
|
||||
@@ -326,7 +327,8 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected)
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
transformed_nodes = get_test_obj(lexer_nodes, expected_array)
|
||||
assert transformed_nodes == expected_array
|
||||
|
||||
@pytest.mark.parametrize("text, expected_is_evaluated", [
|
||||
("foo", False),
|
||||
|
||||
+129
-123
@@ -2,18 +2,19 @@ import pytest
|
||||
|
||||
import tests.parsers.parsers_utils
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, CIO, CMV
|
||||
from core.concept import Concept
|
||||
from core.global_symbols import CONCEPT_COMPARISON_CONTEXT
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import Tokenizer
|
||||
from core.utils import NextIdManager
|
||||
from parsers.BaseNodeParser import utnode, cnode, short_cnode, UnrecognizedTokensNode, \
|
||||
SCWC, CNC, UTN, SCN, CN
|
||||
from parsers.BaseNodeParser import UnrecognizedTokensNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
from parsers.SyaNodeParser import SyaNodeParser, SyaConceptParserHelper, SyaAssociativity, \
|
||||
NoneAssociativeSequenceError, TooManyParametersFoundError, InFixToPostFix, ParenthesisMismatchError
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import UTN, SCWC, CNC, SCN, CIO, CN, compute_debug_array, CMV, get_test_obj, \
|
||||
compare_with_test_object
|
||||
|
||||
|
||||
def compute_expected_array(concepts_map, expression, expected):
|
||||
@@ -102,6 +103,16 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
parser.init_from_concepts(context, concepts, sya=sya_def_to_use)
|
||||
return sheerka, context, parser
|
||||
|
||||
@staticmethod
|
||||
def compare_results(res, expected_sequences, concept_map, expression, validate_errors=True):
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
if validate_errors:
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(concept_map, expression, expected)
|
||||
res_i_as_test_obj = get_test_obj(res_i.out, expected_array)
|
||||
assert res_i_as_test_obj == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("one plus two", [["one", "two", "plus"]]),
|
||||
("1 + 1 plus two", [["1 + 1", "two", "plus"]]),
|
||||
@@ -110,7 +121,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
["one + two", "three", "plus"]]),
|
||||
("twenty one plus two", [
|
||||
["twenty ", "one", "two", "plus"],
|
||||
[short_cnode("twenties", "twenty one"), "two", "plus"]
|
||||
[CN("twenties", "twenty one"), "two", "plus"]
|
||||
]),
|
||||
("x$!# plus two", [["x$!#", "two", "plus"]]),
|
||||
|
||||
@@ -122,7 +133,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
]),
|
||||
("twenty one plus 1 + 1", [
|
||||
["twenty ", "one", "1 + 1", "plus"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), "1 + 1", "plus"]
|
||||
[CN("twenties", "twenty one", 0, 2), "1 + 1", "plus"]
|
||||
]),
|
||||
("x$!# plus 1 + 1", [["x$!#", "1 + 1", "plus"]]),
|
||||
|
||||
@@ -142,9 +153,9 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
]),
|
||||
("twenty one plus two + three", [
|
||||
["twenty ", "one", "two", "plus", " + ", "three"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), "two", "plus", " + ", "three"],
|
||||
[CN("twenties", "twenty one", 0, 2), "two", "plus", " + ", "three"],
|
||||
["twenty ", "one", "two + three", "plus"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), "two + three", "plus"],
|
||||
[CN("twenties", "twenty one", 0, 2), "two + three", "plus"],
|
||||
]),
|
||||
("x$!# plus two + three", [
|
||||
["x$!#", "two", "plus", " + ", "three"],
|
||||
@@ -153,28 +164,28 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
("one plus twenty two", [
|
||||
["one", "twenty ", "plus", "two"],
|
||||
["one", cnode("twenties", 4, 6, "twenty two"), "plus"],
|
||||
["one", CN("twenties", "twenty two", 4, 6), "plus"],
|
||||
]),
|
||||
("1 + 1 plus twenty one", [
|
||||
["1 + 1", "twenty ", "plus", "one"],
|
||||
["1 + 1", cnode("twenties", 8, 10, "twenty one"), "plus"],
|
||||
["1 + 1", CN("twenties", "twenty one", 8, 10), "plus"],
|
||||
]),
|
||||
("one + two plus twenty one", [
|
||||
["one", " + ", "two", "twenty ", "plus", ("one", 1)],
|
||||
["one + two", "twenty ", "plus", ("one", 1)],
|
||||
["one", " + ", "two", cnode("twenties", 8, 10, "twenty one"), "plus"],
|
||||
["one + two", cnode("twenties", 8, 10, "twenty one"), "plus"],
|
||||
["one", " + ", "two", CN("twenties", "twenty one", 8, 10), "plus"],
|
||||
["one + two", CN("twenties", "twenty one", 8, 10), "plus"],
|
||||
]),
|
||||
("twenty one plus twenty two",
|
||||
[
|
||||
["twenty ", "one", ("twenty ", 1), "plus", "two"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), ("twenty ", 1), "plus", "two"],
|
||||
["twenty ", "one", cnode("twenties", 6, 8, "twenty two"), "plus"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), cnode("twenties", 6, 8, "twenty two"), "plus"],
|
||||
[CN("twenties", "twenty one", 0, 2), ("twenty ", 1), "plus", "two"],
|
||||
["twenty ", "one", CN("twenties", "twenty two", 6, 8), "plus"],
|
||||
[CN("twenties", "twenty one", 0, 2), CN("twenties", "twenty two", 6, 8), "plus"],
|
||||
]),
|
||||
("x$!# plus twenty two", [
|
||||
["x$!#", "twenty ", "plus", "two"],
|
||||
["x$!#", cnode("twenties", 7, 9, "twenty two"), "plus"]
|
||||
["x$!#", CN("twenties", "twenty two", 7, 9), "plus"]
|
||||
]),
|
||||
|
||||
("one plus z$!#", [["one", "z$!#", "plus"]]),
|
||||
@@ -185,7 +196,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
]),
|
||||
("twenty one plus z$!#", [
|
||||
["twenty ", "one", "z$!#", "plus"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), "z$!#", "plus"],
|
||||
[CN("twenties", "twenty one", 0, 2), "z$!#", "plus"],
|
||||
]),
|
||||
("x$!# plus z$!#", [["x$!#", "z$!#", "plus"]]),
|
||||
])
|
||||
@@ -194,17 +205,13 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, cmap, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("one plus plus plus 1 + 1", [["one", "1 + 1", "plus plus plus"]]),
|
||||
("x$!# another long name infix twenty two", [
|
||||
["x$!#", "twenty ", "another long name infix", "two"],
|
||||
["x$!#", cnode("twenties", 13, 15, "twenty two"), "another long name infix"],
|
||||
["x$!#", CN("twenties", "twenty two", 13, 15), "another long name infix"],
|
||||
]),
|
||||
])
|
||||
def test_i_can_post_fix_infix_concepts_with_long_name(self, expression, expected_sequences):
|
||||
@@ -220,11 +227,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, concepts_map, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("one prefixed", [["one", "prefixed"]]),
|
||||
@@ -235,7 +238,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
]),
|
||||
("twenty one prefixed", [
|
||||
["twenty ", "one", "prefixed"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), "prefixed"],
|
||||
[CN("twenties", "twenty one", 0, 2), "prefixed"],
|
||||
]),
|
||||
("x$!# prefixed", [["x$!#", "prefixed"]]),
|
||||
])
|
||||
@@ -244,11 +247,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, cmap, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("one prefixed prefixed", [["one", "prefixed prefixed"]]),
|
||||
@@ -259,7 +258,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
]),
|
||||
("twenty one prefixed prefixed", [
|
||||
["twenty ", "one", "prefixed prefixed"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), "prefixed prefixed"],
|
||||
[CN("twenties", "twenty one", 0, 2), "prefixed prefixed"],
|
||||
]),
|
||||
("x$!# prefixed prefixed", [["x$!#", "prefixed prefixed"]]),
|
||||
|
||||
@@ -271,7 +270,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
]),
|
||||
("twenty one long name prefixed", [
|
||||
["twenty ", "one", "long name prefixed"],
|
||||
[cnode("twenties", 0, 2, "twenty one"), "long name prefixed"],
|
||||
[CN("twenties", "twenty one", 0, 2), "long name prefixed"],
|
||||
]),
|
||||
("x$!# long name prefixed", [["x$!#", "long name prefixed"]]),
|
||||
])
|
||||
@@ -287,11 +286,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, concepts_map, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("suffixed one", [["one", "suffixed"]]),
|
||||
@@ -302,7 +297,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
]),
|
||||
("suffixed twenty one", [
|
||||
["twenty ", "suffixed", "one"],
|
||||
[cnode("twenties", 2, 4, "twenty one"), "suffixed"],
|
||||
[CN("twenties", "twenty one", 2, 4), "suffixed"],
|
||||
]),
|
||||
("suffixed x$!#", [["x$!#", "suffixed"]]),
|
||||
])
|
||||
@@ -311,11 +306,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, cmap, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("suffixed suffixed one", ["one", "suffixed suffixed"]),
|
||||
@@ -333,8 +324,10 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("one ? two : three", [["one", "two", "three", "?"]]),
|
||||
@@ -342,14 +335,14 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
("1+1 ? one + two : twenty one", [
|
||||
["1+1", "one", " + ", "two"], # error is detected so the parsing has stopped
|
||||
["1+1", "one + two", "twenty ", "?", ("one", 1)],
|
||||
["1+1", "one + two", short_cnode("twenties", "twenty one"), "?"],
|
||||
["1+1", "one + two", CN("twenties", "twenty one"), "?"],
|
||||
]),
|
||||
("x$!# ? y$!# : z$!#", [["x$!#", "y$!#", "z$!#", "?"]]),
|
||||
|
||||
("if one then two else three end", [["one", "two", "three", "if"]]),
|
||||
("if 1+1 then x$!# else twenty one end", [
|
||||
["1+1", "x$!#", "twenty ", "one"], # an error is detected
|
||||
["1+1", "x$!#", short_cnode("twenties", "twenty one"), "if"],
|
||||
["1+1", "x$!#", CN("twenties", "twenty one"), "if"],
|
||||
]),
|
||||
("if x$!# then one + two else z$!# end", [
|
||||
["x$!#", "one", " + ", "two"], # error is detected so the parsing has stopped
|
||||
@@ -373,24 +366,20 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
# assert len(res_i.errors) == 0 # Do not validate errors
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, cmap, expression, validate_errors=False)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("one ? ? two : : three", [["one", "two", "three", "? ?"]]),
|
||||
("1+1 ? ? one + two : : twenty one", [
|
||||
["1+1", "one", " + ", "two"], # error
|
||||
["1+1", "one + two", "twenty ", "? ?", ("one", 1)],
|
||||
["1+1", "one + two", short_cnode("twenties", "twenty one"), "? ?"],
|
||||
["1+1", "one + two", CN("twenties", "twenty one"), "? ?"],
|
||||
]),
|
||||
|
||||
("if if one then then two else else three end end ", [["one", "two", "three", "if if"]]),
|
||||
("if if 1+1 then then x$!# else else twenty one end end ", [
|
||||
["1+1", "x$!#", "twenty ", "one"], # error
|
||||
["1+1", "x$!#", short_cnode("twenties", "twenty one"), "if if"]]),
|
||||
["1+1", "x$!#", CN("twenties", "twenty one"), "if if"]]),
|
||||
])
|
||||
def test_i_can_post_fix_ternary_concept_with_long_names(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
@@ -405,11 +394,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
# assert len(res_i.errors) == 0 # Do not validate errors
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, concepts_map, expression, validate_errors=False)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("foo bar baz", ["baz", "bar", "foo"]),
|
||||
@@ -428,7 +413,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("baz bar foo", ["baz", "bar", "foo"]),
|
||||
@@ -451,7 +437,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("one plus two mult three", ["one", "two", "three", "mult", "plus"]),
|
||||
@@ -466,7 +453,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
def test_i_can_post_fix_unary_with_precedence(self):
|
||||
concepts_map = {
|
||||
@@ -487,7 +475,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
# change the precedence
|
||||
sya_def = {
|
||||
@@ -502,7 +491,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
def test_i_can_post_fix_right_associated_binary(self):
|
||||
concepts_map = {
|
||||
@@ -524,7 +514,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
def test_i_can_post_fix_left_associated_binary(self):
|
||||
concepts_map = {
|
||||
@@ -546,7 +537,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("x$!# ? y$!# : z$!# ? two : three", ["x$!#", "y$!#", "z$!#", "two", "three", ("?", 1), "?"]),
|
||||
@@ -572,8 +564,10 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("x$!# ? y$!# : z$!# ? two : three", ["x$!#", "y$!#", "z$!#", "?", "two", "three", ("?", 1)]),
|
||||
@@ -599,8 +593,10 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
def test_i_can_post_fix_when_multiple_concepts_are_found(self):
|
||||
concepts_map = {
|
||||
@@ -617,11 +613,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
["baz", "foo bar"]
|
||||
]
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, concepts_map, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
# ("function(one plus three) minus two",
|
||||
@@ -667,7 +659,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
# composition
|
||||
@@ -681,20 +674,18 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
[[SCWC("function(", ")", CNC("prefixed", a=CIO("twenties", source="twenty two")))]]),
|
||||
("function(if one then twenty two else three end)",
|
||||
[[SCWC("function(", ")", CNC("if", a="one", b=CIO("twenties", source="twenty two"), c="three", end=16))]]),
|
||||
("func1(func2(one two) three)",
|
||||
[[SCWC("func1(", (")", 1), SCWC("func2(", ")", "one", "two"), "three")]]),
|
||||
|
||||
("twenty two(suffixed one)", [
|
||||
["twenty ", SCWC("two(", ")", CNC("suffixed", a="one"))],
|
||||
[CN("twenties", source="twenty two"), "one", "suffixed"],
|
||||
[CN("twenties", "twenty two"), "one", "suffixed"],
|
||||
]),
|
||||
("twenty two(one prefixed)", [
|
||||
["twenty ", SCWC("two(", ")", CNC("prefixed", a="one"))],
|
||||
[CN("twenties", source="twenty two"), "one", "prefixed"],
|
||||
[CN("twenties", "twenty two"), "one", "prefixed"],
|
||||
]),
|
||||
("f1(one plus two mult three) plus f2(suffixed x$!# prefixed)", [
|
||||
[SCWC("f1(", ")", CN("plus", source="one plus two mult three")),
|
||||
SCWC("f2(", (")", 1), CN("suffixed", source="suffixed x$!# prefixed")),
|
||||
("f1(one plus two mult three) plus f2(suffixed xxx prefixed)", [
|
||||
[SCWC("f1(", ")", CN("plus", "one plus two mult three")),
|
||||
SCWC("f2(", (")", 1), CN("suffixed", "suffixed xxx prefixed")),
|
||||
("plus", 1)]
|
||||
]),
|
||||
|
||||
@@ -706,8 +697,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
[SCWC("f1(", ")", "one"), SCWC("f2(", (")", 1), "two"), SCWC("f3(", (")", 2), "three"), "if"]]),
|
||||
|
||||
# Sequence
|
||||
("if one then two else three end function(x$!#)", [
|
||||
["one", "two", "three", "if", UTN(" ", start=13, end=13), SCWC("function(", ")", "x$!#")]]),
|
||||
("if one then two else three end function(xxx)", [
|
||||
["one", "two", "three", "if", UTN(" ", start=13, end=13), SCWC("function(", ")", "xxx")]]),
|
||||
("one prefixed function(two)", [["one", "prefixed", UTN(" ", start=3, end=3), SCWC("function(", ")", "two")]]),
|
||||
("suffixed one function(two)", [["one", "suffixed", UTN(" ", start=3, end=3), SCWC("function(", ")", "two")]]),
|
||||
("func(one, two, three)", [[SCWC("func(", ")", "one", ", ", "two", (", ", 1), "three")]]),
|
||||
@@ -717,10 +708,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
self.compare_results(res, expected_sequences, cmap, expression)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("(", ("(", 0)),
|
||||
@@ -800,7 +788,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression", [
|
||||
"one ? two : three",
|
||||
@@ -818,7 +807,8 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
def test_the_more_concepts_the_more_results(self):
|
||||
concepts_map = {
|
||||
@@ -837,7 +827,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expression = "a plus plus equals b"
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
expected_array = tests.parsers.parsers_utils.compute_debug_array(res)
|
||||
expected_array = compute_debug_array(res)
|
||||
assert len(expected_array) == len([
|
||||
["T(a)", "C(a plus b)", "C(a plus b)", "T(equals)", "T(b)"],
|
||||
["T(a)", "C(a plus b)", "C(a plus plus)", "T(equals)", "T(b)"],
|
||||
@@ -861,14 +851,17 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
|
||||
res = parser.infix_to_postfix(context, ParserInput("one ? ? two '::' three"))
|
||||
assert len(res) == 1
|
||||
assert res[0].out == [
|
||||
cnode("one", start=0, end=0, source="one"),
|
||||
cnode("two", start=6, end=6, source="two"),
|
||||
cnode("three", start=10, end=10, source="three"),
|
||||
expected_array = [
|
||||
CN("one", start=0, end=0, source="one"),
|
||||
CN("two", start=6, end=6, source="two"),
|
||||
CN("three", start=10, end=10, source="three"),
|
||||
SyaConceptParserHelper(concepts_map["ternary"], 2),
|
||||
]
|
||||
|
||||
assert len(res) == 1
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
def test_i_cannot_chain_non_associative(self):
|
||||
concepts_map = {
|
||||
"less than": Concept("a less than b").def_var("a").def_var("b"),
|
||||
@@ -897,10 +890,12 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expression = "suffixed twenties"
|
||||
res = parser.infix_to_postfix(context, ParserInput(expression))
|
||||
|
||||
expected = [cnode("twenties", 2, 2, "twenties"), "suffixed"]
|
||||
expected = [CN("twenties", "twenties", 2, 2), "suffixed"]
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
transformed_out = get_test_obj(res[0].out, expected_array)
|
||||
assert transformed_out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_debugs", [
|
||||
("one", [[" 0:one => PUSH_UNREC"]]),
|
||||
@@ -999,12 +994,12 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [CN(cmap["plus"], 0, 8, source=text)]
|
||||
compare_with_test_object(lexer_nodes, [CN(cmap["plus"], text, 0, 8)])
|
||||
|
||||
# check the compiled
|
||||
expected_concept = lexer_nodes[0].concept
|
||||
assert expected_concept.get_compiled()["a"] == cmap["one"]
|
||||
assert expected_concept.get_compiled()["b"] == CMV(cmap["mult"], a="two", b="three")
|
||||
compare_with_test_object(expected_concept.get_compiled()["b"], CMV(cmap["mult"], a="two", b="three"))
|
||||
assert expected_concept.get_compiled()["b"].get_compiled()["a"] == cmap["two"]
|
||||
assert expected_concept.get_compiled()["b"].get_compiled()["b"] == cmap["three"]
|
||||
|
||||
@@ -1023,7 +1018,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [CN(cmap["suffixed"], 0, 6, source=text)]
|
||||
compare_with_test_object(lexer_nodes, [CN(cmap["suffixed"], text, 0, 6)])
|
||||
|
||||
# check the compiled
|
||||
expected_concept = lexer_nodes[0].concept
|
||||
@@ -1051,7 +1046,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
lexer_nodes = res[1].body.body
|
||||
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [CN(cmap["suffixed"], 0, 4, source=text)]
|
||||
compare_with_test_object(lexer_nodes, [CN(cmap["suffixed"], text, 0, 4)])
|
||||
|
||||
# check the compiled
|
||||
expected_concept = lexer_nodes[0].concept
|
||||
@@ -1071,9 +1066,9 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [
|
||||
CN(cmap["plus"], 0, 9, source="one plus 1 + 1 "),
|
||||
CN(cmap["suffixed"], 10, 12, source="suffixed two")]
|
||||
compare_with_test_object(lexer_nodes, [
|
||||
CN(cmap["plus"], "one plus 1 + 1 ", 0, 9),
|
||||
CN(cmap["suffixed"], "suffixed two", 10, 12)])
|
||||
|
||||
# check the compiled
|
||||
concept_plus_a = lexer_nodes[0].concept.get_compiled()["a"]
|
||||
@@ -1105,7 +1100,9 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(cmap, text, expected_result)
|
||||
assert res.status == expected_status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
|
||||
transformed_nodes = get_test_obj(lexer_nodes, expected_array)
|
||||
assert transformed_nodes == expected_array
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"function(suffixed one)",
|
||||
@@ -1166,11 +1163,15 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(cmap, text, expected_result)
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
|
||||
transformed_nodes = get_test_obj(lexer_nodes, expected_array)
|
||||
assert transformed_nodes == expected_array
|
||||
|
||||
# assert lexer_nodes == expected_array
|
||||
|
||||
@pytest.mark.parametrize("text, expected_result", [
|
||||
("a plus b", [CN("plus", source="a plus b")]),
|
||||
("suffixed a plus b", [CN("suffixed", source="suffixed a plus b")]),
|
||||
("a plus b", [CN("plus", "a plus b")]),
|
||||
("suffixed a plus b", [CN("suffixed", "suffixed a plus b")]),
|
||||
])
|
||||
def test_i_can_almost_parse_concept_definition(self, text, expected_result):
|
||||
"""
|
||||
@@ -1190,7 +1191,9 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(cmap, text, expected_result)
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
transformed_nodes = get_test_obj(lexer_nodes, expected_array)
|
||||
assert transformed_nodes == expected_array
|
||||
# assert lexer_nodes == expected_array
|
||||
|
||||
@pytest.mark.parametrize("text, expected_concept, expected_unrecognized", [
|
||||
("x$!# prefixed", "prefixed", ["a"]),
|
||||
@@ -1209,15 +1212,18 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [CN(cmap[expected_concept], 0, expected_end, source=text)]
|
||||
expected_array = [CN(cmap[expected_concept], text, 0, expected_end)]
|
||||
transformed_nodes = get_test_obj(lexer_nodes, expected_array)
|
||||
assert transformed_nodes == expected_array
|
||||
# assert lexer_nodes == [CN(cmap[expected_concept], text, 0, expected_end)]
|
||||
|
||||
concept_found = lexer_nodes[0].concept
|
||||
for unrecognized in expected_unrecognized:
|
||||
assert isinstance(concept_found.get_compiled()[unrecognized], UnrecognizedTokensNode)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("x$!# suffixed one", [utnode(0, 4, "x$!# "), cnode("suffixed __var__0", 5, 7, "suffixed one")]),
|
||||
("one prefixed x$!#", [cnode("__var__0 prefixed", 0, 2, "one prefixed"), utnode(3, 7, " x$!#")]),
|
||||
("x$!# suffixed one", [UTN("x$!# ", 0, 4), CN("suffixed __var__0", "suffixed one", 5, 7)]),
|
||||
("one prefixed x$!#", [CN("__var__0 prefixed", "one prefixed", 0, 2), UTN(" x$!#", 3, 7)]),
|
||||
])
|
||||
def test_i_cannot_parse_when_part_of_the_sequence_is_not_recognized(self, text, expected):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -1228,7 +1234,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected
|
||||
compare_with_test_object(lexer_nodes, expected)
|
||||
|
||||
def test_i_cannot_parse_function_using_short_name(self):
|
||||
concepts_map = {
|
||||
@@ -1301,15 +1307,15 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(actual) == 1
|
||||
|
||||
assert actual[0].to_out == resolved_to_out
|
||||
compare_with_test_object(actual[0].to_out, resolved_to_out)
|
||||
actual[0].function.fix_source()
|
||||
assert actual[0].function == resolved_function_name[0]
|
||||
compare_with_test_object(actual[0].function, resolved_function_name[0])
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_list", [
|
||||
("twenty two function(", [(["twenty ", "two", UTN(" ", 3, 3)], "function("),
|
||||
([CN("twenties", source="twenty two"), UTN(" ", 3, 3)], "function(")]),
|
||||
([CN("twenties", "twenty two"), UTN(" ", 3, 3)], "function(")]),
|
||||
("twenty two(", [(["twenty "], "two("),
|
||||
([CN("twenties", source="twenty two")], None)]),
|
||||
([CN("twenties", "twenty two")], None)]),
|
||||
])
|
||||
def test_i_can_get_functions_names_from_unrecognized_when_multiple_results(self, expression, expected_list):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -1326,11 +1332,11 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
for actual, expected in zip(actual_list, expected_list):
|
||||
resolved_to_out = compute_expected_array(cmap, expression, expected[0])
|
||||
|
||||
assert actual.to_out == resolved_to_out
|
||||
compare_with_test_object(actual.to_out, resolved_to_out)
|
||||
if actual.function:
|
||||
actual.function.fix_source()
|
||||
resolved_function_name = compute_expected_array(cmap, expression, [expected[1]])
|
||||
assert actual.function == resolved_function_name[0]
|
||||
compare_with_test_object(actual.function, resolved_function_name[0])
|
||||
else:
|
||||
assert actual.function is None
|
||||
|
||||
@@ -1344,7 +1350,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [CN(cmap["suffixed"], 0, 6, source=text)]
|
||||
compare_with_test_object(lexer_nodes, [CN(cmap["suffixed"], text, 0, 6)])
|
||||
|
||||
# add an ontology layer and make sure will still can parse
|
||||
sheerka.push_ontology(context, "new ontology")
|
||||
@@ -1356,7 +1362,7 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [CN(cmap["suffixed"], 0, 6, source=text)]
|
||||
compare_with_test_object(lexer_nodes, [CN(cmap["suffixed"], text, 0, 6)])
|
||||
|
||||
|
||||
class TestFileBaseSyaNodeParser(TestUsingFileBasedSheerka):
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept, CC
|
||||
from core.concept import Concept
|
||||
from core.tokenizer import Tokenizer, TokenKind
|
||||
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode, scnode, cnode, \
|
||||
utnode, CN, CNC, UTN, SourceCodeWithConceptNode, SCWC, SourceCodeNode
|
||||
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode, SourceCodeWithConceptNode, SourceCodeNode
|
||||
from parsers.BnfNodeParser import BnfNodeParser
|
||||
from parsers.SequenceNodeParser import SequenceNodeParser
|
||||
from parsers.SyaNodeParser import SyaNodeParser
|
||||
from parsers.UnrecognizedNodeParser import UnrecognizedNodeParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array, get_node
|
||||
from tests.parsers.parsers_utils import compute_expected_array, get_node, CC, UTN, CNC, CN, SCWC, \
|
||||
compare_with_test_object, SCN
|
||||
|
||||
|
||||
def get_input_nodes_from(my_concepts_map, full_expr, *args):
|
||||
@@ -19,10 +19,10 @@ def get_input_nodes_from(my_concepts_map, full_expr, *args):
|
||||
concept.get_compiled()[k] = _get_real_node(v)
|
||||
return concept
|
||||
|
||||
if isinstance(n, (utnode, UTN)):
|
||||
if isinstance(n, UTN):
|
||||
return UnrecognizedTokensNode(n.start, n.end, full_expr_as_tokens[n.start: n.end + 1])
|
||||
|
||||
if isinstance(n, (CNC, CN, cnode)):
|
||||
if isinstance(n, (CNC, CN)):
|
||||
concept = n.concept if hasattr(n, "concept") and n.concept else \
|
||||
Concept().update_from(my_concepts_map[n.concept_key])
|
||||
tokens = full_expr_as_tokens[n.start: n.end + 1]
|
||||
@@ -116,7 +116,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
a=" one ",
|
||||
b=" two three ",
|
||||
c=" twenty one ",
|
||||
d=utnode(12, 18, " 1 + 2 "),
|
||||
d=UTN(" 1 + 2 ", 12, 18),
|
||||
e=" one plus two mult three"))[0]
|
||||
|
||||
res = UnrecognizedNodeParser().validate_concept_node(context, node)
|
||||
@@ -130,13 +130,14 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isinstance(concept.get_compiled()["a"][0], BuiltinConcepts.RETURN_VALUE)
|
||||
assert concept.get_compiled()["a"][0].status
|
||||
assert concept.get_compiled()["a"][0].who == "parsers." + SequenceNodeParser.NAME
|
||||
assert concept.get_compiled()["a"][0].body.body == [cnode("one", 1, 1, "one")]
|
||||
compare_with_test_object(concept.get_compiled()["a"][0].body.body, [CN("one", "one", 1, 1)])
|
||||
|
||||
assert len(concept.get_compiled()["b"]) == 1
|
||||
assert sheerka.isinstance(concept.get_compiled()["b"][0], BuiltinConcepts.RETURN_VALUE)
|
||||
assert concept.get_compiled()["b"][0].status
|
||||
assert concept.get_compiled()["b"][0].who == "parsers." + SequenceNodeParser.NAME
|
||||
assert concept.get_compiled()["b"][0].body.body == [cnode("two", 1, 1, "two"), cnode("three", 3, 3, "three")]
|
||||
compare_with_test_object(concept.get_compiled()["b"][0].body.body,
|
||||
[CN("two", "two", 1, 1), CN("three", "three", 3, 3)])
|
||||
|
||||
assert len(concept.get_compiled()["c"]) == 1
|
||||
assert sheerka.isinstance(concept.get_compiled()["c"][0], BuiltinConcepts.RETURN_VALUE)
|
||||
@@ -145,8 +146,8 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_nodes = compute_expected_array(
|
||||
concepts_map,
|
||||
" twenty one ",
|
||||
[CNC("twenties", source="twenty one", unit="one")])
|
||||
assert concept.get_compiled()["c"][0].body.body == expected_nodes
|
||||
[CNC("twenties", "twenty one", unit="one")])
|
||||
compare_with_test_object(concept.get_compiled()["c"][0].body.body, expected_nodes)
|
||||
|
||||
assert len(concept.get_compiled()["d"]) == 1
|
||||
assert sheerka.isinstance(concept.get_compiled()["d"][0], BuiltinConcepts.RETURN_VALUE)
|
||||
@@ -164,7 +165,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
[CNC("plus", a="one", b=CC("mult", a="two", b="three"))],
|
||||
exclude_body=True)
|
||||
|
||||
assert concept.get_compiled()["e"][0].body.body == expected_nodes
|
||||
compare_with_test_object(concept.get_compiled()["e"][0].body.body, expected_nodes)
|
||||
|
||||
# # sanity check, I can evaluate the concept
|
||||
# evaluated = sheerka.evaluate_concept(self.get_context(sheerka, eval_body=True), concept)
|
||||
@@ -204,8 +205,8 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_nodes = compute_expected_array(
|
||||
concepts_map,
|
||||
" twenty two",
|
||||
[CNC("twenties", source="twenty two", unit="two")])
|
||||
assert res.body.concept.get_compiled()["b"].get_compiled()["b"][0].body.body == expected_nodes
|
||||
[CNC("twenties", "twenty two", unit="two")])
|
||||
compare_with_test_object(res.body.concept.get_compiled()["b"].get_compiled()["b"][0].body.body, expected_nodes)
|
||||
|
||||
def test_i_can_validate_and_evaluate_a_concept_node_with_python(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -281,7 +282,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert parser_result.source == expression
|
||||
assert len(actual_nodes) == 1
|
||||
assert actual_nodes[0] == scnode(0, 4, expression)
|
||||
compare_with_test_object(actual_nodes[0], SCN(expression, 0, 4))
|
||||
|
||||
def test_i_cannot_parse_unrecognized_python_that_looks_like_concept(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -319,7 +320,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(
|
||||
concepts_map,
|
||||
expression, [CNC("twenties", source=expression, unit="one")])
|
||||
assert actual_nodes == expected_array
|
||||
compare_with_test_object(actual_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_unrecognized_sya_concept_node(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -343,7 +344,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
a="one",
|
||||
b=CC("mult", source="two mult three", a="two", b="three"))],
|
||||
exclude_body=True)
|
||||
assert actual_nodes == expected_array
|
||||
compare_with_test_object(actual_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_unrecognized_source_code_with_concept_node(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -388,8 +389,8 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expression = "hello get_user_name(twenty one)"
|
||||
tmp_node = CNC("hello_sya",
|
||||
source="hello get_user_name(twenty one)",
|
||||
a=SCWC("get_user_name(", ")", CNC("twenties", source="twenty one", unit="one")))
|
||||
"hello get_user_name(twenty one)",
|
||||
a=SCWC("get_user_name(", ")", CNC("twenties", "twenty one", unit="one")))
|
||||
nodes = get_input_nodes_from(concepts_map, expression, tmp_node)
|
||||
parser_input = ParserResultConcept("parsers.xxx", source=expression, value=nodes)
|
||||
|
||||
@@ -404,9 +405,9 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
expected_array = compute_expected_array(
|
||||
concepts_map,
|
||||
expression, [CN("hello_sya", source="hello get_user_name(twenty one)")],
|
||||
expression, [CN("hello_sya", "hello get_user_name(twenty one)")],
|
||||
exclude_body=True)
|
||||
assert actual_nodes == expected_array
|
||||
compare_with_test_object(actual_nodes, expected_array)
|
||||
assert isinstance(actual_nodes[0].concept.get_compiled()["a"], list)
|
||||
assert sheerka.isinstance(actual_nodes[0].concept.get_compiled()["a"][0], BuiltinConcepts.RETURN_VALUE)
|
||||
|
||||
@@ -416,7 +417,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expression = "one plus two three"
|
||||
sequence = get_input_nodes_from(concepts_map, expression,
|
||||
CNC("plus", a="one", b="two"),
|
||||
utnode(5, 6, " three"))
|
||||
UTN(" three", 5, 6))
|
||||
parser_input = ParserResultConcept("parsers.xxx", source="one plus two three", value=sequence)
|
||||
|
||||
res = parser.parse(context, parser_input)
|
||||
@@ -429,7 +430,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expression, [
|
||||
CNC("plus", a="one", b="two"),
|
||||
CN("three", start=6, end=6)])
|
||||
assert actual_nodes == expected_array
|
||||
compare_with_test_object(actual_nodes, expected_array)
|
||||
|
||||
def test_i_can_parse_when_multiple_atom_and_sya(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -445,19 +446,18 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
actual_nodes0 = res[0].body.body
|
||||
expected_0 = compute_expected_array(concepts_map, expression, [
|
||||
CN("two", 0, 0),
|
||||
CN("two", start=0, end=0),
|
||||
CN("hello_atom", source="hello one", start=2, end=4),
|
||||
CN("three", 6, 6)])
|
||||
assert actual_nodes0 == expected_0
|
||||
CN("three", start=6, end=6)])
|
||||
compare_with_test_object(actual_nodes0, expected_0)
|
||||
|
||||
actual_nodes1 = res[1].body.body
|
||||
expected_1 = compute_expected_array(concepts_map, expression, [
|
||||
CN("two", 0, 0),
|
||||
CNC("hello_sya", source="hello one", start=2, end=4, a="one"),
|
||||
CN("three", 6, 6)],
|
||||
CN("two", start=0, end=0),
|
||||
CNC("hello_sya", "hello one", start=2, end=4, a="one"),
|
||||
CN("three", start=6, end=6)],
|
||||
exclude_body=True)
|
||||
|
||||
assert actual_nodes1 == expected_1
|
||||
compare_with_test_object(actual_nodes1, expected_1)
|
||||
|
||||
def test_i_can_parse_when_multiple_sya_concepts(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -474,12 +474,12 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
actual_nodes0 = res[0].body.body
|
||||
expected_0 = compute_expected_array(concepts_map, expression, [
|
||||
CNC("greetings_a", source="greetings two", start=0, end=2, a="two")], exclude_body=True)
|
||||
assert actual_nodes0 == expected_0
|
||||
compare_with_test_object(actual_nodes0, expected_0)
|
||||
|
||||
actual_nodes1 = res[1].body.body
|
||||
expected_1 = compute_expected_array(concepts_map, expression, [
|
||||
CNC("greetings_b", source="greetings two", start=0, end=2, b="two")], exclude_body=True)
|
||||
assert actual_nodes1 == expected_1
|
||||
compare_with_test_object(actual_nodes1, expected_1)
|
||||
|
||||
def test_i_cannot_parse_when_some_unrecognized_remain(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
from core.concept import Concept, ConceptParts, CC
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.global_symbols import NotInit
|
||||
from core.rule import Rule, ACTION_TYPE_EXEC
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from parsers.BaseNodeParser import CNC
|
||||
from parsers.BaseNodeParser import RuleNode
|
||||
from parsers.BnfNodeParser import BnfNodeParser
|
||||
from parsers.FunctionParser import FunctionParser
|
||||
from parsers.SyaNodeParser import SyaNodeParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import get_test_obj
|
||||
from tests.parsers.parsers_utils import get_test_obj, CNC, CC, CN, SCN, SCWC, UTN, RN, CB
|
||||
|
||||
|
||||
class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
@@ -20,12 +23,12 @@ class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
cnode = parser.parse(context, ParserInput("one plus two")).body.body[0]
|
||||
|
||||
# compare all attributes
|
||||
cnc_res = get_test_obj(CNC(concept_key="key", start=0, end=1, source="", exclude_body=False), cnode)
|
||||
cnc_res = get_test_obj(cnode, CNC(concept_key="key", start=0, end=1, source="", exclude_body=False))
|
||||
assert isinstance(cnc_res, CNC)
|
||||
assert cnc_res == CNC("__var__0 plus __var__1", 0, 4, "one plus two", False, **cnode.concept.get_compiled())
|
||||
assert cnc_res == CNC("__var__0 plus __var__1", "one plus two", 0, 4, False, **cnode.concept.get_compiled())
|
||||
|
||||
# I can discard start, end and source
|
||||
cnc_res = get_test_obj(CNC(concept_key="key"), cnode)
|
||||
cnc_res = get_test_obj(cnode, CNC(concept_key="key"))
|
||||
assert isinstance(cnc_res, CNC)
|
||||
assert cnc_res == CNC("__var__0 plus __var__1", None, None, None, False, **cnode.concept.get_compiled())
|
||||
|
||||
@@ -40,12 +43,12 @@ class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
cnode = parser.parse(context, ParserInput("twenty one")).body.body[0]
|
||||
|
||||
# compare all attributes
|
||||
cnc_res = get_test_obj(CNC(concept_key="key", start=0, end=1, source="", exclude_body=False), cnode)
|
||||
cnc_res = get_test_obj(cnode, CNC(concept_key="key", start=0, end=1, source="", exclude_body=False))
|
||||
assert isinstance(cnc_res, CNC)
|
||||
assert cnc_res == CNC("twenties", 0, 2, "twenty one", False, **cnode.concept.get_compiled())
|
||||
assert cnc_res == CNC("twenties", "twenty one", 0, 2, False, **cnode.concept.get_compiled())
|
||||
|
||||
# I can exclude body
|
||||
cnc_res = get_test_obj(CNC(concept_key="key", exclude_body=True), cnode)
|
||||
cnc_res = get_test_obj(cnode, CNC(concept_key="key", exclude_body=True))
|
||||
expected_compiled = {k: v for k, v in cnode.concept.get_compiled().items()}
|
||||
del expected_compiled[ConceptParts.BODY]
|
||||
assert isinstance(cnc_res, CNC)
|
||||
@@ -61,13 +64,13 @@ class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
parser = SyaNodeParser().init_from_concepts(context, [one, two, plus])
|
||||
cnode = parser.parse(context, ParserInput("one plus two")).body.body[0]
|
||||
|
||||
res = get_test_obj([CNC("key1"), CNC("key", 0, 1, "")], [cnode, cnode])
|
||||
res = get_test_obj([cnode, cnode], [CNC("key1"), CNC("key", 0, 1, "")])
|
||||
|
||||
assert len(res) == 2
|
||||
assert isinstance(res[0], CNC)
|
||||
assert res[0] == CNC("__var__0 plus __var__1", None, None, None, False, **cnode.concept.get_compiled())
|
||||
assert isinstance(res[1], CNC)
|
||||
assert res[1] == CNC("__var__0 plus __var__1", 0, 4, "one plus two", False, **cnode.concept.get_compiled())
|
||||
assert res[1] == CNC("__var__0 plus __var__1", "one plus two", 0, 4, False, **cnode.concept.get_compiled())
|
||||
|
||||
def test_i_can_get_test_obj_when_dict(self):
|
||||
sheerka, context, one, two, plus = self.init_concepts(
|
||||
@@ -79,12 +82,12 @@ class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
parser = SyaNodeParser().init_from_concepts(context, [one, two, plus])
|
||||
cnode = parser.parse(context, ParserInput("one plus two")).body.body[0]
|
||||
|
||||
res = get_test_obj({"key1": CNC("key1"), "key2": CNC("key", 0, 1, "")}, {"key1": cnode, "key2": cnode})
|
||||
res = get_test_obj({"key1": cnode, "key2": cnode}, {"key1": CNC("key1"), "key2": CNC("key", 0, 1, "")})
|
||||
assert len(res) == 2
|
||||
assert isinstance(res["key1"], CNC)
|
||||
assert res["key1"] == CNC("__var__0 plus __var__1", None, None, None, False, **cnode.concept.get_compiled())
|
||||
assert isinstance(res["key2"], CNC)
|
||||
assert res["key2"] == CNC("__var__0 plus __var__1", 0, 4, "one plus two", False, **cnode.concept.get_compiled())
|
||||
assert res["key2"] == CNC("__var__0 plus __var__1", "one plus two", 0, 4, False, **cnode.concept.get_compiled())
|
||||
|
||||
def test_i_can_get_test_obj_when_CC(self):
|
||||
sheerka, context, one, two, plus = self.init_concepts(
|
||||
@@ -97,13 +100,115 @@ class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
cc = parser.parse(context, ParserInput("twenty one")).body.body[0].concept
|
||||
|
||||
# compare all attributes
|
||||
cc_res = get_test_obj(CC(concept="key", source="", exclude_body=False), cc)
|
||||
cc_res = get_test_obj(cc, CC(concept="key", source="", exclude_body=False))
|
||||
assert isinstance(cc_res, CC)
|
||||
assert cc_res == CC("twenties", "twenty one", False, **cc.get_compiled())
|
||||
|
||||
# I can exclude body
|
||||
cnc_res = get_test_obj(CC(concept="key", exclude_body=True), cc)
|
||||
cnc_res = get_test_obj(cc, CC(concept="key", exclude_body=True))
|
||||
expected_compiled = {k: v for k, v in cc.get_compiled().items()}
|
||||
del expected_compiled[ConceptParts.BODY]
|
||||
assert isinstance(cnc_res, CC)
|
||||
assert cnc_res == CC("twenties", "twenty one", True, **expected_compiled)
|
||||
|
||||
def test_i_can_get_test_obj_when_CN(self):
|
||||
sheerka, context, one, two, plus = self.init_concepts(
|
||||
"one",
|
||||
"two",
|
||||
Concept("a plus b").def_var("a").def_var("b")
|
||||
)
|
||||
|
||||
parser = SyaNodeParser().init_from_concepts(context, [one, two, plus])
|
||||
cnode = parser.parse(context, ParserInput("one plus two")).body.body[0]
|
||||
|
||||
cn_res = get_test_obj(cnode, CN(concept="key", start=0, end=1, source=""))
|
||||
assert isinstance(cn_res, CN)
|
||||
assert cn_res == CN(plus, "one plus two", 0, 4)
|
||||
|
||||
# I can discard start, end and source
|
||||
cnc_res = get_test_obj(cnode, CN(concept="key"))
|
||||
assert isinstance(cnc_res, CN)
|
||||
assert cnc_res == CN(plus, None, None, None)
|
||||
|
||||
def test_i_can_get_test_obj_when_SCN(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
parser = FunctionParser()
|
||||
scn = parser.parse(context, ParserInput("test()")).body.body
|
||||
|
||||
scn_res = get_test_obj(scn, SCN("", start=0, end=1))
|
||||
assert isinstance(scn_res, SCN)
|
||||
assert scn_res == SCN("test()", 0, 2)
|
||||
|
||||
# I can discard start and end
|
||||
scn_res = get_test_obj(scn, SCN(""))
|
||||
assert isinstance(scn_res, SCN)
|
||||
assert scn_res == SCN("test()", None, None)
|
||||
|
||||
def test_i_can_get_test_obj_when_SCWC(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
parser = FunctionParser()
|
||||
scwc = parser.parse(context, ParserInput("test(param1, test2())")).body.body
|
||||
|
||||
scwc_res = get_test_obj(scwc, SCWC(UTN(""), UTN(""), UTN(""), UTN(""), SCN("", 0, 0)))
|
||||
assert isinstance(scwc_res, SCWC)
|
||||
expected = SCWC(UTN("test(", 0, 1),
|
||||
UTN(")", 8, 8),
|
||||
UTN("param1", 2, 2),
|
||||
UTN(", ", 3, 4),
|
||||
SCN("test2()", 5, 7))
|
||||
expected.start = 0
|
||||
expected.end = 8
|
||||
assert scwc_res == expected
|
||||
|
||||
assert isinstance(scwc_res.first, UTN)
|
||||
assert isinstance(scwc_res.last, UTN)
|
||||
assert isinstance(scwc_res.content[0], UTN)
|
||||
assert isinstance(scwc_res.content[1], UTN)
|
||||
assert isinstance(scwc_res.content[2], SCN)
|
||||
|
||||
def test_i_can_get_test_obj_when_RN(self):
|
||||
rule = Rule(ACTION_TYPE_EXEC, "test_rule", "True", "True")
|
||||
rn = RuleNode(rule, 1, 1, source="r:|xxx:")
|
||||
|
||||
rn_res = get_test_obj(rn, RN("", "", 0, 1))
|
||||
|
||||
assert isinstance(rn_res, RN)
|
||||
assert rn_res == RN(rule, rn.source, rn.start, rn.end)
|
||||
|
||||
# I can discard start and end
|
||||
rn_res = get_test_obj(rn, RN("", None, None, None))
|
||||
assert isinstance(rn_res, RN)
|
||||
assert rn_res == RN(rule, None, None, None)
|
||||
|
||||
def test_i_can_get_test_obj_when_CB(self):
|
||||
a = Concept("a", key="a", body="10").auto_init()
|
||||
b = Concept("b", key="b", body=a).auto_init()
|
||||
c = Concept("c", key="c")
|
||||
other_c = Concept("c", key="c", body="i don't care")
|
||||
|
||||
# i can test when no body
|
||||
res = get_test_obj(c, CB("", ""))
|
||||
assert isinstance(res, CB)
|
||||
assert res == CB("c", NotInit)
|
||||
|
||||
# i can test with a concept instead of a key
|
||||
res = get_test_obj(c, CB(Concept(), ""))
|
||||
assert isinstance(res, CB)
|
||||
assert res == CB(other_c, NotInit) # don't care if it's not the real 'c', only test key and body
|
||||
|
||||
# # i can test when the body is a concept
|
||||
res = get_test_obj(b, CB("", ""))
|
||||
assert isinstance(res, CB)
|
||||
assert res == CB("b", a)
|
||||
|
||||
# i can go into recursion when body is a concept
|
||||
res = get_test_obj(b, CB("", CB("", "")))
|
||||
assert isinstance(res, CB)
|
||||
assert res == CB("b", CB("a", "10"))
|
||||
|
||||
# I can try to go into recursion when there nothing to found
|
||||
res = get_test_obj(c, CB("", CB("", "")))
|
||||
assert isinstance(res, CB)
|
||||
assert res == CB("c", NotInit)
|
||||
|
||||
Reference in New Issue
Block a user