-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 90749a5
Showing
9 changed files
with
379 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
# Created by .ignore support plugin (hsz.mobi) | ||
### Python template | ||
# Byte-compiled / optimized / DLL files | ||
__pycache__/ | ||
*.py[cod] | ||
*$py.class | ||
|
||
# C extensions | ||
*.so | ||
|
||
# Distribution / packaging | ||
.Python | ||
env/ | ||
build/ | ||
develop-eggs/ | ||
dist/ | ||
downloads/ | ||
eggs/ | ||
.eggs/ | ||
lib/ | ||
lib64/ | ||
parts/ | ||
sdist/ | ||
var/ | ||
wheels/ | ||
*.egg-info/ | ||
.installed.cfg | ||
*.egg | ||
|
||
# PyInstaller | ||
# Usually these files are written by a python script from a template | ||
# before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
*.manifest | ||
*.spec | ||
|
||
# Installer logs | ||
pip-log.txt | ||
pip-delete-this-directory.txt | ||
|
||
# Unit tests / coverage reports | ||
htmlcov/ | ||
.tox/ | ||
.coverage | ||
.coverage.* | ||
.cache | ||
nosetests.xml | ||
coverage.xml | ||
*,cover | ||
.hypothesis/ | ||
coverage/ | ||
|
||
# Translations | ||
*.mo | ||
*.pot | ||
|
||
# Django stuff: | ||
*.log | ||
local_settings.py | ||
|
||
# Flask stuff: | ||
instance/ | ||
.webassets-cache | ||
|
||
# Scrapy stuff: | ||
.scrapy | ||
|
||
# Sphinx documentation | ||
docs/_build/ | ||
|
||
# PyBuilder | ||
target/ | ||
|
||
# Jupyter Notebook | ||
.ipynb_checkpoints | ||
|
||
# pyenv | ||
.python-version | ||
|
||
# celery beat schedule file | ||
celerybeat-schedule | ||
|
||
# SageMath parsed files | ||
*.sage.py | ||
|
||
# dotenv | ||
.env | ||
|
||
# virtualenv | ||
.venv | ||
venv/ | ||
ENV/ | ||
|
||
# Spyder project settings | ||
.spyderproject | ||
|
||
# Rope project settings | ||
.ropeproject | ||
### JetBrains template | ||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm | ||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 | ||
|
||
# User-specific stuff: | ||
.idea/**/workspace.xml | ||
.idea/**/tasks.xml | ||
.idea/dictionaries | ||
|
||
# Sensitive or high-churn files: | ||
.idea/**/dataSources/ | ||
.idea/**/dataSources.ids | ||
.idea/**/dataSources.xml | ||
.idea/**/dataSources.local.xml | ||
.idea/**/sqlDataSources.xml | ||
.idea/**/dynamic.xml | ||
.idea/**/uiDesigner.xml | ||
|
||
# Gradle: | ||
.idea/**/gradle.xml | ||
.idea/**/libraries | ||
|
||
# Mongo Explorer plugin: | ||
.idea/**/mongoSettings.xml | ||
|
||
## File-based project format: | ||
*.iws | ||
|
||
## Plugin-specific files: | ||
|
||
# IntelliJ | ||
/out/ | ||
|
||
# mpeltonen/sbt-idea plugin | ||
.idea_modules/ | ||
|
||
# JIRA plugin | ||
atlassian-ide-plugin.xml | ||
|
||
# Crashlytics plugin (for Android Studio and IntelliJ) | ||
com_crashlytics_export_strings.xml | ||
crashlytics.properties | ||
crashlytics-build.properties | ||
fabric.properties | ||
|
||
## Custom | ||
/.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
ISC License | ||
|
||
Copyright (c) 2017, Paweł Zadrożny @pawelzny <[email protected]> | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted, provided that the above | ||
copyright notice and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
============ | ||
Value Object | ||
============ | ||
|
||
:Info: DDD Value Objects implementation. | ||
:Author: Paweł Zadrożny <[email protected]> | ||
|
||
Installation: | ||
============= | ||
|
||
.. code:: bash | ||
pip install vo | ||
**Package**: https://pypi.python.org/pypi/vo | ||
|
||
|
||
Example | ||
======= | ||
|
||
.. code:: python | ||
from vo.Value import Value | ||
value1 = Value(test=True, some_text="I am some text string") | ||
value2 = Value(some_text="I am some text string", test=True) | ||
assert(value1 == value2) # True | ||
value1.set("extra_attr", "whatever") | ||
assert(value1 == value2) # False | ||
assert("whatever" == value1.get("extra_attr")) # True | ||
assert("default value" == value2.get("extra_attr", "default value")) # True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Get absolute path to this script directory | ||
bin_dir=$(dirname $(readlink -f "$0")) | ||
package_dir=${bin_dir}/../ | ||
coverage_dir=${package_dir}/tests/coverage | ||
|
||
# Run tests with nose test runner | ||
nosetests --where=${package_dir} \ | ||
--with-coverage --cover-erase --cover-branches \ | ||
--cover-html --cover-html-dir=${coverage_dir} \ | ||
--cover-xml --cover-xml-file=${package_dir}/coverage.xml \ | ||
--stop |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from setuptools import setup, find_packages | ||
|
||
|
||
with open('README.rst') as f: | ||
readme = f.read() | ||
|
||
with open('LICENSE') as f: | ||
license = f.read() | ||
|
||
setup(name='vo', | ||
version='0.1.0', | ||
description='DDD Value Objects implementation', | ||
long_description=readme, | ||
keywords='value data object DDD', | ||
author='Pawel Zadrozny @pawelzny', | ||
author_email='[email protected]', | ||
url='https://github.com/pawelzny/vo', | ||
license=license, | ||
test_suite='nose.collector', | ||
tests_require=['nose', 'coverage'], | ||
packages=find_packages(exclude=('tests', 'docs', 'bin')), | ||
zip_safe=False) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import unittest | ||
|
||
from vo.Value import Value | ||
|
||
|
||
class ValueTest(unittest.TestCase): | ||
def test_assign_kwargs(self): | ||
value = Value(test=True, text="Some text") | ||
|
||
self.assertTrue(value.test) | ||
self.assertEqual('Some text', value.text) | ||
|
||
def test_equal(self): | ||
v1 = Value(text="first text", other_attr=1243) | ||
v2 = Value(other_attr=1243, text="first text") | ||
|
||
self.assertEqual(v1, v2) | ||
self.assertEqual(hash(v1), hash(v2)) | ||
|
||
v1.new_attr = True | ||
v2.new_attr = False | ||
|
||
self.assertNotEqual(v1, v2) | ||
self.assertNotEqual(hash(v1), hash(v2)) | ||
|
||
def test_setter(self): | ||
v1 = Value() | ||
v1.set(some_attr="I am some attribute") | ||
self.assertEqual('I am some attribute', v1.get('some_attr')) | ||
|
||
v1.set(some_attr="Now i am different") | ||
self.assertEqual("Now i am different", v1.some_attr) | ||
|
||
def test_getter(self): | ||
v1 = Value() | ||
self.assertEqual("Example string", v1.get('undefined_attr', "Example string")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import hashlib | ||
|
||
|
||
class Value: | ||
""" | ||
Basic implementation of DDD Value Object. These objects | ||
are meant to holds data only without any business logic. | ||
When data has no identifier so it is not an Entity, | ||
there comes Value Objects. | ||
Value Objects are consider same if they holds the same | ||
data even if allocated in different parts of memory. | ||
:Example: | ||
import vo | ||
value1 = vo.Value(name="test value", test=True) | ||
value2 = vo.Value(test=True, name="test value") | ||
assert(value1 == value2) # True | ||
value1.set(extra="extra data") | ||
assert(value1 == value2) # False | ||
""" | ||
|
||
@staticmethod | ||
def to_bytes(string): | ||
""" | ||
Converts string to byte string | ||
:param | ||
string (str): String or number to convert | ||
:return | ||
(str): Byte string | ||
""" | ||
|
||
return bytes(repr(string), 'utf-8') | ||
|
||
def __init__(self, **kwargs): | ||
""" | ||
Dynamically add all kwargs to self dictionary. | ||
:param | ||
kwargs: Key-value pairs | ||
""" | ||
|
||
self.set(**kwargs) | ||
|
||
def __eq__(self, other): | ||
""" | ||
Predicate if checksum of Value Objects are the same. | ||
:param | ||
other: ValueObject | ||
:return | ||
(bool): Boolean | ||
""" | ||
|
||
return self.checksum() == other.checksum() | ||
|
||
def __ne__(self, other): | ||
""" | ||
Predicate if checksum of Value Objects are different. | ||
:param | ||
other: ValueObject | ||
:return | ||
(bool): Boolean | ||
""" | ||
|
||
return self.checksum() != other.checksum() | ||
|
||
def __hash__(self): | ||
""" | ||
Returns hash of checksum | ||
:return | ||
(int): Integer representing object Hash | ||
""" | ||
|
||
return hash(self.checksum()) | ||
|
||
def set(self, **kwargs): | ||
""" | ||
Set additional attributes from kwargs | ||
:param | ||
kwargs: | ||
:return | ||
(self): Returns self to allow method chaining. | ||
""" | ||
|
||
self.__dict__.update(kwargs) | ||
|
||
return self | ||
|
||
def get(self, name, default=None): | ||
""" | ||
Gets attribute value or default if not exists. | ||
:param | ||
name (str): Attribute name | ||
default (any): Default value | ||
:return | ||
(any): Existing attribute value or default | ||
""" | ||
|
||
return getattr(self, name, default) | ||
|
||
def checksum(self): | ||
""" | ||
Computes and returns sha224 string from self dict items. | ||
:return | ||
(str): SHA224 string representing checksum of object values. | ||
""" | ||
|
||
ck_sum = Value.to_bytes('checksum:') | ||
for key, value in sorted(self.__dict__.items()): | ||
ck_sum += Value.to_bytes(str(key) + str(value)) | ||
|
||
return hashlib.sha224(ck_sum).hexdigest() |
Empty file.