#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Tests for `scopes` package."""

import os

print(os.getenv('PYTHONPATH'))

import pytest

from click.testing import CliRunner

from scopes.tasks import tasks, bolt, spout, builder
from scopes.graph import G, build, topological_sort, traverse
from scopes import cli


@pytest.fixture
def response():
    """Sample pytest fixture.

    See more at: http://doc.pytest.org/en/latest/fixture.html
    """
    # import requests
    # return requests.get('https://github.com/audreyr/cookiecutter-pypackage')


def test_content(response):
    """Sample pytest test function with the pytest fixture as an argument."""
    # from bs4 import BeautifulSoup
    # assert 'GitHub' in BeautifulSoup(response.content).title.string


def test_command_line_interface():
    """Test the CLI."""
    runner = CliRunner()
    result = runner.invoke(cli.main)
    assert result.exit_code == 0
    assert 'scopes.cli.main' in result.output
    help_result = runner.invoke(cli.main, ['--help'])
    assert help_result.exit_code == 0
    assert '--help  Show this message and exit.' in help_result.output


# t1---
# |   |
# v   v
# t2  t3
# \  /     t4
#  v       |
#  t5<----/


@pytest.fixture
def example():
    tasks.clear()
    G.clear()

    @spout({'x': None})
    def t1():
        yield {'x': 'east'}
        yield {'x': 'west'}


    @bolt({'y': None}, lambda d: 'x' in d)
    def t2(dep):
        return {'y': 1, **dep}


    @bolt({'z': None}, lambda d: d == {'x': None})
    def t3(dep):
        return {'z': 1, **dep}


    @spout({'c': None})
    def t4():
        yield {'c': 4, 'x': 'east'}
        yield {'c': 5, 'x': 'west'}


    @builder({'a': 2}, lambda _: True, 'x')
    def t5(obj, dep):
        obj.update(dep)


def test_task_decorator(example):
    assert len(tasks) == 5
    assert callable(tasks[0].func)
    assert tasks[0].obj == {'x': None}


def test_task_dag(example):
    build(tasks)

    assert len(G) == 5
    assert len(G.edges) == 6


def test_task_traversal(example):
    build(tasks)
    nodes = topological_sort()
    results = traverse(nodes)

    assert results == {
            't1': [{'x': 'east'}, {'x': 'west'}],
            't2': [{'x': 'east', 'y': 1}, {'x': 'west', 'y': 1}],
            't3': [{'x': 'east', 'z': 1}, {'x': 'west', 'z': 1}],
            't4': [{'x': 'east', 'c': 4}, {'x': 'west', 'c': 5}],
            't5': [
                {'a': 2, 'x': 'east', 'y': 1, 'z': 1, 'c': 4},
                {'a': 2, 'x': 'west', 'y': 1, 'z': 1, 'c': 5}
                ]
            }

[((99, 122), 'os.getenv', 'os.getenv', (['"""PYTHONPATH"""'], {}), "('PYTHONPATH')\n", (108, 122), False, 'import os\n'), ((839, 850), 'click.testing.CliRunner', 'CliRunner', ([], {}), '()\n', (848, 850), False, 'from click.testing import CliRunner\n'), ((1241, 1254), 'scopes.tasks.tasks.clear', 'tasks.clear', ([], {}), '()\n', (1252, 1254), False, 'from scopes.tasks import tasks, bolt, spout, builder\n'), ((1259, 1268), 'scopes.graph.G.clear', 'G.clear', ([], {}), '()\n', (1266, 1268), False, 'from scopes.graph import G, build, topological_sort, traverse\n'), ((1275, 1293), 'scopes.tasks.spout', 'spout', (["{'x': None}"], {}), "({'x': None})\n", (1280, 1293), False, 'from scopes.tasks import tasks, bolt, spout, builder\n'), ((1371, 1408), 'scopes.tasks.bolt', 'bolt', (["{'y': None}", "(lambda d: 'x' in d)"], {}), "({'y': None}, lambda d: 'x' in d)\n", (1375, 1408), False, 'from scopes.tasks import tasks, bolt, spout, builder\n'), ((1464, 1509), 'scopes.tasks.bolt', 'bolt', (["{'z': None}", "(lambda d: d == {'x': None})"], {}), "({'z': None}, lambda d: d == {'x': None})\n", (1468, 1509), False, 'from scopes.tasks import tasks, bolt, spout, builder\n'), ((1565, 1583), 'scopes.tasks.spout', 'spout', (["{'c': None}"], {}), "({'c': None})\n", (1570, 1583), False, 'from scopes.tasks import tasks, bolt, spout, builder\n'), ((1677, 1715), 'scopes.tasks.builder', 'builder', (["{'a': 2}", '(lambda _: True)', '"""x"""'], {}), "({'a': 2}, lambda _: True, 'x')\n", (1684, 1715), False, 'from scopes.tasks import tasks, bolt, spout, builder\n'), ((1933, 1945), 'scopes.graph.build', 'build', (['tasks'], {}), '(tasks)\n', (1938, 1945), False, 'from scopes.graph import G, build, topological_sort, traverse\n'), ((2039, 2051), 'scopes.graph.build', 'build', (['tasks'], {}), '(tasks)\n', (2044, 2051), False, 'from scopes.graph import G, build, topological_sort, traverse\n'), ((2064, 2082), 'scopes.graph.topological_sort', 'topological_sort', ([], {}), '()\n', (2080, 2082), False, 'from scopes.graph import G, build, topological_sort, traverse\n'), ((2097, 2112), 'scopes.graph.traverse', 'traverse', (['nodes'], {}), '(nodes)\n', (2105, 2112), False, 'from scopes.graph import G, build, topological_sort, traverse\n')]