Added basic implementation for Python code evaluation

This commit is contained in:
2019-11-07 17:18:07 +01:00
parent b818c992ec
commit 448ebc696a
18 changed files with 501 additions and 156 deletions
+38 -38
View File
@@ -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
View File
@@ -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
+4 -3
View File
@@ -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)
+2 -1
View File
@@ -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)