Skip to content

Commit

Permalink
Fix importing. Use .xcdatamodeld for coredata
Browse files Browse the repository at this point in the history
  • Loading branch information
ZachGawlik committed Oct 16, 2015
1 parent 815a345 commit 33fe8e8
Show file tree
Hide file tree
Showing 15 changed files with 138 additions and 34 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def read(filename):
name="yak-signals",
packages=find_packages(exclude=["tests*"]),
package_data={'signals': package_data_files},
version="0.2.2",
version="0.2.7",
description="A tool for auto generating libraries for different platforms to communicate with your API",
long_description=long_description,
url="https://github.com/yeti/signals/",
Expand Down
4 changes: 3 additions & 1 deletion signals/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
__author__ = 'rudy'
from signals.main import run_signals

__all__ = ['run_signals']
4 changes: 3 additions & 1 deletion signals/__main__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
import signals.main
signals.main.main()

if __name__ == '__main__':
signals.main.main()
34 changes: 28 additions & 6 deletions signals/generators/ios/core_data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Creates an Xcode Core Data file.
"""
import os
from xml.dom import minidom
from lxml import etree
from signals.parser.fields import Relationship, Field
Expand Down Expand Up @@ -189,22 +190,43 @@ def add_entities(model, objects):


# Parses the given XML's model element and creates our initial root
def get_model(xml):
xml_doc = minidom.parse(xml)
item_list = xml_doc.getElementsByTagName('model')
def get_model(core_data_path):
xml_dom = minidom.parse(core_data_path)
item_list = xml_dom.getElementsByTagName('model')
new_model = etree.Element("model")
current_xml_model = item_list[0]
for att in current_xml_model.attributes.keys():
new_model.set(att, current_xml_model.attributes[att].value)
return new_model


def write_xml_to_file(xml, objects):
model = get_model(xml)
# parses the hidden .xccurrentversion for the name of the current version
# this information is stored inside its first and only <string> xml tag
def get_current_version(xcdatamodeld_path):
xccurrentversion_path = xcdatamodeld_path + '/.xccurrentversion'

# .xccurrentversion might not exist if there is only one version
if os.path.exists(xccurrentversion_path):
xml_dom = minidom.parse(xccurrentversion_path)
return xml_dom.getElementsByTagName('string')[0].childNodes[0].data
else:
return [f for f in os.listdir(xcdatamodeld_path) if f.endswith('.xcdatamodel')][0]


def get_core_data_from_folder(xcdatamodeld_path):
current_version_name = get_current_version(xcdatamodeld_path)
core_data_path = xcdatamodeld_path + '/' + current_version_name + '/contents'
return core_data_path


def write_xml_to_file(xcdatamodeld_path, objects):
core_data_path = get_core_data_from_folder(xcdatamodeld_path)

model = get_model(core_data_path)
add_entities(model, objects)
add_relationships(model, objects)
add_elements(model, objects)

# write tree
tree = etree.ElementTree(model)
tree.write(xml, pretty_print=True)
tree.write(core_data_path, pretty_print=True)
5 changes: 3 additions & 2 deletions signals/generators/ios/ios_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@


class iOSGenerator(BaseGenerator):
def __init__(self, schema, data_models_path, core_data_path, project_name):
def __init__(self, schema, data_models_path, core_data_path, check_xcode, project_name):
super(iOSGenerator, self).__init__(schema)
# Command flags
self.data_models_path = data_models_path
self.core_data_path = core_data_path
self.check_xcode = check_xcode
self.project_name = project_name

# Setup
Expand All @@ -34,7 +35,7 @@ def __init__(self, schema, data_models_path, core_data_path, project_name):

def process(self):
if self.core_data_path is not None:
if self.is_xcode_running():
if self.check_xcode and self.is_xcode_running():
raise SignalsError("Must quit Xcode before writing to core data")
progress("Creating core data file")
write_xml_to_file(self.core_data_path, self.schema.data_objects)
Expand Down
2 changes: 1 addition & 1 deletion signals/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ def recursively_find_parent_containing_file(current_path, search_files):

current_path = os.path.normpath(os.path.join(current_path, ".."))

return None
return None, None
24 changes: 13 additions & 11 deletions signals/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

# Create a separate function so that we can unit test.
# Issues unit testing `main` due to click decorators.
def run_main(schema, generator_name, data_models, core_data, project_name, save):
def run_signals(schema, generator_name, data_models, core_data, check_xcode, project_name, save):

schema = Schema(schema)

generator = generators[generator_name](schema, data_models, core_data, project_name)
generator = generators[generator_name](schema, data_models, core_data, check_xcode, project_name)
try:
generator.process()
if save:
Expand All @@ -40,12 +40,13 @@ def project_specified(ctx, param, value):
except SignalsError as e:
print(str(e))
else:
run_main(setting_dict["schema"],
setting_dict["generator"],
setting_dict["data_models"],
setting_dict["core_data"],
setting_dict["project_name"],
False)
run_signals(setting_dict["schema"],
setting_dict["generator"],
setting_dict["data_models"],
setting_dict["core_data"],
True,
setting_dict["project_name"],
False)

if ctx is not None:
ctx.exit()
Expand All @@ -59,6 +60,7 @@ def add_trailing_slash_to_api(ctx, param, value):


def validate_path(ctx, param, value):
value = value.strip()
if value.startswith('~'):
value = os.path.expanduser(value)
elif value.startswith('.'):
Expand Down Expand Up @@ -93,8 +95,8 @@ def validate_path(ctx, param, value):
type=click.Path(dir_okay=True),
callback=validate_path)
@click.option('core_data', '--coredata',
help='The location of your core data configuration xcdatamodel file.',
type=click.Path(exists=True))
help='The location of your core data .xcdatamodeld file.',
type=click.Path(dir_okay=True))
@click.option('project_name', '--projectname',
prompt="name of your iOS project and main target",
help='The name of your iOS project and main target.',
Expand All @@ -103,4 +105,4 @@ def validate_path(ctx, param, value):
# TODO: These are iOS specific settings and we'll need to figure out a way to handle generator specific arguments
# when we add more generators in the future.
def main(settings_path, schema, generator, data_models, core_data, project_name, save):
run_main(schema, generator, data_models, core_data, project_name, save)
run_signals(schema, generator, data_models, core_data, True, project_name, save)
8 changes: 8 additions & 0 deletions tests/files/doubledummy.xcdatamodeld/.xccurrentversion
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>dummy 2.xcdatamodel</string>
</dict>
</plist>
File renamed without changes.
24 changes: 24 additions & 0 deletions tests/files/doubledummy.xcdatamodeld/dummy.xcdatamodel/contents
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<model userDefinedModelVersionIdentifier="" macOSVersion="Automatic" minimumToolsVersion="Xcode 4.3" documentVersion="1.0" lastSavedToolsVersion="7549" systemVersion="14D136" type="com.apple.IDECoreDataModeler.DataModel" iOSVersion="Automatic">
<entity name="LoginResponse" representedClassName="LoginResponse">
<attribute name="clientSecret" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="clientId" optional="NO" attributeType="String" syncable="YES"/>
</entity>
<entity name="SignUpRequest" representedClassName="SignUpRequest">
<attribute name="username" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="fullname" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="password" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="email" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<entity name="SignUpResponse" representedClassName="SignUpResponse">
<attribute name="username" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="clientSecret" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="fullname" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="email" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="clientId" optional="NO" attributeType="String" syncable="YES"/>
</entity>
<elements>
<element name="LoginResponse" positionX="0" positionY="0" width="128" height="600"/>
<element name="SignUpResponse" positionX="0" positionY="0" width="128" height="600"/>
<element name="SignUpRequest" positionX="0" positionY="0" width="128" height="600"/>
</elements>
</model>
24 changes: 24 additions & 0 deletions tests/files/dummy.xcdatamodeld/dummy.xcdatamodel/contents
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<model userDefinedModelVersionIdentifier="" macOSVersion="Automatic" minimumToolsVersion="Xcode 4.3" documentVersion="1.0" lastSavedToolsVersion="7549" systemVersion="14D136" type="com.apple.IDECoreDataModeler.DataModel" iOSVersion="Automatic">
<entity name="LoginResponse" representedClassName="LoginResponse">
<attribute name="clientSecret" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="clientId" optional="NO" attributeType="String" syncable="YES"/>
</entity>
<entity name="SignUpRequest" representedClassName="SignUpRequest">
<attribute name="username" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="fullname" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="password" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="email" optional="YES" attributeType="String" syncable="YES"/>
</entity>
<entity name="SignUpResponse" representedClassName="SignUpResponse">
<attribute name="username" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="clientSecret" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="fullname" optional="NO" attributeType="String" syncable="YES"/>
<attribute name="email" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="clientId" optional="NO" attributeType="String" syncable="YES"/>
</entity>
<elements>
<element name="LoginResponse" positionX="0" positionY="0" width="128" height="600"/>
<element name="SignUpResponse" positionX="0" positionY="0" width="128" height="600"/>
<element name="SignUpRequest" positionX="0" positionY="0" width="128" height="600"/>
</elements>
</model>
19 changes: 19 additions & 0 deletions tests/generators/ios/test_core_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import unittest
from signals.generators.ios.core_data import get_current_version, get_core_data_from_folder


class CoreDataTestCase(unittest.TestCase):
def test_get_current_version(self):
version_name = get_current_version('./tests/files/doubledummy.xcdatamodeld')
self.assertEqual(version_name, 'dummy 2.xcdatamodel')
version_name = get_current_version('./tests/files/dummy.xcdatamodeld')
self.assertEqual(version_name, 'dummy.xcdatamodel')

def test_get_core_data_from_folder(self):
xcdatamodeld_path = './tests/files/doubledummy.xcdatamodeld'
contents_path = xcdatamodeld_path + '/dummy 2.xcdatamodel/contents'
self.assertEqual(get_core_data_from_folder(xcdatamodeld_path), contents_path)

xcdatamodeld_path = './tests/files/dummy.xcdatamodeld'
contents_path = xcdatamodeld_path + '/dummy.xcdatamodel/contents'
self.assertEqual(get_core_data_from_folder(xcdatamodeld_path), contents_path)
6 changes: 3 additions & 3 deletions tests/generators/ios/test_ios_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@ def test_is_xcode_running(self, mock_subprocess):
@mock.patch("signals.generators.ios.ios_generator.subprocess")
def test_process_error(self, mock_subprocess):
mock_subprocess.check_output.return_value = "Xcode.app"
generator = iOSGenerator(Schema("./tests/files/test_schema.json"), "./tests/files/", "./core/data/path",
generator = iOSGenerator(Schema("./tests/files/test_schema.json"), "./tests/files/", "./core/data/path", True,
"YetiProject")
with self.assertRaises(SignalsError) as e:
generator.process()
self.assertEqual(e.exception.msg, "Must quit Xcode before writing to core data")

@mock.patch("signals.generators.ios.ios_generator.recursively_find_parent_containing_file", side_effect=good_app_delegate)
def test_check_setup_called_success(self, mock_function):
generator = iOSGenerator(Schema("./tests/files/test_schema.json"), "./tests/files/", "./core/data/path",
generator = iOSGenerator(Schema("./tests/files/test_schema.json"), "./tests/files/", "./core/data/path", True,
"YetiProject")
self.assertTrue(generator.check_setup_called())

@mock.patch("signals.generators.ios.ios_generator.recursively_find_parent_containing_file", side_effect=bad_app_delegate)
def test_check_setup_called_failure(self, mock_function):
generator = iOSGenerator(Schema("./tests/files/test_schema.json"), "./tests/files/", "./core/data/path",
generator = iOSGenerator(Schema("./tests/files/test_schema.json"), "./tests/files/", "./core/data/path", False,
"YetiProject")
self.assertFalse(generator.check_setup_called())

Expand Down
10 changes: 5 additions & 5 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import mock
import unittest
import subprocess
from signals.main import run_main, add_trailing_slash_to_api, validate_path
from signals.main import run_signals, add_trailing_slash_to_api, validate_path
from signals.generators.base.base_generator import BaseGenerator
from tests.utils import captured_stderr, captured_stdout

Expand All @@ -17,17 +17,17 @@ def test_run_command(self):
self.assertEqual(error, "")
self.assertIn("Finished generating your files!", output)

def test_run_main(self):
def test_run_signals(self):
with captured_stderr() as error, captured_stdout() as out:
run_main("./tests/files/test_schema.json", "ios", "./tests/files/", None, "YetiProject", False)
run_signals("./tests/files/test_schema.json", "ios", "./tests/files/", None, False, "YetiProject", False)
self.assertEqual(error.getvalue(), "")
self.assertIn("Finished generating your files!", out.getvalue())

@mock.patch("signals.generators.ios.ios_generator.subprocess")
def test_run_main_error(self, mock_subprocess):
def test_run_signals_error(self, mock_subprocess):
mock_subprocess.check_output.return_value = "Xcode.app"
with captured_stdout() as out:
run_main("./tests/files/test_schema.json", "ios", "./tests/files/", "./core/data/path", "YetiProject",
run_signals("./tests/files/test_schema.json", "ios", "./tests/files/", "./core/data/path", True, "YetiProject",
False)
self.assertIn("Must quit Xcode before writing to core data", out.getvalue())

Expand Down
6 changes: 3 additions & 3 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mock
import unittest
import subprocess
from signals.main import run_main, project_specified
from signals.main import run_signals, project_specified
from tests.utils import captured_stderr, captured_stdout


Expand All @@ -13,8 +13,8 @@ def test_run_command(self, mock_subprocess):

# Run normally to generate settings file
with captured_stderr() as error, captured_stdout() as out:
run_main("./tests/files/test_schema.json", "ios", "./tests/files/", "./tests/files/dummycontents",
"YetiProject", True)
run_signals("./tests/files/test_schema.json", "ios", "./tests/files/",
"./tests/files/doubledummy.xcdatamodeld", True, "YetiProject", True)
self.assertEqual(error.getvalue(), "")
self.assertIn("Finished generating your files!", out.getvalue())

Expand Down

0 comments on commit 33fe8e8

Please sign in to comment.