# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['preacher',
 'preacher.app',
 'preacher.app.cli',
 'preacher.app.listener',
 'preacher.compilation',
 'preacher.core']

package_data = \
{'': ['*'], 'preacher': ['resources/html/*', 'resources/html/macros/*']}

install_requires = \
['aniso8601>=8.0,<9.0',
 'jinja2>=2.10,<3.0',
 'lxml>=4.4,<5.0',
 'pyhamcrest>=1.9,<2.0',
 'pyjq>=2.3,<3.0',
 'requests>=2.21,<3.0',
 'ruamel.yaml>=0.15.89,<0.16.0']

entry_points = \
{'console_scripts': ['preacher-cli = preacher.app.cli.main:main']}

setup_kwargs = {
    'name': 'preacher',
    'version': '0.10.1',
    'description': 'A web API verification tool.',
    'long_description': '########\nPreacher\n########\n\n.. image:: https://img.shields.io/badge/python-3.7+-blue.svg\n    :target: https://www.python.org/\n.. image:: https://badge.fury.io/py/preacher.svg\n    :target: https://badge.fury.io/py/preacher\n.. image:: https://circleci.com/gh/ymoch/preacher.svg?style=svg\n    :target: https://circleci.com/gh/ymoch/preacher\n.. image:: https://codecov.io/gh/ymoch/preacher/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/ymoch/preacher\n.. image:: https://img.shields.io/lgtm/grade/python/g/ymoch/preacher.svg\n    :target: https://lgtm.com/projects/g/ymoch/preacher/context:python\n\nPreacher verifies API servers,\nwhich requests to API servers and verify the response along to given scenarios.\n\nScenarios are written in `YAML`_, bodies are analyzed `jq`_ or `XPath`_ queries\nand validation rules are based on `Hamcrest`_ (`PyHamcrest`_)\nso that any developers can write without learning toughly.\n\n.. contents:: Contents\n   :depth: 1 \n\n******************\nDevelopment Policy\n******************\nPreacher aims to automate tests using real backends: neither mocks or sandboxes.\nSupporting both automation and real backends has been challenging.\n\nPreacher prefers:\n\n- Flexible validation: Real backends causes fuzzy behavior.\n  Matcher-based validation allow fuzziness caused by real backends.\n- CI integration: CI tools are basic automation ways.\n  CLI and YAML based test scenarios are suitable for CI.\n- Simple GET requests: Testing with real backends often targets data fetching\n  rather than HTTP interactions such as authorization.\n  Development for complex HTTP interactions is less priored.\n\nComparing to other similar tools:\n\n- `Postman <https://www.getpostman.com/>`_ gives rich insights on Web APIs.\n  On the other hand, testing with CLI tools and configuration files is\n  more suitable for CI automation.\n- `Tavern <https://tavern.readthedocs.io/en/latest/>`_ is more suitable for testing\n  HTTP interactions. It seems to be more suitable for testing simple systems\n  or testing without real backends than Preacher because of simple validators.\n\n*****\nUsage\n*****\n\nRequirements\n============\nSupports only Python 3.7+.\n\n.. code-block:: sh\n\n    pip install preacher\n    preacher-cli scenario.yml\n\n    # Help command is available.\n    preacher-cli --help\n\n**************************\nWriting Your Own Scenarios\n**************************\n\nExample\n=======\nHere is a simple configuration example.\n\n.. code-block:: yaml\n\n    label: Scenario example\n    default:\n      request:\n        path: /path\n      response:\n        body:\n          analyzed_as: json\n    cases:\n      - label: Simple\n        request: /path/to/foo\n        response:\n          status_code: 200\n          body:\n            - describe: .foo\n              should:\n                equal: bar\n      - label: A Little Complecated\n        request:\n          path: /path/to/foo\n          headers:\n            user-agent: custom-value\n          params:\n            key1: value\n            key2:\n              - value1\n              - value2\n        response:\n          status_code:\n            - be_greater_than_or_equal_to: 200\n            - be_less_than: 400\n          headers:\n            - describe: ."content-type"\n              should:\n                equal_to: application/xml\n          body:\n            analyzed_as: xml\n            descriptions:\n              - describe: /html/body/h1\n                should:\n                  - start_with: x\n                  - end_with: y\n\nGrammer\n=======\n\nScenario\n--------\nA ``Scenario`` is written in `YAML`_.\nA ``Scenario`` is a mapping that consists of below:\n\n- label: ``String`` (Recommended)\n    - A label of this scenario.\n    - This field is actually optional but recommended to tell this scenario from another.\n- default: ``Default`` (Optional)\n    - Default of this scenario.\n- cases: ``List<Case>``\n    - Test cases.\n\nCase\n----\nA ``Case`` is a mapping that consists of below:\n\n- label: ``String`` (Recommended)\n    - A label of this case.\n    - This field is actually optional but recommended to tell this case from another.\n- request: ``Request`` (Optional)\n    - A request.\n- response: ``ResponseDescription`` (Optional)\n    - A response description.\n\nRequest\n-------\nA ``Request`` is a mapping or a string.\n\nA mapping for ``Request`` has items below:\n\n- path: ``String`` (Optional)\n    - A request path. The default value is ``\'\'``.\n- Headers: ``Mapping<String, String>`` (Optional)\n    - Request headers as a mapping of names to values.\n- params: ``Mapping<String, String>`` (Optional)\n    - Query parameters as a mapping of keys to values.\n\nWhen given a string, that is equivalent to ``{"path": it}``.\n\nResponse Decription\n-------------------\nA ``ResponseDescription`` is a mapping that consists of below:\n\n- status_code: ``Integer``, ``Predicate`` or ``List<Predicate>`` (Optional)\n    - Predicates that match a status code as an integer value.\n    - When given a number, that is equivalent to ``{"equal": it}``.\n- headers:\n    - Descriptions that descript the response headers.\n    - Response headers are validated as a mapping of names to values\n      and can be descripted by `jq_` query (e.g. ``."content-type"``).\n      *Note that Names are lower-cased* to normalize.\n- body: ``BodyDescription`` (Optional)\n    - A description that descript the response body.\n\nBody Description\n----------------\nA ``BodyDescription`` is a mapping or a list.\n\nA mapping for ``BodyDescription`` has items below.\n\n- analyzed_as: ``String`` (Optional)\n    - The method to analyze the body. The default value is ``json``.\n    - When given ``json``, the body is analyzed as a JSON.\n    - When given ``xml``, the body is analyzed as an XML.\n- descriptions: ``Description`` or ``List<Description>``\n    - Descriptions that descript the response body.\n\nWhen given a list, that is equivalent to ``{"descritptions": it}``.\n\nDescription\n-----------\nA ``Description`` is a mapping that consists of below:\n\n- describe: ``Extraction``\n    - An extraction process.\n- should: ``Predicate``, or ``List<Predicate>>`` (Optional)\n    - Predicates that match the descripted value.\n\nExtraction\n----------\nAn Extraction is a mapping or a string.\n\nA mapping for Extraction has one of below:\n\n- jq: ``String``\n    - A `jq`_ query.\n- xpath: ``String``\n    - A `XPath`_ query\n- multiple: ``Boolean`` (Optional)\n    - When given ``true``, it returns the list of all extracted values.\n    - When given ``false``, it returns the first of extracted values.\n    - The default value is ``false``.\n- cast_to: ``String`` (Optional)\n    - When given, it returns the casted value.\n    - Allowed values are ``int``, ``float``, ``string``.\n    - Casting does not affect ``null``.\n\nWhen given a string, that is equivalent to {"jq": it}.\n\n.. note:: The extraction must be compatible for the body analysis.\n\n   +----------------------------+----+-------+\n   | Body Analysis / Extraction | jq | xpath |\n   +============================+====+=======+\n   | JSON                       |  o |     x |\n   +----------------------------+----+-------+\n   | XML                        |  x |     o |\n   +----------------------------+----+-------+\n\nPredicate\n---------\nA ``Predicate`` is a ``Matcher`` (can be extended in the future).\n\nMatcher\n-------\nA ``Matcher`` is a string or a mapping that has an item.\nAllowed matchers are below.\n\n.. note:: A matchers taking ``none`` is given as a string like ``{"should": "be_null"}``.\n.. note:: A ``Value`` given as a ``Matcher`` is equivalent to ``{"equal": it}``.\n\nObject\n^^^^^^\n- be: ``Matcher``\n    - Matches the given matcher.\n- be_null: ``none``\n    - Matches if it is a null value.\n- not_be_null: ``none``\n    - Matches if it is not a null value.\n- equal: ``Value``\n    - Matches if it equals the given value.\n- have_length: ``Integer``\n    - Matches if it has a length and its length is equal to the given value.\n\nComparable\n^^^^^^^^^^\n- be_greater_than: ``Comparable``\n    - Matches if it is greater than the given value (it > argument).\n- be_greater_than_or_equal_to: ``Comparable``\n    - Matches if it is greater than or equal to the given value (it >= argument).\n- be_less_than: ``Comparable``\n    - Matches if it is less than the given value (it < argument).\n- be_less_than_or_equal_to: ``Comparable``\n    - Matches if it is less than or equal to the given value (it < argument).\n\nString\n^^^^^^\n- contain_string: ``String``\n    - Matches if it is an string and contains the given value.\n- start_with: ``String``\n    - Matches if it is an string and starts with the given value.\n- end_with: ``String``\n    - Matches if it is an string and ends with the given value.\n- match_regexp: ``String``\n    - Matches if it is an string and matches the given regular expression.\n\nDatetime\n^^^^^^^^\n- be_before: ``String``\n    - Matches if it is a datetime and before the given datetime.\n    - When given ``now``, then compares to the datetime just when the request starts.\n    - When given an offset, then compares to the datetime when the request starts.\n        - Days, hours, minutes and seconds offsets are available.\n        - When given a positive offset like ``1 day`` or ``+2 hours``,\n          then compares to the future datetime.\n        - When given a negative offset like ``-1 minute`` or ``-2 seconds``,\n          then compares to the past datetime.\n- be_after: ``String``\n    - Matches if it is a datetime and after the given datetime.\n    - Usage is the same as ``be_before``.\n\n.. note:: Validated datetime values must be in ISO 8601 format\n          like ``2019-01-23T12:34:56Z``.\n\nSequence\n^^^^^^^^\n- be_empty: ``none``\n    - Matches an empty sequence.\n- have_item: ``Matcher``\n    - Matches if it is a collection and has the given item.\n- have_items: ``List<Matcher>``\n    - Matches if all given items appear in the list, in any order.\n- contain: ``List<Matcher>``\n    - Exactly matches the entire sequence.\n- contain_in_any_order: ``List<Matcher>``\n    - Matches the entire sequence, but in any order.\n\nLogical\n^^^^^^^\n- not: ``Matcher``\n    - Matches if it doesn\'t match the given matcher.\n- all_of: ``List<Matcher>``\n    - Matches if it matches all of the given matchers.\n- any_of: ``List<Matcher>``\n    - Matches if it matches any of the given matchers.\n- anything: ``none``\n    - Matches anything.\n\nDefault\n-------\nA ``Default`` is a mapping that consists of below:\n\n- request: ``Request`` (Optional)\n    - A request to overwrite the default request values.\n- response: ``ResponseDescription`` (Optional)\n    - A response description to overwrite the default response description values.\n\n*******\nLicense\n*******\n.. image:: https://img.shields.io/badge/License-MIT-brightgreen.svg\n    :target: https://opensource.org/licenses/MIT\n\nCopyright (c) 2019 Yu MOCHIZUKI\n\n\n.. _YAML: https://yaml.org/\n.. _jq: https://stedolan.github.io/jq/\n.. _XPATH: https://www.w3.org/TR/xpath/all/\n.. _Hamcrest: http://hamcrest.org/\n.. _PyHamcrest: https://pyhamcrest.readthedocs.io/\n',
    'author': 'Yu Mochizuki',
    'author_email': 'ymoch.dev@gmail.com',
    'url': 'https://github.com/ymoch/preacher',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
