{ "info": { "author": "Shachar Nudler", "author_email": "snudler6@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Testing" ], "description": ".. image:: https://travis-ci.org/snudler6/time-travel.svg?branch=master\n :target: https://travis-ci.org/snudler6/time-travel\n\n.. image:: https://ci.appveyor.com/api/projects/status/y13ewnvmj0muoapf/branch/master?svg=true\n :target: https://ci.appveyor.com/project/snudler6/time-travel/branch/master\n\n.. image:: https://readthedocs.org/projects/time-travel/badge/?version=latest\n :target: http://time-travel.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/pypi/pyversions/time-travel.svg\n :target: https://pypi.org/project/time-travel\n\ntime-travel - time and I/O mocking library\n==========================================\n\n**time-travel** is a python library that helps users write deterministic\ntests for time sensitive and I/O intensive code.\n\n**time-travel** supports python 2.7, 3.4, 3.5, 3.6 and pypy2 on both Linux\nand Windows.\n\nInstall\n-------\n\n.. code:: bash\n\n $ pip install time_travel\n\nTesting Time Sensitive Code\n---------------------------\n\nImagine testing a state machine that times out after some time passes.\nOne way to test it would be:\n\n.. code-block:: python\n\n def test_state_timeout():\n sm.handle_event(event=...)\n time.sleep(5)\n sm.handle_event(event=...)\n assert sm.state == TIMEOUT\n\nThis is bad for several reasons:\n\n* **Your test takes 5 seconds to run**. That's a no-no.\n* ``time.sleep()`` promises that the process will sleep ``x`` seconds\n **at most**. This test might fail randomly, depending on how sensitive your\n state machine is.\n\nThere's nothing worse than a heisenbuild (well, perhaps a **SLOW** heisenbuild).\nHere's a **better** way to do this using ``time-travel``:\n\n.. code-block:: python\n\n def test_state_timeout():\n with TimeTravel() as tt:\n sm.handle_event(event=...)\n tt.clock.time += 5\n sm.handle_event(event=...)\n assert sm.state == TIMEOUT\n\nWhen the ``handle_event`` method is called it will probably check the time\nusing one of ``time`` or ``datetime`` modules. These modules are patched by\n``time-travel`` and return the value stored in ``TimeTravel.clock.time``.\n\nFrom now on, your time sensitive tests will run faster, accurately, and your\nbuild will be consistent.\n\nTesting I/O Code\n----------------\n\n``time-travel`` also mocks I/O event interfaces such as ``select`` and ``poll``.\n\nTesting code that uses ``select`` is easy - you just inject a real socket object\nand send data to it from your test code. But what about timeouts? Testing\nbehaviour that occurs on timeout forces you to actually **wait**! That's bananas!\n\nHere's how you'd do it with ``time-travel``:\n\n.. code-block:: python\n\n def test_select_timeout():\n with TimeTravel() as tt:\n sock = socket.socket()\n tt.add_future_event(2, sock, tt.event_types.select.WRITE)\n start = time.time()\n assert select.select([sock], [sock], []) == ([], [sock], []) # This will be satisfied after \"2 seconds\"\n assert time.time() == start + 2 # You see? 2 seconds!\n assert select.select([sock], [sock], [], 100) == ([], [], []) # This is the \"timeout\"\n assert time.time() == start + 2 + 100\n\nOnce again, this code will run instantly.\n\nOh yes, ``sock`` doesn't even have to be a socket object :)\n\n\nFor detailed information and usage examples, see the\n`full documentation `_. You know\nyou want to.\n\nLinks\n=====\n\n`Full documentation `_\n\n`PyPI project page `_\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/snudler6/time-travel", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "time_travel", "package_url": "https://pypi.org/project/time_travel/", "platform": "", "project_url": "https://pypi.org/project/time_travel/", "project_urls": { "Homepage": "https://github.com/snudler6/time-travel" }, "release_url": "https://pypi.org/project/time_travel/1.1.2/", "requires_dist": null, "requires_python": "", "summary": "Python time mocking", "version": "1.1.2" }, "last_serial": 4238760, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "23ee9ac722d8e4008f9984bdf377c9b2", "sha256": "9967716725ff0098b821f50e219bcaeaa2e3a393b93cadc1a497bbb40132ffa2" }, "downloads": -1, "filename": "time_travel-0.0.1-py2.7.egg", "has_sig": false, "md5_digest": "23ee9ac722d8e4008f9984bdf377c9b2", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 3906, "upload_time": "2017-10-27T15:02:46", "url": "https://files.pythonhosted.org/packages/9b/7a/bdaf083c4f7799fe905aecf168b15f4691fa093b072491b9b96fd2366f0d/time_travel-0.0.1-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "91222cba10edbb616981ebcd57cb5ee2", "sha256": "39d3ef08ac81d85085f45fd716eef1450cbeee4c3f98b1bd0ce5168621e9fe6f" }, "downloads": -1, "filename": "time_travel-0.0.1.tar.gz", "has_sig": false, "md5_digest": "91222cba10edbb616981ebcd57cb5ee2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1631, "upload_time": "2017-07-08T11:05:18", "url": "https://files.pythonhosted.org/packages/0a/d4/b3e7d764fb532f33499c3314765a10dda8a90a5cb40dc66d7766e04e732c/time_travel-0.0.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "55cac84e5dab2322ebf70e21d4fe36a1", "sha256": "259015ad830c4d791ac70b0e780970ccba15207fcb856ae95cfee4e56feae621" }, "downloads": -1, "filename": "time_travel-0.1.2-py2-none-any.whl", "has_sig": false, "md5_digest": "55cac84e5dab2322ebf70e21d4fe36a1", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 4057, "upload_time": "2017-07-21T15:47:52", "url": "https://files.pythonhosted.org/packages/ec/16/0aacbabae4895721ac1dded05d1bb419ae4a34725fa116f28cceceea90d7/time_travel-0.1.2-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e9a51a47462c8c45914efae42bd64143", "sha256": "e3bf2f10b8788d650ac0ea5d3c1606eb04eadcc158625c74ca941ef6da342bd0" }, "downloads": -1, "filename": "time_travel-0.1.2.tar.gz", "has_sig": false, "md5_digest": "e9a51a47462c8c45914efae42bd64143", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 1439, "upload_time": "2017-07-21T15:47:50", "url": "https://files.pythonhosted.org/packages/26/f9/57365f6b592be4caede5c1539df2d7594bfdd27827c2d0473fcc63369a4d/time_travel-0.1.2.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "51476d0e90f3c638692ae3d2f98c3892", "sha256": "61a1def6b478578bda0e810837b2dc02aba2420c0fe71e0dd9827096ce3aeaff" }, "downloads": -1, "filename": "time_travel-1.0.0-py2-none-any.whl", "has_sig": false, "md5_digest": "51476d0e90f3c638692ae3d2f98c3892", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 5658, "upload_time": "2017-07-28T16:31:39", "url": "https://files.pythonhosted.org/packages/b5/db/1f3112583423bc98f98be2291b4e657a626f4136bfa644fbe26fa87e2986/time_travel-1.0.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "896c3fa29962e9b71bdd30a7d76e3902", "sha256": "c405571a07df8a3e6d05a918e83d3a70d178c2e61f8f60d8ced772e06a49f32e" }, "downloads": -1, "filename": "time_travel-1.0.0.tar.gz", "has_sig": false, "md5_digest": "896c3fa29962e9b71bdd30a7d76e3902", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2464, "upload_time": "2017-07-28T16:28:48", "url": "https://files.pythonhosted.org/packages/04/64/fd1345a7bc25216dcbed0be5abafe5f9b9936eea4024eef1739e7c9e3a57/time_travel-1.0.0.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "dff2dc68185e6a0e015ba080fa9346a9", "sha256": "74459af3fb6c4d2e1aad0d3dcc2561b8e18aecab5194e14e5be96bd495b58eca" }, "downloads": -1, "filename": "time_travel-1.1.0-py2-none-any.whl", "has_sig": false, "md5_digest": "dff2dc68185e6a0e015ba080fa9346a9", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 11023, "upload_time": "2017-10-27T15:02:44", "url": "https://files.pythonhosted.org/packages/4b/42/75dcf8d8c9f7a3dd69ec3ac2b117b923e0999c276ecd7099acda79ecc351/time_travel-1.1.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0cfea21aba22261e549ebd2464e20210", "sha256": "05bc8d511d59bd3e85251ede0acc09fdc969e62259bc17191385e6aae1e97461" }, "downloads": -1, "filename": "time_travel-1.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "0cfea21aba22261e549ebd2464e20210", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 10989, "upload_time": "2017-10-27T15:25:12", "url": "https://files.pythonhosted.org/packages/85/ed/561ed9cc595d796fff2b614c24be13f88652834288bdceff0f1dd7bcc540/time_travel-1.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6c80c7ff8e42b949fd5434d4383fa6a2", "sha256": "c5ae4bb01de2a162fd5bfd8b1ce7a99280273ad59ba1ac27552e102800371018" }, "downloads": -1, "filename": "time_travel-1.1.0.tar.gz", "has_sig": false, "md5_digest": "6c80c7ff8e42b949fd5434d4383fa6a2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5322, "upload_time": "2017-10-27T15:27:17", "url": "https://files.pythonhosted.org/packages/77/b1/6fabe14d8698f98f87c0e342a779a006c72678068a7c6637a18e810d6cb5/time_travel-1.1.0.tar.gz" } ], "1.1.2": [ { "comment_text": "", "digests": { "md5": "3666b2cdb151ceb8522a40c4306d2219", "sha256": "82829b820f9529f714581dfcdb3f96917bc8dc9b28075dbdc144a5e983202038" }, "downloads": -1, "filename": "time_travel-1.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "3666b2cdb151ceb8522a40c4306d2219", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12784, "upload_time": "2018-09-04T19:11:39", "url": "https://files.pythonhosted.org/packages/a1/4a/e9583fa64094ce05f3450c35db3d183a0a54964e70a913fb572885bbb0ef/time_travel-1.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a6660e6ca84bb7a9d6bbbb63311d25f7", "sha256": "55c99d00b169c012e4e7fbebcd208d2e5f132abfbc7bbceb30533ef06f35a44d" }, "downloads": -1, "filename": "time_travel-1.1.2.tar.gz", "has_sig": false, "md5_digest": "a6660e6ca84bb7a9d6bbbb63311d25f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9452, "upload_time": "2018-09-04T19:11:40", "url": "https://files.pythonhosted.org/packages/07/64/922fe9d3bd079b4fbea9726997ed216328d9163490c5f0df8afa58baebab/time_travel-1.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3666b2cdb151ceb8522a40c4306d2219", "sha256": "82829b820f9529f714581dfcdb3f96917bc8dc9b28075dbdc144a5e983202038" }, "downloads": -1, "filename": "time_travel-1.1.2-py3-none-any.whl", "has_sig": false, "md5_digest": "3666b2cdb151ceb8522a40c4306d2219", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 12784, "upload_time": "2018-09-04T19:11:39", "url": "https://files.pythonhosted.org/packages/a1/4a/e9583fa64094ce05f3450c35db3d183a0a54964e70a913fb572885bbb0ef/time_travel-1.1.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a6660e6ca84bb7a9d6bbbb63311d25f7", "sha256": "55c99d00b169c012e4e7fbebcd208d2e5f132abfbc7bbceb30533ef06f35a44d" }, "downloads": -1, "filename": "time_travel-1.1.2.tar.gz", "has_sig": false, "md5_digest": "a6660e6ca84bb7a9d6bbbb63311d25f7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9452, "upload_time": "2018-09-04T19:11:40", "url": "https://files.pythonhosted.org/packages/07/64/922fe9d3bd079b4fbea9726997ed216328d9163490c5f0df8afa58baebab/time_travel-1.1.2.tar.gz" } ] }