Skip to content

Commit

Permalink
snipper_provider (#4)
Browse files Browse the repository at this point in the history
* add class initialization skeleton

* moved mock data to test files

* Use patch instead of changing snippetProvider object

* Moved snippet provider instance to snippet provider module

* Implemented initialize method

* Fixes from manual testing

* Added docstrings and refactored a bit

* Implemented most of the tests for snippet provider

* Finished initialization test implementation

* Added os.path.join use to ensure multiple platform support
  • Loading branch information
Ahhhhmed committed Mar 25, 2018
1 parent 8ad569c commit 3f7c795
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 11 deletions.
38 changes: 33 additions & 5 deletions homotopy/snippet_provider.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
import os
import json
import logging


class SnippetProvider:
"""
Class for translating simple snippets into code.
Uses a database provided in json files located in path variable.
"""

data = {
"for": "for # in !:\n\tpass"
}
def __init__(self, language="", path=[]):
"""
Initialize snippet provider instance.
:param language: language to compile to
:param path: list of directories to search for json files containing snippets
"""
self.data = {}
self.language = language
self.path = path
for item in self.path:
for file in filter(lambda x: x.endswith(".json"), os.listdir(item)):
try:
for snippet in filter(lambda x: x["language"].lower() == self.language.lower(), json.load(open(os.path.join(item, file)))):
if snippet["name"] in self.data:
logging.warning("Multiple definition for %s" % snippet["name"])
else:
self.data[snippet["name"]] = snippet["snippet"]
except (ValueError, OSError):
logging.warning("Could not get data from file %s" % file, exc_info=True)

def __getitem__(self, item):
if item in SnippetProvider.data:
return SnippetProvider.data[item]
"""
Expand single snippet
:param item: snippet
:return: snippet expansion
"""
if item in self.data:
return self.data[item]
return item


snippetProvider = SnippetProvider()
4 changes: 1 addition & 3 deletions homotopy/syntax_tree.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from homotopy.snippet_provider import SnippetProvider

snippetProvider = SnippetProvider()
from homotopy.snippet_provider import snippetProvider


class Snippet:
Expand Down
52 changes: 51 additions & 1 deletion test/testSnippet_provider.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,61 @@
from unittest import TestCase
from unittest.mock import patch, MagicMock
from unittest.mock import mock_open

import os

import homotopy.snippet_provider as sp


class TestSnippetProvider(TestCase):
def test_basic(self):
def test_getitem(self):
provider = sp.SnippetProvider()

provider.data = {
"for": "for # in !:\n\tpass"
}

self.assertEqual(provider['for'], "for # in !:\n\tpass")
self.assertEqual(provider['i==5'], "i==5")

@patch('os.listdir')
def test_initialization(self, listdir):
listdir.return_value = ['test.json', 'test.txt']

self.assertDictEqual(sp.SnippetProvider().data, {}, "Snippet provider should be empty.")

with patch('builtins.open', mock_open(read_data='[{"name": "for","language": "C++","snippet": "if(#){$}"}]')) as m:
provider = sp.SnippetProvider("c++", ["test"])

self.assertEqual("if(#){$}", provider["for"])

m.assert_called_once_with(os.path.join("test", "test.json"))

listdir.assert_called_once_with("test")

with patch('builtins.open', mock_open(read_data='[{"name": "for","language": "C++","snippet": "if(#){$}"}]')) as m:
provider = sp.SnippetProvider("java", ["test"])

self.assertEqual("for", provider["for"])

with patch('logging.warning', MagicMock()) as m:
with patch('builtins.open', mock_open()) as m_open:
m_open.side_effect = IOError()

provider = sp.SnippetProvider("c++", ["test"])

m.assert_called_once_with("Could not get data from file test.json", exc_info=True)

with patch('logging.warning', MagicMock()) as m:
with patch('builtins.open', mock_open(read_data='invalidJSON')) as m_open:
provider = sp.SnippetProvider("c++", ["test"])

m.assert_called_once_with("Could not get data from file test.json", exc_info=True)

with patch('logging.warning', MagicMock()) as m:
with patch('builtins.open', mock_open(
read_data='[{"name": "for","language": "C++","snippet": "if(#){$}"}'
',{"name": "for","language": "C++","snippet": "if(#){$}"}]')) as m_open:
provider = sp.SnippetProvider("c++", ["test"])

m.assert_called_once_with("Multiple definition for for")
7 changes: 5 additions & 2 deletions test/testSyntax_tree.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from unittest import TestCase
from unittest.mock import patch

import homotopy.syntax_tree as st

Expand All @@ -21,10 +22,12 @@ def test_eq(self):

self.assertFalse(st.SimpleSnippet('if') != st.SimpleSnippet('if'))


def test_compile(self):
@patch('homotopy.snippet_provider.SnippetProvider.__getitem__')
def test_compile(self, mockProvider):
self.assertIsNone(st.Snippet().compile())

mockProvider.side_effect = lambda x: x if x != "for" else "for # in !:\n\tpass"

self.assertEqual(
st.CompositeSnippet(
st.CompositeSnippet(st.SimpleSnippet('for'), '#', st.SimpleSnippet('i')),
Expand Down

0 comments on commit 3f7c795

Please sign in to comment.