{ "info": { "author": "Dori Reuveni", "author_email": "dorireuv@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Testing" ], "description": "make-it-easy\n============\n\n.. image:: https://pypip.in/v/make-it-easy/badge.png\n :alt: Release Status\n :target: https://crate.io/packages/make-it-easy\n.. image:: https://pypip.in/d/make-it-easy/badge.png\n :alt: Downloads\n :target: https://crate.io/packages/make-it-easy\n.. image:: https://travis-ci.org/dorireuv/make-it-easy.png\n :alt: Build Status\n :target: https://travis-ci.org/dorireuv/make-it-easy\n\nIntroduction\n============\n\nmake-it-easy is a tiny framework that makes it easy to write Test Data Builders in Python.\nThe framework is a port of the `Java make-it-easy by Nat Pryce`_\n\n.. _Java make-it-easy by Nat Pryce: https://code.google.com/p/make-it-easy/\n\nTest Data Builders are described in the book Growing Object-Oriented Software, Guided by Tests by\nSteve Freeman and Nat Pryce. This library lets you write Test Data Builders with much less duplication and\nboilerplate code than the approach described in the book.\n\nInstallation\n============\n\nmake-it-easy can be installed using the usual Python packaging tools. It depends on\ndistribute, but as long as you have a network connection when you install, the\ninstallation process will take care of that for you.\n\nUsage\n=====\n\nBasic\n-----\n\nConsider the following class hierarchy. This hierarchy illustrates a couple of complicating factors: there is\nan abstract base class Fruit and there is a property (ripeness) that is not set via the constructor but by\nan operation of the Fruit class.\n\n.. code:: python\n\n class Fruit(object):\n def __init__(self):\n self._ripeness = 0.0\n \n def ripen(self, ripeness):\n self._ripeness = ripeness\n \n @property\n def is_ripe(self):\n return self._ripeness >= 0.9\n \n \n class Apple(Fruit):\n def __init__(self, num_of_leaves):\n super(Apple, self).__init__()\n self.num_of_leaves = num_of_leaves\n \n \n class Banana(Fruit):\n def __init__(self, curve):\n super(Banana, self).__init__()\n self.curve = curve\n\nDoing so in the style documented in Growing Object-Oriented Software, Guided by Tests would look like this:\n\n.. code:: python\n\n class AppleBuilder(object):\n def __init__(self):\n self._ripeness = 0.5\n self._leaves = 2\n \n def with_ripeness(self, ripeness):\n self._ripeness = ripeness\n return self\n \n def with_leaves(self, leaves):\n self._leaves = leaves\n return self\n\n def but(self):\n return AppleBuilder() \\\n .with_ripeness(self._ripeness) \\\n .with_leaves(self._leaves)\n \n def build(self):\n apple = Apple(self._leaves)\n apple.ripen(self._ripeness)\n return apple\n \n \n class BananaBuilder(object):\n def __init__(self):\n self._ripeness = 0.5\n self._curve = 0.1\n \n def with_ripeness(self, ripeness):\n self._ripeness = ripeness\n \n def with_curve(self, curve):\n self._curve = curve\n \n def but(self):\n return BananaBuilder() \\\n .with_ripeness(self._ripeness) \\\n .with_curve(self._curve)\n \n def build(self):\n banana = Banana()\n banana.ripen(self._ripeness)\n banana.curve = self._curve\n return banana\n\n apple_with_two_leaves = AppleBuilder().with_leaves(2)\n ripe_apple = apple_with_two_leaves.but().with_ripeness(0.95)\n unripe_apple = apple_with_two_leaves.but().with_ripeness(0.1)\n \n apple1 = ripe_apple.build()\n apple2 = unripe_apple.build()\n \n \nWhile doing it with make-it-easy can be easy as that:\n\n.. code:: python\n \n from make_it_easy import *\n \n def apple(leaves=2, ripeness=0.0):\n an_apple = Apple(leaves)\n an_apple.ripen(ripeness)\n return an_apple\n \n \n def banana(curve=0.1, ripeness=0.0):\n a_banana = Banana(curve)\n a_banana.ripen(ripeness)\n return a_banana\n \n apple_with_two_leaves = an(apple, with_(2, 'leaves'))\n ripe_apple = apple_with_two_leaves.but(with_(0.95, 'ripeness'))\n unripe_apple = apple_with_two_leaves.but().with_(0.1, 'ripeness'))\n \n apple1 = make(ripe_apple)\n apple2 = make(unripe_apple)\n\nAs you can see, with Make It Easy you have to write a lot less duplicated and boilerplate code.\n\nValue Donors\n============\n\nPrimitives / Makers\n-------------------\n\nA value donor is any primitive ('Bob' / 3 / False / etc.) or a `Maker` (the returned object from the a, an functions).\nAll these can be used as the value in `with_`. For instance a customer `Maker` can be a donor in order `Maker`. It's\nimportant to notice that if a `Maker` is used as a donor, a new instance will be created every time:\n\n.. code:: python\n\n a_customer = a(customer, with_('Bob', as_('name')))\n an_order = an(order, with_(a_customer, as_('customer')))\n my_order1 = make(an_order)\n my_order2 = make(an_order)\n assert_that(my_order1.customer, is_(instance_of(Customer)))\n assert_that(my_order2.customer, is_(instance_of(Customer)))\n assert_that(my_order1.customer, is_not(same_instance(my_order2.customer))) # two different instances!!!\n\nThe Same Value Donor\n--------------------\n\nSometimes you will need to share the same value while making new data objects, this can be done using `the_same` value\ndonor. In the following example both my_order1 and my_order2 will have the same customer instance:\n\n.. code:: python\n\n a_customer = a(customer, with_('Bob', as_('name')))\n an_order = an(order, with_(the_same(a_customer), as_('customer')))\n my_order1 = make(an_order)\n my_order2 = make(an_order)\n assert_that(my_order1.customer, is_(same_instance(my_order2.customer)))\n\nCustom Donors\n-------------\nIn order to create a custom donor, you will simply need to implement the `Donor` interface.\n\n.. code:: python\n\n class IndexDonor(Donor):\n def __init__(self):\n self._count = itertools.count()\n\n @property\n def value(self):\n return next(self._count)\n\n an_indexed_thing = an(an_indexed_thing, with_(IndexDonor(), as_('index')))\n indexed_thing1 = make(an_indexed_thing)\n indexed_thing2 = make(an_indexed_thing)\n assert_that(indexed_thing1.index, is_(equal_to(0)))\n assert_that(indexed_thing2.index, is_(equal_to(1)))\n\nSequences Donors\n----------------\nSometimes we want values to be allocated from a sequence, so we can predict their values or understand where data\nhas come from in test diagnostics. make-it-easy lets you define a fixed or repeating sequence of values.\n\nA fixed sequence is defined by the `from_` function which expects an iterable:\n\n.. code:: python\n\n letters = from_(\"abc\")\n assert_that(letters.value, is_(equal_to(\"a\")))\n assert_that(letters.value, is_(equal_to(\"b\")))\n assert_that(letters.value, is_(equal_to(\"c\")))\n\nA fixed sequence of values will fail if asked to provide more elements than are specified when the sequence is created.\nA repeating sequence will start back at the beginning of the sequence when all elements are exhausted:\n\n.. code:: python\n\n letters = from_repeating(\"ab\")\n assert_that(letters.value, is_(equal_to(\"a\")))\n assert_that(letters.value, is_(equal_to(\"b\")))\n assert_that(letters.value, is_(equal_to(\"a\")))\n assert_that(letters.value, is_(equal_to(\"b\")))\n assert_that(letters.value, is_(equal_to(\"a\")))\n assert_that(letters.value, is_(equal_to(\"b\")))\n\nBoth fixed and repeating sequences can be created from any iterable (tuple / list / set / dict / etc.).\n\nCalculated Sequences\n--------------------\nIf we do not want to explicitly specify a sequence of values, we can use some convenient base classes to help us\ncalculate each element of the sequence.\nAn `IndexedSequence` calculates each element of the sequence from its integer index, starting at zero.\n\n.. code:: python\n\n class FTagSequence(IndexedSequence):\n def _value_at(self, index):\n return 'f' + \"'\" * index\n\n f_tag_sequence = FTagSequence()\n assert_that(f_tag_sequence.value, is_(equal_to(\"f\")))\n assert_that(f_tag_sequence.value, is_(equal_to(\"f'\")))\n assert_that(f_tag_sequence.value, is_(equal_to(\"f''\")))\n\nA ChainedSequence calculates each element of the sequence from the element that preceded it.\n\n.. code:: python\n\n class FTagChainedSequence(ChainedSequence):\n def _first_value(self):\n return 'f'\n\n def _value_after(self, prev_value):\n return prev_value + \"'\"\n\n f_tag_sequence = FTagChainedSequence()\n assert_that(f_tag_sequence.value, is_(equal_to(\"f\")))\n assert_that(f_tag_sequence.value, is_(equal_to(\"f'\")))\n assert_that(f_tag_sequence.value, is_(equal_to(\"f''\")))", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://www.github.com/dorireuv/make-it-easy", "keywords": "testing,test,tdd,unittest,builder,goos", "license": "Apache License (2.0)", "maintainer": null, "maintainer_email": null, "name": "make-it-easy", "package_url": "https://pypi.org/project/make-it-easy/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/make-it-easy/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://www.github.com/dorireuv/make-it-easy" }, "release_url": "https://pypi.org/project/make-it-easy/1.0.3/", "requires_dist": null, "requires_python": null, "summary": "A tiny framework that makes it easy to write Test Data Builders in Python", "version": "1.0.3" }, "last_serial": 927764, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "cc17fde23c74b402e9066a342f842e2c", "sha256": "5df1d0718c20be7c2b396d764be466361f9850da3900975e9c92655494f029de" }, "downloads": -1, "filename": "make-it-easy-1.0.zip", "has_sig": false, "md5_digest": "cc17fde23c74b402e9066a342f842e2c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12334, "upload_time": "2013-10-21T12:06:18", "url": "https://files.pythonhosted.org/packages/e3/b3/e4be58ee1a7fa146485efe38f17a7219f00913813784bc314d9ef7ee6608/make-it-easy-1.0.zip" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "c6989c95512c297a95699e16135f0dd9", "sha256": "68b25530dd759334e067ce9cb20c1279ef1895d2ceea4e8c4d66d3b76c0a3720" }, "downloads": -1, "filename": "make-it-easy-1.0.1.zip", "has_sig": false, "md5_digest": "c6989c95512c297a95699e16135f0dd9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12393, "upload_time": "2013-11-05T09:43:59", "url": "https://files.pythonhosted.org/packages/35/a4/cc157576997f7eee6bb08c93233a6cb88d6e84888b8f6ed5fea6365c7e86/make-it-easy-1.0.1.zip" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "b723d7bd1d3b8d20a5913f95578c8fff", "sha256": "5feef74fe564558d603f1305c332247384426b71b3c02bf9069f7880f32f5f5f" }, "downloads": -1, "filename": "make-it-easy-1.0.2.zip", "has_sig": false, "md5_digest": "b723d7bd1d3b8d20a5913f95578c8fff", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12400, "upload_time": "2013-11-05T10:25:00", "url": "https://files.pythonhosted.org/packages/d1/ca/2abc2c9bc7d678acc0b7ca3529e8a7603cff6d04b6cfdfc75c3887161146/make-it-easy-1.0.2.zip" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "bc1091c8dcef387739e030f517bfe652", "sha256": "b38776fc959c0289ba7131fa3d9a420561eabeaa1c3091e321a17793b246aa6e" }, "downloads": -1, "filename": "make-it-easy-1.0.3.zip", "has_sig": false, "md5_digest": "bc1091c8dcef387739e030f517bfe652", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12333, "upload_time": "2013-11-24T12:55:21", "url": "https://files.pythonhosted.org/packages/ee/53/c5f8ba745821c45824d182d22a528507f8331da80d05d922078dbeb09960/make-it-easy-1.0.3.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "bc1091c8dcef387739e030f517bfe652", "sha256": "b38776fc959c0289ba7131fa3d9a420561eabeaa1c3091e321a17793b246aa6e" }, "downloads": -1, "filename": "make-it-easy-1.0.3.zip", "has_sig": false, "md5_digest": "bc1091c8dcef387739e030f517bfe652", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12333, "upload_time": "2013-11-24T12:55:21", "url": "https://files.pythonhosted.org/packages/ee/53/c5f8ba745821c45824d182d22a528507f8331da80d05d922078dbeb09960/make-it-easy-1.0.3.zip" } ] }