Added basic implementation for Python code evaluation
This commit is contained in:
+38
-38
@@ -167,44 +167,44 @@ def test_i_can_recognize_keywords(text, expected):
|
||||
assert tokens[0].value == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("1", n(1)),
|
||||
("+1", n(1)),
|
||||
("-1", n(-1)),
|
||||
("'foo'", s("foo")),
|
||||
("identifier", v("identifier")),
|
||||
("true", t()),
|
||||
("false", f()),
|
||||
("null", null()),
|
||||
("1 * 2", b(TokenKind.STAR, n(1), n(2))),
|
||||
("1 * 2/3", b(TokenKind.STAR, n(1), b(TokenKind.SLASH, n(2), n(3)))),
|
||||
("1 + 2", b(TokenKind.PLUS, n(1), n(2))),
|
||||
("1 + 2 - 3", b(TokenKind.PLUS, n(1), b(TokenKind.MINUS, n(2), n(3)))),
|
||||
("1 + 2-3", b(TokenKind.PLUS, n(1), b(TokenKind.PLUS, n(2), n(-3)))),
|
||||
("1 + 2 +-3", b(TokenKind.PLUS, n(1), b(TokenKind.PLUS, n(2), n(-3)))),
|
||||
("1 + 2 * 3", b(TokenKind.PLUS, n(1), b(TokenKind.STAR, n(2), n(3)))),
|
||||
("1 * 2 + 3", b(TokenKind.PLUS, b(TokenKind.STAR, n(1), n(2)), n(3))),
|
||||
("(1 + 2) * 3", b(TokenKind.STAR, b(TokenKind.PLUS, n(1), n(2)), n(3))),
|
||||
("1 * (2 + 3)", b(TokenKind.STAR, n(1), b(TokenKind.PLUS, n(2), n(3)))),
|
||||
])
|
||||
def test_i_can_parse_simple_expression(text, expected):
|
||||
parser = DefaultParser(text, None)
|
||||
ast = parser.parse()
|
||||
assert ast.is_same(expected)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, token_found, expected_tokens", [
|
||||
("1+", TokenKind.EOF,
|
||||
[TokenKind.NUMBER, TokenKind.STRING, TokenKind.IDENTIFIER, 'true', 'false', 'null', TokenKind.LPAR]),
|
||||
("(1+1", TokenKind.EOF, [TokenKind.RPAR])
|
||||
])
|
||||
def test_i_can_detect_unexpected_end_of_code(text, token_found, expected_tokens):
|
||||
parser = DefaultParser(text, None)
|
||||
parser.parse()
|
||||
|
||||
assert parser.has_error
|
||||
assert parser.error_sink[0].tokens[0].type == token_found
|
||||
assert parser.error_sink[0].expected_tokens == expected_tokens
|
||||
# @pytest.mark.parametrize("text, expected", [
|
||||
# ("1", n(1)),
|
||||
# ("+1", n(1)),
|
||||
# ("-1", n(-1)),
|
||||
# ("'foo'", s("foo")),
|
||||
# ("identifier", v("identifier")),
|
||||
# ("true", t()),
|
||||
# ("false", f()),
|
||||
# ("null", null()),
|
||||
# ("1 * 2", b(TokenKind.STAR, n(1), n(2))),
|
||||
# ("1 * 2/3", b(TokenKind.STAR, n(1), b(TokenKind.SLASH, n(2), n(3)))),
|
||||
# ("1 + 2", b(TokenKind.PLUS, n(1), n(2))),
|
||||
# ("1 + 2 - 3", b(TokenKind.PLUS, n(1), b(TokenKind.MINUS, n(2), n(3)))),
|
||||
# ("1 + 2-3", b(TokenKind.PLUS, n(1), b(TokenKind.PLUS, n(2), n(-3)))),
|
||||
# ("1 + 2 +-3", b(TokenKind.PLUS, n(1), b(TokenKind.PLUS, n(2), n(-3)))),
|
||||
# ("1 + 2 * 3", b(TokenKind.PLUS, n(1), b(TokenKind.STAR, n(2), n(3)))),
|
||||
# ("1 * 2 + 3", b(TokenKind.PLUS, b(TokenKind.STAR, n(1), n(2)), n(3))),
|
||||
# ("(1 + 2) * 3", b(TokenKind.STAR, b(TokenKind.PLUS, n(1), n(2)), n(3))),
|
||||
# ("1 * (2 + 3)", b(TokenKind.STAR, n(1), b(TokenKind.PLUS, n(2), n(3)))),
|
||||
# ])
|
||||
# def test_i_can_parse_simple_expression(text, expected):
|
||||
# parser = DefaultParser(text, None)
|
||||
# ast = parser.parse()
|
||||
# assert ast.is_same(expected)
|
||||
#
|
||||
#
|
||||
# @pytest.mark.parametrize("text, token_found, expected_tokens", [
|
||||
# ("1+", TokenKind.EOF,
|
||||
# [TokenKind.NUMBER, TokenKind.STRING, TokenKind.IDENTIFIER, 'true', 'false', 'null', TokenKind.LPAR]),
|
||||
# ("(1+1", TokenKind.EOF, [TokenKind.RPAR])
|
||||
# ])
|
||||
# def test_i_can_detect_unexpected_end_of_code(text, token_found, expected_tokens):
|
||||
# parser = DefaultParser(text, None)
|
||||
# parser.parse()
|
||||
#
|
||||
# assert parser.has_error
|
||||
# assert parser.error_sink[0].tokens[0].type == token_found
|
||||
# assert parser.error_sink[0].expected_tokens == expected_tokens
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected_name, expected_expr", [
|
||||
|
||||
+51
-20
@@ -5,10 +5,11 @@ import os
|
||||
from os import path
|
||||
import shutil
|
||||
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.concept import Concept, ConceptParts, ReturnValueConcept
|
||||
from core.sheerka import Sheerka, ExecutionContext
|
||||
from parsers.DefaultParser import DefConceptNode, DefaultParser
|
||||
from parsers.PythonParser import PythonParser
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider
|
||||
|
||||
tests_root = path.abspath("../build/tests")
|
||||
root_folder = "init_folder"
|
||||
@@ -36,23 +37,11 @@ def test_root_folder_is_created_after_initialization():
|
||||
|
||||
|
||||
def test_lists_of_concepts_is_initialized():
|
||||
Sheerka().initialize(root_folder)
|
||||
assert len(Sheerka().concepts_cache) > 1
|
||||
sheerka = Sheerka()
|
||||
sheerka.initialize(root_folder)
|
||||
assert len(sheerka.concepts_cache) > 1
|
||||
|
||||
|
||||
# def test_null_concept_are_equals():
|
||||
# concept1 = Concept("test1")
|
||||
# concept2 = Concept("test2")
|
||||
# concept3 = Concept("test3")
|
||||
#
|
||||
# assert not Sheerka.concept_equals(concept1, None)
|
||||
# assert not Sheerka.concept_equals(None, concept1)
|
||||
# assert not Sheerka.concept_equals(concept1, concept2)
|
||||
# assert not Sheerka.concept_equals(concept1, concept3)
|
||||
#
|
||||
# assert Sheerka.concept_equals(None, None)
|
||||
# assert Sheerka.concept_equals(concept1, concept1)
|
||||
|
||||
def get_concept():
|
||||
text = """
|
||||
def concept a+b
|
||||
@@ -72,7 +61,7 @@ def test_i_can_add_a_concept():
|
||||
concept = get_concept()
|
||||
sheerka = Sheerka()
|
||||
sheerka.initialize(root_folder)
|
||||
res = sheerka.add_concept(ExecutionContext("xxx"), concept)
|
||||
res = sheerka.add_concept(ExecutionContext(sheerka, "xxx"), concept)
|
||||
concept_found = res.value
|
||||
|
||||
assert res.status
|
||||
@@ -93,6 +82,48 @@ def test_i_can_add_a_concept():
|
||||
assert concept_found.key == "__var__0 + __var__1"
|
||||
assert concept_found.id == "1001"
|
||||
|
||||
# def test_i_cannot_add_the_same_concept_twice():
|
||||
# concept1 = DefConceptNode(name="concept")
|
||||
# sheerka = Sheerka
|
||||
assert path.exists(sheerka.sdp.get_obj_path(SheerkaDataProvider.ObjectsFolder,
|
||||
"4f249487410db35d8bcbcf4521acb3dd8354978804cd99bbc4de17a323b2f237"))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("1 + 1", 2),
|
||||
("sheerka.test()", 'I have access to Sheerka !')
|
||||
])
|
||||
def test_i_can_eval_simple_python_expressions(text, expected):
|
||||
sheerka = Sheerka(debug=True)
|
||||
sheerka.initialize(root_folder)
|
||||
|
||||
res = sheerka.eval(text)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].value.body == expected
|
||||
assert sheerka.isinstance(res[0].value, ReturnValueConcept())
|
||||
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice():
|
||||
"""
|
||||
Checks that duplicated concepts are managed by sheerka, not by sheerka.sdp
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def test_i_can_get_a_concept():
|
||||
"""
|
||||
Checks that a concept can be found its name
|
||||
even when there are variables in the name (ex 'hello + a' or 'a + b' )
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def test_i_can_instanciate_a_concept():
|
||||
"""
|
||||
Test the new() functionnality
|
||||
make sure that some Concept are singleton (ex Sheerka, True, False)
|
||||
but some other need a new instance everytime
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -10,6 +10,7 @@ import shutil
|
||||
import json
|
||||
|
||||
from sdp.sheerkaSerializer import ObjectSerializer, BaseSerializer, Serializer, SerializerContext, PickleSerializer
|
||||
import core.utils
|
||||
|
||||
tests_root = path.abspath("../build/tests")
|
||||
evt_digest = "3a571cb6034ef6fc8d7fe91948d0d29728eed74de02bac7968b0e9facca2c2d7"
|
||||
@@ -637,7 +638,7 @@ def test_i_can_add_unique():
|
||||
def test_i_can_add_reference_of_an_object_with_a_key():
|
||||
sdp = SheerkaDataProvider(".sheerka")
|
||||
obj = ObjDumpJson("my_key", "value1")
|
||||
obj_serializer = ObjectSerializer(BaseSerializer.get_full_qualified_name(obj))
|
||||
obj_serializer = ObjectSerializer(core.utils.get_full_qualified_name(obj))
|
||||
sdp.serializer.register(obj_serializer)
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj, use_ref=True)
|
||||
@@ -1102,7 +1103,7 @@ def test_i_can_get_an_entry_by_key():
|
||||
def test_i_can_get_object_save_by_reference():
|
||||
sdp = SheerkaDataProvider(".sheerka")
|
||||
obj = ObjDumpJson("my_key", "value1")
|
||||
sdp.serializer.register(ObjectSerializer(BaseSerializer.get_full_qualified_name(obj)))
|
||||
sdp.serializer.register(ObjectSerializer(core.utils.get_full_qualified_name(obj)))
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj, use_ref=True)
|
||||
loaded = sdp.get(entry, key)
|
||||
@@ -1208,7 +1209,7 @@ def test_i_can_test_than_an_entry_exits():
|
||||
def test_i_can_save_and_load_object_ref_with_history():
|
||||
sdp = SheerkaDataProvider(".sheerka")
|
||||
obj = ObjDumpJson("my_key", "value1")
|
||||
sdp.serializer.register(ObjectSerializer(BaseSerializer.get_full_qualified_name(obj)))
|
||||
sdp.serializer.register(ObjectSerializer(core.utils.get_full_qualified_name(obj)))
|
||||
|
||||
entry, key = sdp.add(evt_digest, "entry", obj, use_ref=True)
|
||||
loaded = sdp.get(entry, key)
|
||||
|
||||
@@ -4,6 +4,7 @@ from dataclasses import dataclass
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
from sdp.sheerkaSerializer import Serializer, ObjectSerializer, SerializerContext, BaseSerializer
|
||||
from datetime import datetime
|
||||
import core.utils
|
||||
|
||||
|
||||
@dataclass()
|
||||
@@ -53,4 +54,4 @@ def test_i_can_serialize_an_object():
|
||||
(Obj("10", "value"), "tests.test_sheerkaSerializer.Obj")
|
||||
])
|
||||
def test_get_full_qualified_name(obj, expected):
|
||||
assert expected == BaseSerializer.get_full_qualified_name(obj)
|
||||
assert expected == core.utils.get_full_qualified_name(obj)
|
||||
|
||||
Reference in New Issue
Block a user