<commit_before>import importlib
import json

import pytest

from netdumplings import DumplingKitchen, DumplingChef, DumplingDriver

class TestDumplingKitchen:
    """
    Test the DumplingKitchen class.
    """
    def test_init_default(self):
        """
        Test default DumplingKitchen initialization.
        """
        kitchen = DumplingKitchen()

        assert kitchen.name == 'default'
        assert kitchen.interface == 'all'
        assert kitchen.filter == 'tcp'
        assert kitchen.chef_poke_interval == 5

        assert len(kitchen._chefs) == 0

    def test_init_with_overrides(self):
        """
        Test DumplingKitchen initialization with overrides.
        """
        kitchen = DumplingKitchen(
            name='test_kitchen',
            interface='en0',
            sniffer_filter='test filter',
            chef_poke_interval=10,
        )

        assert kitchen.name == 'test_kitchen'
        assert kitchen.interface == 'en0'
        assert kitchen.filter == 'test filter'
        assert kitchen.chef_poke_interval == 10

        assert len(kitchen._chefs) == 0

    def test_chef_registration(self):
        """
        Test registration of chefs with the kitchen.
        """
        kitchen = DumplingKitchen()

        assert len(kitchen._chefs) == 0

        test_chef_1 = DumplingChef()
        test_chef_2 = DumplingChef()

        kitchen.register_chef(test_chef_1)
        assert kitchen._chefs == [test_chef_1]

        kitchen.register_chef(test_chef_2)
        assert kitchen._chefs == [test_chef_1, test_chef_2]

    def test_repr(self):
        """
        Test the string representation.
        """
        kitchen = DumplingKitchen()
        assert repr(kitchen) == (
            "DumplingKitchen(name={}, "
            "interface={}, "
            "sniffer_filter={}, "
            "chef_poke_interval={} "
            "dumpling_queue={})".format(
                repr(kitchen.name),
                repr(kitchen.interface),
                repr(kitchen.filter),
                repr(kitchen.chef_poke_interval),
                repr(kitchen.dumpling_queue),
            )
        )

class TestHandlerInvocations:
    """
    Test DumplingKitchen invocations of the packet and interval handlers.
    """
    def test_packet_processing(self, mocker):
        """
        Test invocation of the packet handlers.
        """
        kitchen = DumplingKitchen()

        # Set up two valid chefs. One of them returns a dumpling when given a
        # packet, and the other one doesn't.
        mock_chef_with_packet_dumpling = mocker.Mock()
        mock_chef_with_no_packet_dumpling = mocker.Mock()

        mock_chef_with_packet_dumpling.packet_handler.return_value = 'dumpling'
        mock_chef_with_no_packet_dumpling.packet_handler.return_value = None

        kitchen._chefs = [
            mock_chef_with_packet_dumpling,
            mock_chef_with_no_packet_dumpling,
        ]

        packet = 'test_packet'
        kitchen._process_packet(packet)

        # Check that we only sent one packet dumpling.
        kitchen._send_packet_dumpling.assert_called_once_with(
            mock_chef_with_packet_dumpling,
            'dumpling'
        )

    def test_packet_processing_with_broken_handler(self, mocker):
        """
        Test invocations of the packet handlers where one of them raises an
        exception, which should result in an exception-level log entry being
        created but the processing being otherwise unaffected.
        """
        kitchen = DumplingKitchen()

        # Set up two valid chefs. One of them returns a dumpling when given a
        # packet, and the raises an exception.
        mock_chef_with_packet_dumpling = mocker.Mock()
        mock_chef_with_no_packet_dumpling = mocker.Mock()

        mock_chef_with_packet_dumpling.packet_handler.return_value = 'dumpling'
        mock_chef_with_no_packet_dumpling.packet_handler.side_effect = KeyError

        kitchen._chefs = [
            mock_chef_with_packet_dumpling,
            mock_chef_with_no_packet_dumpling,
        ]

        # Add a spy on the logger so we can check it got called.
        mocker.spy(kitchen._logger, 'exception')

        packet = 'test_packet'
        kitchen._process_packet(packet)

        # Check that we only sent one packet dumpling, and that an
        # exception-level log was created.
        kitchen._send_packet_dumpling.assert_called_once_with(
            mock_chef_with_packet_dumpling,
            'dumpling'
        )
        kitchen._logger.exception.assert_called_once()

    def test_chef_poking(self, mocker):
        """
        Test interval-based chef poking.
        """
        test_interval = 3
        kitchen = DumplingKitchen(chef_poke_interval=test_interval)

        # _poke_chefs() runs in an infinite loop which we need to break out of.
        # We do that by setting a side effect on the mocked call to sleep()
        # which will raise a RuntimeError. This doesn't interfere with being
        # able to determine the value passed to sleep().
        mock_sleep = mocker.patch(
            'netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError
        )

        # Set up two valid chefs. One of them returns a dumpling when poked and
        # and the other one doesn't.
        mock_chef_with_interval_dumpling = mocker.Mock()
        mock_chef_with_no_interval_dumpling = mocker.Mock()

        dumpling_interval_handler = (
            mock_chef_with_interval_dumpling.interval_handler
        )
        no_dumpling_interval_handler = (
            mock_chef_with_no_interval_dumpling.interval_handler
        )

        dumpling_interval_handler.return_value = 'dumpling'
        no_dumpling_interval_handler.return_value = None

        kitchen._chefs = [
            mock_chef_with_interval_dumpling,
            mock_chef_with_no_interval_dumpling,
        ]

        # Run once through the poker infinite loop.
        with pytest.raises(RuntimeError):
            kitchen._poke_chefs(test_interval)

        # Check that we were asked to sleep by the test interval.
        mock_sleep.assert_called_once_with(test_interval)

        # Check that the two interval handlers were invoked, and that the one
        # that returned a dumpling resulted in that dumpling being sent.
        dumpling_interval_handler.assert_called_once_with(
            interval=test_interval
        )
        no_dumpling_interval_handler.assert_called_once_with(
            interval=test_interval
        )

        kitchen._send_interval_dumpling.assert_called_once_with(
            mock_chef_with_interval_dumpling,
            'dumpling'
        )

    def test_chef_poking_with_broken_handler(self, mocker):
        """
        Test interval-based chef poking where one of the handlers raises an
        exception, which should result in an exception-level log entry being
        created but the processing being otherwise unaffected.
        """
        test_interval = 3
        kitchen = DumplingKitchen(chef_poke_interval=test_interval)

        mocker.patch(
            'netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError
        )

        # Set up one valid chefs which returns an interval dumpling, and one
        # chef which raises an exception in its interval handler.
        # and the other one doesn't.
        mock_chef_with_interval_dumpling = mocker.Mock()
        mock_chef_with_interval_error = mocker.Mock()

        dumpling_interval_handler = (
            mock_chef_with_interval_dumpling.interval_handler
        )
        error_interval_handler = (
            mock_chef_with_interval_error.interval_handler
        )

        dumpling_interval_handler.return_value = 'dumpling'
        error_interval_handler.side_effect = KeyError

        kitchen._chefs = [
            mock_chef_with_interval_dumpling,
            mock_chef_with_interval_error,
        ]

        # Run once through the poker infinite loop.
        with pytest.raises(RuntimeError):
            kitchen._poke_chefs(test_interval)

        # Check that the valid dumpling was sent, and that we logged an
        # exception for the other chef.
        kitchen._send_interval_dumpling.assert_called_once_with(
            mock_chef_with_interval_dumpling,
            'dumpling'
        )
        kitchen._logger.exception.assert_called_once()

class TestDumplingSends:
    """
    Test the sending of dumplings.
    """
    def test_send_interval_dumpling(self, mocker):
        """
        Test sending an interval dumpling. It should invoke _send_dumpling
        with the interval dumpling driver.
        """
        kitchen = DumplingKitchen()
        chef = DumplingChef()

        mocker.patch.object(kitchen, '_send_dumpling')

        test_payload = {'one': 1, 'two': 2}
        kitchen._send_interval_dumpling(chef, test_payload)

        kitchen._send_dumpling.assert_called_once_with(
            chef, driver=DumplingDriver.interval, payload=test_payload
        )

    def test_send_packet_dumpling(self, mocker, mock_kitchen):
        """
        Test sending an interval dumpling. It should invoke _send_dumpling
        with the packet dumpling driver.
        """
        kitchen = DumplingKitchen()
        chef = DumplingChef()

        mocker.patch.object(kitchen, '_send_dumpling')

        test_payload = {'one': 1, 'two': 2}
        kitchen._send_packet_dumpling(chef, test_payload)

        kitchen._send_dumpling.assert_called_once_with(
            chef, driver=DumplingDriver.packet, payload=test_payload
        )

    def test_dumpling_send(self, mocker, test_dumpling_dns):
        """
        Test the _send_dumpling method to ensure that it calls make() on a new
        Dumpling and puts the resulting dumpling contents onto the queue.
        """
        test_payload_json = json.dumps(test_dumpling_dns)

        mock_dumpling_class = mocker.patch(
            'netdumplings.dumplingkitchen.Dumpling'
        )

        mock_dumpling_class.return_value.make.return_value = (
            test_payload_json
        )

        mock_chef = mocker.Mock()
        mock_queue = mocker.Mock()

        kitchen = DumplingKitchen(dumpling_queue=mock_queue)

        kitchen._send_dumpling(
            chef=mock_chef,
            driver=DumplingDriver.packet,
            payload=test_dumpling_dns['payload']
        )

        mock_dumpling_class.assert_called_once_with(
            chef=mock_chef,
            driver=DumplingDriver.packet,
            payload=test_dumpling_dns['payload']
        )

        mock_queue.put.assert_called_once_with(test_payload_json)

class TestChefDiscovery:
    """
    Test DumplingKitchen chef discovery.
    """
    def test_chef_discovery(self, mocker):
        """
        Test discovery of chefs from the two valid test chef modules.
        """
        kitchen = DumplingKitchen()

        # WARNING: This will actually allow the imports to take place, so we're
        # technically letting this test pollute our namespace.
        spy_importlib = mocker.spy(importlib, 'import_module')

        chef_info = kitchen.get_chefs_in_modules([
            'tests.data.dumplingchefs',
            'tests.data.moredumplingchefs',
        ])

        # Assert that the two chef modules were actually imported.
        assert spy_importlib.call_count == 2

        assert spy_importlib.call_args_list == [
            (('tests.data.dumplingchefs',),),
            (('tests.data.moredumplingchefs',),),
        ]

        # Assert that the return value of get_chefs_in_modules looks correct.
        assert 'tests.data.dumplingchefs' in chef_info
        assert 'tests.data.moredumplingchefs' in chef_info
        assert len(chef_info.keys()) == 2

        chef_module_one = chef_info['tests.data.dumplingchefs']

        assert chef_module_one['import_error'] is False
        assert sorted(chef_module_one['chef_classes']) == sorted([
            'TestChefOne', 'TestChefTwo', 'TestChefThree'
        ])

        chef_module_two = chef_info['tests.data.moredumplingchefs']

        assert chef_module_two['import_error'] is False
        assert 'NotAChef' not in chef_module_two['chef_classes']
        assert sorted(chef_module_two['chef_classes']) == sorted([
            'MoreTestChefOne', 'MoreTestChefTwo'
        ])

    def test_chef_discovery_with_invalid_module(self):
        """
        Test that attempting to discover chefs from an invalid module
        successfully results in an error for that module, while chefs from a
        valid module are still properly imported.
        """
        kitchen = DumplingKitchen()

        chef_info = kitchen.get_chefs_in_modules([
            'tests.data.dumplingchefs',
            'tests.data.doesnotexist',
        ])

        # We expect to get two results back, but one of them will be an error.
        assert len(chef_info.keys()) == 2

        valid_module = chef_info['tests.data.dumplingchefs']
        assert valid_module['import_error'] is False

        invalid_module = chef_info['tests.data.doesnotexist']
        assert (
            invalid_module['import_error'] ==
            "No module named 'tests.data.doesnotexist'"
        )
        assert len(invalid_module['chef_classes']) == 0

class TestKitchenRun:
    """
    Test DumplingKitchen run() calls.
    """
    def test_poke_thread_started(self, mocker):
        """
        Test that an attempt is made to start the poke thread when poking is
        enabled.
        """
        kitchen = DumplingKitchen(chef_poke_interval=5)

        mock_thread = mocker.patch('netdumplings.dumplingkitchen.Thread')
        mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_thread.assert_called_once_with(
            target=kitchen._poke_chefs,
            kwargs={'interval': 5},
        )

    def test_poke_thread_not_started(self, mocker):
        """
        Test that the poke thread is not started when the kitchen is not
        poking.
        """
        kitchen = DumplingKitchen(chef_poke_interval=None)

        mock_thread = mocker.patch('netdumplings.dumplingkitchen.Thread')
        mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_thread.assert_not_called()

    def test_sniffer_started_with_specified_interface(self, mocker):
        """
        Test that the sniffer was started with the specified interface.
        """
        kitchen = DumplingKitchen(interface='en0')

        mocker.patch('netdumplings.dumplingkitchen.Thread')
        mock_sniffer = mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_sniffer.assert_called_once_with(
            iface='en0',
            filter='tcp',
            prn=kitchen._process_packet,
            store=0,
        )

    def test_sniffer_started_with_all_interface(self, mocker):
        """
        Test that the sniffer was started with no specified interface when the
        'all' interface is requested. Not passing an interface to the sniffer
        results in all interfaces being sniffed.
        """
        kitchen = DumplingKitchen(interface='all')

        mocker.patch('netdumplings.dumplingkitchen.Thread')
        mock_sniffer = mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_sniffer.assert_called_once_with(
            filter='tcp',
            prn=kitchen._process_packet,
            store=0,
        )
<commit_msg>Update DumplingKitchen tests to allow for single _send_dumpling() method<commit_after>import importlib
import json

import pytest

from netdumplings import DumplingKitchen, DumplingChef, DumplingDriver

class TestDumplingKitchen:
    """
    Test the DumplingKitchen class.
    """
    def test_init_default(self):
        """
        Test default DumplingKitchen initialization.
        """
        kitchen = DumplingKitchen()

        assert kitchen.name == 'default'
        assert kitchen.interface == 'all'
        assert kitchen.filter == 'tcp'
        assert kitchen.chef_poke_interval == 5

        assert len(kitchen._chefs) == 0

    def test_init_with_overrides(self):
        """
        Test DumplingKitchen initialization with overrides.
        """
        kitchen = DumplingKitchen(
            name='test_kitchen',
            interface='en0',
            sniffer_filter='test filter',
            chef_poke_interval=10,
        )

        assert kitchen.name == 'test_kitchen'
        assert kitchen.interface == 'en0'
        assert kitchen.filter == 'test filter'
        assert kitchen.chef_poke_interval == 10

        assert len(kitchen._chefs) == 0

    def test_chef_registration(self):
        """
        Test registration of chefs with the kitchen.
        """
        kitchen = DumplingKitchen()

        assert len(kitchen._chefs) == 0

        test_chef_1 = DumplingChef()
        test_chef_2 = DumplingChef()

        kitchen.register_chef(test_chef_1)
        assert kitchen._chefs == [test_chef_1]

        kitchen.register_chef(test_chef_2)
        assert kitchen._chefs == [test_chef_1, test_chef_2]

    def test_repr(self):
        """
        Test the string representation.
        """
        kitchen = DumplingKitchen()
        assert repr(kitchen) == (
            "DumplingKitchen(name={}, "
            "interface={}, "
            "sniffer_filter={}, "
            "chef_poke_interval={} "
            "dumpling_queue={})".format(
                repr(kitchen.name),
                repr(kitchen.interface),
                repr(kitchen.filter),
                repr(kitchen.chef_poke_interval),
                repr(kitchen.dumpling_queue),
            )
        )

class TestHandlerInvocations:
    """
    Test DumplingKitchen invocations of the packet and interval handlers.
    """
    def test_packet_processing(self, mocker):
        """
        Test invocation of the packet handlers.
        """
        kitchen = DumplingKitchen()
        mocker.patch.object(kitchen, '_send_dumpling')

        # Set up two valid chefs. One of them returns a dumpling when given a
        # packet, and the other one doesn't.
        mock_chef_with_packet_dumpling = mocker.Mock()
        mock_chef_with_no_packet_dumpling = mocker.Mock()

        mock_chef_with_packet_dumpling.packet_handler.return_value = 'dumpling'
        mock_chef_with_no_packet_dumpling.packet_handler.return_value = None

        kitchen._chefs = [
            mock_chef_with_packet_dumpling,
            mock_chef_with_no_packet_dumpling,
        ]

        packet = 'test_packet'
        kitchen._process_packet(packet)

        # Check that we only sent one packet dumpling.
        kitchen._send_dumpling.assert_called_once_with(
            mock_chef_with_packet_dumpling,
            'dumpling',
            DumplingDriver.packet,
        )

    def test_packet_processing_with_broken_handler(self, mocker):
        """
        Test invocations of the packet handlers where one of them raises an
        exception, which should result in an exception-level log entry being
        created but the processing being otherwise unaffected.
        """
        kitchen = DumplingKitchen()
        mocker.patch.object(kitchen, '_send_dumpling')
        mocker.patch.object(kitchen, '_logger')

        # Set up two valid chefs. One of them returns a dumpling when given a
        # packet, and the raises an exception.
        mock_chef_with_packet_dumpling = mocker.Mock()
        mock_chef_with_no_packet_dumpling = mocker.Mock()

        mock_chef_with_packet_dumpling.packet_handler.return_value = 'dumpling'
        mock_chef_with_no_packet_dumpling.packet_handler.side_effect = KeyError

        kitchen._chefs = [
            mock_chef_with_packet_dumpling,
            mock_chef_with_no_packet_dumpling,
        ]

        # Add a spy on the logger so we can check it got called.
        mocker.spy(kitchen._logger, 'exception')

        packet = 'test_packet'
        kitchen._process_packet(packet)

        # Check that we only sent one packet dumpling, and that an
        # exception-level log was created.
        kitchen._send_dumpling.assert_called_once_with(
            mock_chef_with_packet_dumpling,
            'dumpling',
            DumplingDriver.packet,
        )
        kitchen._logger.exception.assert_called_once()

    def test_chef_poking(self, mocker):
        """
        Test interval-based chef poking.
        """
        test_interval = 3
        kitchen = DumplingKitchen(
            chef_poke_interval=test_interval,
        )
        mocker.patch.object(kitchen, '_send_dumpling')

        # _poke_chefs() runs in an infinite loop which we need to break out of.
        # We do that by setting a side effect on the mocked call to sleep()
        # which will raise a RuntimeError. This doesn't interfere with being
        # able to determine the value passed to sleep().
        mock_sleep = mocker.patch(
            'netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError
        )

        # Set up two valid chefs. One of them returns a dumpling when poked and
        # and the other one doesn't.
        mock_chef_with_interval_dumpling = mocker.Mock()
        mock_chef_with_no_interval_dumpling = mocker.Mock()

        dumpling_interval_handler = (
            mock_chef_with_interval_dumpling.interval_handler
        )
        no_dumpling_interval_handler = (
            mock_chef_with_no_interval_dumpling.interval_handler
        )

        dumpling_interval_handler.return_value = 'dumpling'
        no_dumpling_interval_handler.return_value = None

        kitchen._chefs = [
            mock_chef_with_interval_dumpling,
            mock_chef_with_no_interval_dumpling,
        ]

        # Run once through the poker infinite loop.
        with pytest.raises(RuntimeError):
            kitchen._poke_chefs(test_interval)

        # Check that we were asked to sleep by the test interval.
        mock_sleep.assert_called_once_with(test_interval)

        # Check that the two interval handlers were invoked, and that the one
        # that returned a dumpling resulted in that dumpling being sent.
        dumpling_interval_handler.assert_called_once_with(
            interval=test_interval
        )
        no_dumpling_interval_handler.assert_called_once_with(
            interval=test_interval
        )

        kitchen._send_dumpling.assert_called_once_with(
            mock_chef_with_interval_dumpling,
            'dumpling',
            DumplingDriver.interval,
        )

    def test_chef_poking_with_broken_handler(self, mocker):
        """
        Test interval-based chef poking where one of the handlers raises an
        exception, which should result in an exception-level log entry being
        created but the processing being otherwise unaffected.
        """
        test_interval = 3
        kitchen = DumplingKitchen(
            chef_poke_interval=test_interval,
        )
        mocker.patch.object(kitchen, '_send_dumpling')
        mocker.patch.object(kitchen, '_logger')

        mocker.patch(
            'netdumplings.dumplingkitchen.sleep', side_effect=RuntimeError
        )

        # Set up one valid chefs which returns an interval dumpling, and one
        # chef which raises an exception in its interval handler.
        # and the other one doesn't.
        mock_chef_with_interval_dumpling = mocker.Mock()
        mock_chef_with_interval_error = mocker.Mock()

        dumpling_interval_handler = (
            mock_chef_with_interval_dumpling.interval_handler
        )
        error_interval_handler = (
            mock_chef_with_interval_error.interval_handler
        )

        dumpling_interval_handler.return_value = 'dumpling'
        error_interval_handler.side_effect = KeyError

        kitchen._chefs = [
            mock_chef_with_interval_dumpling,
            mock_chef_with_interval_error,
        ]

        # Run once through the poker infinite loop.
        with pytest.raises(RuntimeError):
            kitchen._poke_chefs(test_interval)

        # Check that the valid dumpling was sent, and that we logged an
        # exception for the other chef.
        kitchen._send_dumpling.assert_called_once_with(
            mock_chef_with_interval_dumpling,
            'dumpling',
            DumplingDriver.interval,
        )
        kitchen._logger.exception.assert_called_once()

class TestDumplingSends:
    """
    Test the sending of dumplings.
    """
    def test_dumpling_send(self, mocker, test_dumpling_dns):
        """
        Test the _send_dumpling method to ensure that it calls make() on a new
        Dumpling and puts the resulting dumpling contents onto the queue.
        """
        test_payload_json = json.dumps(test_dumpling_dns)

        mock_dumpling_class = mocker.patch(
            'netdumplings.dumplingkitchen.Dumpling'
        )

        mock_dumpling_class.return_value.make.return_value = (
            test_payload_json
        )

        mock_chef = mocker.Mock()
        mock_queue = mocker.Mock()

        kitchen = DumplingKitchen(dumpling_queue=mock_queue)

        kitchen._send_dumpling(
            chef=mock_chef,
            payload=test_dumpling_dns['payload'],
            driver=DumplingDriver.packet,
        )

        mock_dumpling_class.assert_called_once_with(
            chef=mock_chef,
            payload=test_dumpling_dns['payload'],
            driver=DumplingDriver.packet,
        )

        mock_queue.put.assert_called_once_with(test_payload_json)

class TestChefDiscovery:
    """
    Test DumplingKitchen chef discovery.
    """
    def test_chef_discovery(self, mocker):
        """
        Test discovery of chefs from the two valid test chef modules.
        """
        kitchen = DumplingKitchen()

        # WARNING: This will actually allow the imports to take place, so we're
        # technically letting this test pollute our namespace.
        spy_importlib = mocker.spy(importlib, 'import_module')

        chef_info = kitchen.get_chefs_in_modules([
            'tests.data.dumplingchefs',
            'tests.data.moredumplingchefs',
        ])

        # Assert that the two chef modules were actually imported.
        assert spy_importlib.call_count == 2

        assert spy_importlib.call_args_list == [
            (('tests.data.dumplingchefs',),),
            (('tests.data.moredumplingchefs',),),
        ]

        # Assert that the return value of get_chefs_in_modules looks correct.
        assert 'tests.data.dumplingchefs' in chef_info
        assert 'tests.data.moredumplingchefs' in chef_info
        assert len(chef_info.keys()) == 2

        chef_module_one = chef_info['tests.data.dumplingchefs']

        assert chef_module_one['import_error'] is False
        assert sorted(chef_module_one['chef_classes']) == sorted([
            'TestChefOne', 'TestChefTwo', 'TestChefThree'
        ])

        chef_module_two = chef_info['tests.data.moredumplingchefs']

        assert chef_module_two['import_error'] is False
        assert 'NotAChef' not in chef_module_two['chef_classes']
        assert sorted(chef_module_two['chef_classes']) == sorted([
            'MoreTestChefOne', 'MoreTestChefTwo'
        ])

    def test_chef_discovery_with_invalid_module(self):
        """
        Test that attempting to discover chefs from an invalid module
        successfully results in an error for that module, while chefs from a
        valid module are still properly imported.
        """
        kitchen = DumplingKitchen()

        chef_info = kitchen.get_chefs_in_modules([
            'tests.data.dumplingchefs',
            'tests.data.doesnotexist',
        ])

        # We expect to get two results back, but one of them will be an error.
        assert len(chef_info.keys()) == 2

        valid_module = chef_info['tests.data.dumplingchefs']
        assert valid_module['import_error'] is False

        invalid_module = chef_info['tests.data.doesnotexist']
        assert (
            invalid_module['import_error'] ==
            "No module named 'tests.data.doesnotexist'"
        )
        assert len(invalid_module['chef_classes']) == 0

class TestKitchenRun:
    """
    Test DumplingKitchen run() calls.
    """
    def test_poke_thread_started(self, mocker):
        """
        Test that an attempt is made to start the poke thread when poking is
        enabled.
        """
        kitchen = DumplingKitchen(chef_poke_interval=5)

        mock_thread = mocker.patch('netdumplings.dumplingkitchen.Thread')
        mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_thread.assert_called_once_with(
            target=kitchen._poke_chefs,
            kwargs={'interval': 5},
        )

    def test_poke_thread_not_started(self, mocker):
        """
        Test that the poke thread is not started when the kitchen is not
        poking.
        """
        kitchen = DumplingKitchen(chef_poke_interval=None)

        mock_thread = mocker.patch('netdumplings.dumplingkitchen.Thread')
        mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_thread.assert_not_called()

    def test_sniffer_started_with_specified_interface(self, mocker):
        """
        Test that the sniffer was started with the specified interface.
        """
        kitchen = DumplingKitchen(interface='en0')

        mocker.patch('netdumplings.dumplingkitchen.Thread')
        mock_sniffer = mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_sniffer.assert_called_once_with(
            iface='en0',
            filter='tcp',
            prn=kitchen._process_packet,
            store=0,
        )

    def test_sniffer_started_with_all_interface(self, mocker):
        """
        Test that the sniffer was started with no specified interface when the
        'all' interface is requested. Not passing an interface to the sniffer
        results in all interfaces being sniffed.
        """
        kitchen = DumplingKitchen(interface='all')

        mocker.patch('netdumplings.dumplingkitchen.Thread')
        mock_sniffer = mocker.patch('netdumplings.dumplingkitchen.sniff')

        kitchen.run()
        mock_sniffer.assert_called_once_with(
            filter='tcp',
            prn=kitchen._process_packet,
            store=0,
        )
<|endoftext|>


<commit_before>#!/usr/bin/env python
# coding=utf8

import json
import sys

if sys.version_info < (2, 7):
    import unittest2 as unittest
else:
    import unittest

import time

from simplekv.memory import DictStore
from flask import Flask, session
from flaskext.kvsession import generate_session_key, KVSession

class TestGenerateSessionKey(unittest.TestCase):
    def test_id_well_formed(self):
        for i in xrange(0,100):
            key = generate_session_key(time.time())

            self.assertRegexpMatches(key, r'^[0-9a-f]+_[0-9a-f]+$')

    def test_non_expiring_id_has_timestamp_0(self):
        key = generate_session_key()
        id, timestamp = key.split('_')

        self.assertEqual(int(timestamp), 0)

    def test_timestamp_set_properly(self):
        time = 0x823aC

        key = generate_session_key(expires=time)
        id, timestamp = key.split('_')

        self.assertEqual(timestamp, '823ac')

    def test_ids_generated_unique(self):
        ids = set()

        for i in xrange(0,10**5):
            id, timestamp = generate_session_key().split('_')

            self.assertNotIn(id, ids)
            ids.add(id)

def create_app(store):
    app = Flask(__name__)

    KVSession(store, app)

    @app.route('/')
    def index():
        return 'nothing to see here, move along'

    @app.route('/store-in-session/<key>/<value>/')
    def store(key, value):
        session[key] = value
        return 'stored %r at %r' % (value, key)

    @app.route('/delete-from-session/<key>/')
    def delete(key):
        del session[key]
        return 'deleted %r' % key

    @app.route('/destroy-session/')
    def destroy():
        session.destroy()
        return 'session destroyed'

    @app.route('/dump-session/')
    def dump():
        return json.dumps(dict(session))

    return app

class TestSampleApp(unittest.TestCase):
    def setUp(self):
        self.store = DictStore()
        self.app = create_app(self.store)
        self.app.config['TESTING'] = True
        self.app.config['SECRET_KEY'] = 'devkey'

        self.client = self.app.test_client()

    def split_cookie(self, rv):
        cookie_data = rv.headers['Set-Cookie'].split(';', 1)[0]

        for cookie in cookie_data.split('&'):
            name, value = cookie_data.split('=')

            if name == self.app.session_cookie_name:
                return value.split('_')

    def test_app_setup(self):
        pass

    def test_app_request_no_extras(self):
        rv = self.client.get('/')

        self.assertIn('move along', rv.data)

    def test_no_session_usage_uses_no_storage(self):
        rv = self.client.get('/')
        rv2 = self.client.get('/')

        self.assertEqual({}, self.store.d)

    def test_session_usage(self):
        self.client.get('/store-in-session/foo/bar/')

        self.assertNotEqual({}, self.store.d)

    def test_proper_cookie_received(self):
        rv = self.client.get('/store-in-session/bar/baz/')

        sid, expires, hmac = self.split_cookie(rv)

        self.assertEqual(int(expires), 0)

        # check sid in store
        key = '%s_%s' % (sid, expires)

        self.assertIn(key, self.store)

    def test_session_restores_properly(self):
        rv = self.client.get('/store-in-session/k1/value1/')
        cookie = '_'.join(self.split_cookie(rv))

        rv = self.client.get('/store-in-session/k2/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')
        self.assertEqual(s['k2'], 'value2')

    def test_manipulation_caught(self):
        rv = self.client.get('/store-in-session/k1/value1/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')

        # now manipulate cookie
        cookie = self.client.cookie_jar.\
                 _cookies['localhost.local']['/']['session']
        v_orig = cookie.value

        for i in xrange(len(v_orig)):
            broken_value = v_orig[:i] +\
                           ('a' if v_orig[i] != 'a' else 'b') +\
                           v_orig[i+1:]
            cookie.value = broken_value

            rv = self.client.get('/dump-session/')
            s = json.loads(rv.data)

            self.assertEqual(s, {})

    def test_can_change_values(self):
        rv = self.client.get('/store-in-session/k1/value1/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')

        rv = self.client.get('/store-in-session/k1/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value2')

    def test_can_delete_values(self):
        rv = self.client.get('/store-in-session/k1/value1/')
        rv = self.client.get('/store-in-session/k2/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')
        self.assertEqual(s['k2'], 'value2')

        rv = self.client.get('/delete-from-session/k1/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertNotIn('k1', s)
        self.assertEqual(s['k2'], 'value2')

    def test_can_destroy_sessions(self):
        rv = self.client.get('/store-in-session/k1/value1/')
        rv = self.client.get('/store-in-session/k2/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')
        self.assertEqual(s['k2'], 'value2')

        # destroy session
        rv = self.client.get('/destroy-session/')
        self.assertIn('session destroyed', rv.data)

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s, {})

    def test_session_expires(self):
        raise NotImplementedError

    def test_session_cleanup_works(self):
        raise NotImplementedError
<commit_msg>Added session expiration test.<commit_after>#!/usr/bin/env python
# coding=utf8

from datetime import timedelta
import json
import sys

if sys.version_info < (2, 7):
    import unittest2 as unittest
else:
    import unittest

import time

from simplekv.memory import DictStore
from flask import Flask, session
from flaskext.kvsession import generate_session_key, KVSession

class TestGenerateSessionKey(unittest.TestCase):
    def test_id_well_formed(self):
        for i in xrange(0,100):
            key = generate_session_key(time.time())

            self.assertRegexpMatches(key, r'^[0-9a-f]+_[0-9a-f]+$')

    def test_non_expiring_id_has_timestamp_0(self):
        key = generate_session_key()
        id, timestamp = key.split('_')

        self.assertEqual(int(timestamp), 0)

    def test_timestamp_set_properly(self):
        time = 0x823aC

        key = generate_session_key(expires=time)
        id, timestamp = key.split('_')

        self.assertEqual(timestamp, '823ac')

    def test_ids_generated_unique(self):
        ids = set()

        for i in xrange(0,10**5):
            id, timestamp = generate_session_key().split('_')

            self.assertNotIn(id, ids)
            ids.add(id)

def create_app(store):
    app = Flask(__name__)

    KVSession(store, app)

    @app.route('/')
    def index():
        return 'nothing to see here, move along'

    @app.route('/store-in-session/<key>/<value>/')
    def store(key, value):
        session[key] = value
        return 'stored %r at %r' % (value, key)

    @app.route('/delete-from-session/<key>/')
    def delete(key):
        del session[key]
        return 'deleted %r' % key

    @app.route('/destroy-session/')
    def destroy():
        session.destroy()
        return 'session destroyed'

    @app.route('/make-session-permanent/')
    def make_permanent():
        session.permanent = True
        return 'made session permanent'

    @app.route('/dump-session/')
    def dump():
        return json.dumps(dict(session))

    return app

class TestSampleApp(unittest.TestCase):
    def setUp(self):
        self.store = DictStore()
        self.app = create_app(self.store)
        self.app.config['TESTING'] = True
        self.app.config['SECRET_KEY'] = 'devkey'

        self.client = self.app.test_client()

    def split_cookie(self, rv):
        cookie_data = rv.headers['Set-Cookie'].split(';', 1)[0]

        for cookie in cookie_data.split('&'):
            name, value = cookie_data.split('=')

            if name == self.app.session_cookie_name:
                return value.split('_')

    def test_app_setup(self):
        pass

    def test_app_request_no_extras(self):
        rv = self.client.get('/')

        self.assertIn('move along', rv.data)

    def test_no_session_usage_uses_no_storage(self):
        rv = self.client.get('/')
        rv2 = self.client.get('/')

        self.assertEqual({}, self.store.d)

    def test_session_usage(self):
        self.client.get('/store-in-session/foo/bar/')

        self.assertNotEqual({}, self.store.d)

    def test_proper_cookie_received(self):
        rv = self.client.get('/store-in-session/bar/baz/')

        sid, expires, hmac = self.split_cookie(rv)

        self.assertEqual(int(expires), 0)

        # check sid in store
        key = '%s_%s' % (sid, expires)

        self.assertIn(key, self.store)

    def test_session_restores_properly(self):
        rv = self.client.get('/store-in-session/k1/value1/')
        cookie = '_'.join(self.split_cookie(rv))

        rv = self.client.get('/store-in-session/k2/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')
        self.assertEqual(s['k2'], 'value2')

    def test_manipulation_caught(self):
        rv = self.client.get('/store-in-session/k1/value1/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')

        # now manipulate cookie
        cookie = self.client.cookie_jar.\
                 _cookies['localhost.local']['/']['session']
        v_orig = cookie.value

        for i in xrange(len(v_orig)):
            broken_value = v_orig[:i] +\
                           ('a' if v_orig[i] != 'a' else 'b') +\
                           v_orig[i+1:]
            cookie.value = broken_value

            rv = self.client.get('/dump-session/')
            s = json.loads(rv.data)

            self.assertEqual(s, {})

    def test_can_change_values(self):
        rv = self.client.get('/store-in-session/k1/value1/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')

        rv = self.client.get('/store-in-session/k1/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value2')

    def test_can_delete_values(self):
        rv = self.client.get('/store-in-session/k1/value1/')
        rv = self.client.get('/store-in-session/k2/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')
        self.assertEqual(s['k2'], 'value2')

        rv = self.client.get('/delete-from-session/k1/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertNotIn('k1', s)
        self.assertEqual(s['k2'], 'value2')

    def test_can_destroy_sessions(self):
        rv = self.client.get('/store-in-session/k1/value1/')
        rv = self.client.get('/store-in-session/k2/value2/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s['k1'], 'value1')
        self.assertEqual(s['k2'], 'value2')

        # destroy session
        rv = self.client.get('/destroy-session/')
        self.assertIn('session destroyed', rv.data)

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)

        self.assertEqual(s, {})

    def test_session_expires(self):
        # set expiration to 1 second
        self.app.permanent_session_lifetime = timedelta(seconds=1)

        rv = self.client.get('/store-in-session/k1/value1/')

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)
        self.assertEqual(s['k1'], 'value1')

        rv = self.client.get('/make-session-permanent/')

        # assert that the session has a non-zero timestamp
        sid, expires, mac = self.split_cookie(rv)

        self.assertNotEqual(0, int(expires,16))

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)
        self.assertEqual(s['k1'], 'value1')

        # sleep two seconds
        time.sleep(2)

        rv = self.client.get('/dump-session/')
        s = json.loads(rv.data)
        self.assertEqual(s, {})

    def test_session_cleanup_works(self):
        raise NotImplementedError
<|endoftext|>


<commit_before>import unittest
from hls_complete import get_completions
from hls_complete import update_completions
from hls_complete.update_completions import FileStatus

class TestGetCompletions(unittest.TestCase):

    def setUp(self):
        self.json = {
            "is_dir": True,
            "content": {
                "user": {
                    "is_dir": True,
                    "content": {
                        "recocomputer": {
                            "is_dir": True,
                            "content": {
                                "bestofs": {
                                    "is_dir": True,
                                    "content": {
                                        "richcatalog":{
                                            "is_dir": True,
                                            "content": {}}
                                    }
                                },
                                "dev": {
                                    "is_dir": True,
                                    "content": {
                                        "s.dolle": {
                                            "is_dir": True,
                                            "content": {
                                                "img.jpg": {
                                                    "is_dir": False
                                                }
                                            },
                                        },
                                        "s.yachaoui": {
                                            "is_dir": True,
                                            "content": {}
                                        },
                                        "b.delayen": {
                                             "is_dir": True,
                                            "content": {}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

    def test_nominal_case(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/s.", self.json)
        expected_result = ["/user/recocomputer/dev/s.dolle/", "/user/recocomputer/dev/s.yachaoui/"]
        self.assertEquals(expected_result, actual_result)

    def test_directory_case(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/", self.json)
        expected_result = ["/user/recocomputer/dev/b.delayen/", "/user/recocomputer/dev/s.dolle/", "/user/recocomputer/dev/s.yachaoui/"]
        self.assertEquals(expected_result, actual_result)

    def test_unexisting_directory(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/t", self.json)
        expected_result = []
        self.assertEquals(expected_result, actual_result)

    def test_too_long_path(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/s.dolle/toto", self.json)
        expected_result = []
        self.assertEquals(expected_result, actual_result)

    def test_root_only(self):
        actual_result = get_completions.get_completions(
                "/", self.json)
        expected_result = ["/user/"]
        self.assertEquals(expected_result, actual_result)

    def test_second_level(self):
        actual_result = get_completions.get_completions(
                "/user/re", self.json)
        expected_result = ["/user/recocomputer/"]
        self.assertEquals(expected_result, actual_result)

    def test_file_with_extension(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/s.dolle/im", self.json)
        expected_result = ["/user/recocomputer/dev/s.dolle/img.jpg"]
        self.assertEquals(expected_result, actual_result)

    def test_empty_json(self):
        actual_result = get_completions.get_completions(
                "/user", {})
        expected_result = []
        self.assertEquals(expected_result, actual_result)

class TestUpdateDirectory(unittest.TestCase):
    def setUp(self):
        #self.maxDiff = None
        self.json = {
            "is_dir": True,
            "content": {
                    "user": {
                        "is_dir": True,
                        "content": {
                            "recocomputer": {
                                "is_dir": True,
                                "content": {
                                    "bestofs": {
                                        "is_dir": True,
                                        "content": {
                                            "richcatalog": {
                                                "is_dir": True,
                                                "content": {}
                                                }
                                            }
                                        },
                                    "dev": {
                                        "is_dir": True,
                                        "content": {
                                            "s.dolle": {
                                                "is_dir": True,
                                                "content": {
                                                    "richcatalog": {"is_dir": True, "content": {}}}
                                                },
                                            "s.yachaoui": {"is_dir": True, "content": {}},
                                            "b.delayen": {"is_dir": True, "content": {}}
                                        }
                                    }
                                }
                            }
                        }
                    }
            }
        }

    def test_new_directory(self):
        update_completions.update_directory("/user/recocomputer/bestofs/ussrPV",
                [FileStatus("/user/recocomputer/bestofs/ussrPV/output1", True),
                    FileStatus("/user/recocomputer/bestofs/ussrPV/output2", True)],
                self.json)

        expected_cache = {
            "is_dir": True,
            "content": {
                    "user": {
                        "is_dir": True,
                        "content": {
                            "recocomputer": {
                                "is_dir": True,
                                "content": {
                                    "bestofs": {
                                        "is_dir": True,
                                        "content": {
                                            "richcatalog": {
                                                "is_dir": True,
                                                "content": {}
                                            },

                                            "ussrPV": {
                                                "is_dir": True,
                                                "content": {
                                                    "output1": {"is_dir": True, "content": {}},
                                                    "output2": {"is_dir": True, "content": {}}
                                                }
                                            }
                                        }
                                    },
                                    "dev": {
                                        "is_dir": True,
                                        "content": {
                                            "s.dolle": {
                                                "is_dir": True,
                                                "content": {
                                                    "richcatalog": {"is_dir": True, "content": {}}}
                                                },
                                            "s.yachaoui": {"is_dir": True, "content": {}},
                                            "b.delayen": {"is_dir": True, "content": {}}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

        self.assertEquals(expected_cache, self.json)

    def test_update_directory(self):
        update_completions.update_directory("/user/recocomputer/dev",
                [FileStatus("/user/recocomputer/dev/s.dolle", True),
                    FileStatus("/user/recocomputer/dev/s.yachaoui", True),
                    FileStatus("/user/recocomputer/dev/pe.mazare", True)],
                self.json)
        expected_cache = {
            "is_dir": True,
            "content": {
                    "user": {
                        "is_dir": True,
                        "content": {
                            "recocomputer": {
                                "is_dir": True,
                                "content": {
                                    "bestofs": {
                                        "is_dir": True,
                                        "content": {
                                            "richcatalog": {
                                                "is_dir": True,
                                                "content": {}
                                            },
                                        }
                                    },
                                    "dev": {
                                        "is_dir": True,
                                        "content": {
                                            "s.dolle": {
                                                "is_dir": True,
                                                "content": {
                                                    "richcatalog": {"is_dir": True, "content": {}}}
                                                },
                                            "s.yachaoui": {"is_dir": True, "content": {}},
                                            "pe.mazare": {"is_dir": True, "content": {}}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        self.assertEquals(expected_cache, self.json)

    def test_update_empty_cache(self):
        cache = {
            "is_dir": True,
            "content": {}
        }
        update_completions.update_directory("/user/recocomputer/dev",
                 [FileStatus("/user/recocomputer/dev/s.dolle", True),
                     FileStatus("/user/recocomputer/dev/s.yachaoui", True),
                     FileStatus("/user/recocomputer/dev/pe.mazare", True)],
                 cache)
        expected_cache = {
            "is_dir": True,
            "content": {
                "user": {
                    "is_dir": True,
                    "content": {
                        "recocomputer": {
                            "is_dir": True,
                            "content": {
                                "dev": {
                                    "is_dir": True,
                                    "content": {
                                        "s.dolle": {"is_dir": True, "content": {}},
                                        "s.yachaoui": {"is_dir": True, "content": {}},
                                        "pe.mazare": {"is_dir": True, "content": {}}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        self.assertEquals(expected_cache, cache)

class TestLsParser(unittest.TestCase):
    def test_nominal_case(self):
        parser = update_completions.LsParser()
        line = "drwx------+  8 simon  staff  272 27 dec  2015 /Users/simon/Music"
        self.assertEquals(update_completions.FileStatus("/Users/simon/Music", True), parser.parse_line(line))

    def test_file_case(self):
        parser = update_completions.LsParser()
        line = "-rwx------+  8 simon  staff  272 27 dec  2015 /Users/simon/Music"
        self.assertEquals(update_completions.FileStatus("/Users/simon/Music", False), parser.parse_line(line))

    def test_space_in_name(self):
        parser = update_completions.LsParser()
        line = "drwx------+  8 simon  staff  272 27 dec  2015 /Users/simon/Personal Documents"
        self.assertEquals(update_completions.FileStatus("/Users/simon/Personal Documents", True), parser.parse_line(line))

class TestSplitPath(unittest.TestCase):
    def test_nominal_case(self):
        self.assertEquals(["user", "s.dolle", "Music"], get_completions.split_path("/user/s.dolle/Music")
        self.assertEquals(["user", "s.dolle", "Music"], get_completions.split_path("/user/s.dolle/Music/")

class TestAppendSlash(unittest.TestCase):
    def test_nominal_case(self):
        self.assertEquals("user/s.dolle/Music/", get_completions.append_slash("/user/s.dolle/Music", True)
        self.assertEquals("user/s.dolle/Music", get_completions.append_slash("/user/s.dolle/Music", False)

if __name__ == '__main__':
    unittest.main()
<commit_msg>Close parentheses<commit_after>import unittest
from hls_complete import get_completions
from hls_complete import update_completions
from hls_complete.update_completions import FileStatus

class TestGetCompletions(unittest.TestCase):

    def setUp(self):
        self.json = {
            "is_dir": True,
            "content": {
                "user": {
                    "is_dir": True,
                    "content": {
                        "recocomputer": {
                            "is_dir": True,
                            "content": {
                                "bestofs": {
                                    "is_dir": True,
                                    "content": {
                                        "richcatalog":{
                                            "is_dir": True,
                                            "content": {}}
                                    }
                                },
                                "dev": {
                                    "is_dir": True,
                                    "content": {
                                        "s.dolle": {
                                            "is_dir": True,
                                            "content": {
                                                "img.jpg": {
                                                    "is_dir": False
                                                }
                                            },
                                        },
                                        "s.yachaoui": {
                                            "is_dir": True,
                                            "content": {}
                                        },
                                        "b.delayen": {
                                             "is_dir": True,
                                            "content": {}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

    def test_nominal_case(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/s.", self.json)
        expected_result = ["/user/recocomputer/dev/s.dolle/", "/user/recocomputer/dev/s.yachaoui/"]
        self.assertEquals(expected_result, actual_result)

    def test_directory_case(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/", self.json)
        expected_result = ["/user/recocomputer/dev/b.delayen/", "/user/recocomputer/dev/s.dolle/", "/user/recocomputer/dev/s.yachaoui/"]
        self.assertEquals(expected_result, actual_result)

    def test_unexisting_directory(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/t", self.json)
        expected_result = []
        self.assertEquals(expected_result, actual_result)

    def test_too_long_path(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/s.dolle/toto", self.json)
        expected_result = []
        self.assertEquals(expected_result, actual_result)

    def test_root_only(self):
        actual_result = get_completions.get_completions(
                "/", self.json)
        expected_result = ["/user/"]
        self.assertEquals(expected_result, actual_result)

    def test_second_level(self):
        actual_result = get_completions.get_completions(
                "/user/re", self.json)
        expected_result = ["/user/recocomputer/"]
        self.assertEquals(expected_result, actual_result)

    def test_file_with_extension(self):
        actual_result = get_completions.get_completions(
                "/user/recocomputer/dev/s.dolle/im", self.json)
        expected_result = ["/user/recocomputer/dev/s.dolle/img.jpg"]
        self.assertEquals(expected_result, actual_result)

    def test_empty_json(self):
        actual_result = get_completions.get_completions(
                "/user", {})
        expected_result = []
        self.assertEquals(expected_result, actual_result)

class TestUpdateDirectory(unittest.TestCase):
    def setUp(self):
        #self.maxDiff = None
        self.json = {
            "is_dir": True,
            "content": {
                    "user": {
                        "is_dir": True,
                        "content": {
                            "recocomputer": {
                                "is_dir": True,
                                "content": {
                                    "bestofs": {
                                        "is_dir": True,
                                        "content": {
                                            "richcatalog": {
                                                "is_dir": True,
                                                "content": {}
                                                }
                                            }
                                        },
                                    "dev": {
                                        "is_dir": True,
                                        "content": {
                                            "s.dolle": {
                                                "is_dir": True,
                                                "content": {
                                                    "richcatalog": {"is_dir": True, "content": {}}}
                                                },
                                            "s.yachaoui": {"is_dir": True, "content": {}},
                                            "b.delayen": {"is_dir": True, "content": {}}
                                        }
                                    }
                                }
                            }
                        }
                    }
            }
        }

    def test_new_directory(self):
        update_completions.update_directory("/user/recocomputer/bestofs/ussrPV",
                [FileStatus("/user/recocomputer/bestofs/ussrPV/output1", True),
                    FileStatus("/user/recocomputer/bestofs/ussrPV/output2", True)],
                self.json)

        expected_cache = {
            "is_dir": True,
            "content": {
                    "user": {
                        "is_dir": True,
                        "content": {
                            "recocomputer": {
                                "is_dir": True,
                                "content": {
                                    "bestofs": {
                                        "is_dir": True,
                                        "content": {
                                            "richcatalog": {
                                                "is_dir": True,
                                                "content": {}
                                            },

                                            "ussrPV": {
                                                "is_dir": True,
                                                "content": {
                                                    "output1": {"is_dir": True, "content": {}},
                                                    "output2": {"is_dir": True, "content": {}}
                                                }
                                            }
                                        }
                                    },
                                    "dev": {
                                        "is_dir": True,
                                        "content": {
                                            "s.dolle": {
                                                "is_dir": True,
                                                "content": {
                                                    "richcatalog": {"is_dir": True, "content": {}}}
                                                },
                                            "s.yachaoui": {"is_dir": True, "content": {}},
                                            "b.delayen": {"is_dir": True, "content": {}}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

        self.assertEquals(expected_cache, self.json)

    def test_update_directory(self):
        update_completions.update_directory("/user/recocomputer/dev",
                [FileStatus("/user/recocomputer/dev/s.dolle", True),
                    FileStatus("/user/recocomputer/dev/s.yachaoui", True),
                    FileStatus("/user/recocomputer/dev/pe.mazare", True)],
                self.json)
        expected_cache = {
            "is_dir": True,
            "content": {
                    "user": {
                        "is_dir": True,
                        "content": {
                            "recocomputer": {
                                "is_dir": True,
                                "content": {
                                    "bestofs": {
                                        "is_dir": True,
                                        "content": {
                                            "richcatalog": {
                                                "is_dir": True,
                                                "content": {}
                                            },
                                        }
                                    },
                                    "dev": {
                                        "is_dir": True,
                                        "content": {
                                            "s.dolle": {
                                                "is_dir": True,
                                                "content": {
                                                    "richcatalog": {"is_dir": True, "content": {}}}
                                                },
                                            "s.yachaoui": {"is_dir": True, "content": {}},
                                            "pe.mazare": {"is_dir": True, "content": {}}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        self.assertEquals(expected_cache, self.json)

    def test_update_empty_cache(self):
        cache = {
            "is_dir": True,
            "content": {}
        }
        update_completions.update_directory("/user/recocomputer/dev",
                 [FileStatus("/user/recocomputer/dev/s.dolle", True),
                     FileStatus("/user/recocomputer/dev/s.yachaoui", True),
                     FileStatus("/user/recocomputer/dev/pe.mazare", True)],
                 cache)
        expected_cache = {
            "is_dir": True,
            "content": {
                "user": {
                    "is_dir": True,
                    "content": {
                        "recocomputer": {
                            "is_dir": True,
                            "content": {
                                "dev": {
                                    "is_dir": True,
                                    "content": {
                                        "s.dolle": {"is_dir": True, "content": {}},
                                        "s.yachaoui": {"is_dir": True, "content": {}},
                                        "pe.mazare": {"is_dir": True, "content": {}}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        self.assertEquals(expected_cache, cache)

class TestLsParser(unittest.TestCase):
    def test_nominal_case(self):
        parser = update_completions.LsParser()
        line = "drwx------+  8 simon  staff  272 27 dec  2015 /Users/simon/Music"
        self.assertEquals(update_completions.FileStatus("/Users/simon/Music", True), parser.parse_line(line))

    def test_file_case(self):
        parser = update_completions.LsParser()
        line = "-rwx------+  8 simon  staff  272 27 dec  2015 /Users/simon/Music"
        self.assertEquals(update_completions.FileStatus("/Users/simon/Music", False), parser.parse_line(line))

    def test_space_in_name(self):
        parser = update_completions.LsParser()
        line = "drwx------+  8 simon  staff  272 27 dec  2015 /Users/simon/Personal Documents"
        self.assertEquals(update_completions.FileStatus("/Users/simon/Personal Documents", True), parser.parse_line(line))

class TestSplitPath(unittest.TestCase):
    def test_nominal_case(self):
        self.assertEquals(["user", "s.dolle", "Music"], get_completions.split_path("/user/s.dolle/Music"))
        self.assertEquals(["user", "s.dolle", "Music"], get_completions.split_path("/user/s.dolle/Music/"))

class TestAppendSlash(unittest.TestCase):
    def test_nominal_case(self):
        self.assertEquals("user/s.dolle/Music/", get_completions.append_slash("/user/s.dolle/Music", True))
        self.assertEquals("user/s.dolle/Music", get_completions.append_slash("/user/s.dolle/Music", False))

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


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

"""
test_infobox_scraper
----------------------------------

Tests for `infobox_scraper` module.
"""

try:
    import unittest2 as unittest
except ImportError:
    import unittest

from wikipediabase.infobox_scraper import DummyInfobox
from wikipediabase.util import get_dummy_infobox

class TestDummyInfobox(unittest.TestCase):

    def setUp(self):
        self.ibx = DummyInfobox('infobox_person')

    def test_musician(self):
        di = get_dummy_infobox('Template:Infobox musical artist')
        self.assertEqual(di.rendered_keys()['origin'], "Origin")

    def test_attributes(self):
        self.assertIn((u'Native\xa0name', '!!!!!native_name!!!!!'),
                      self.ibx.html_parsed())

    def test_rendered_keys(self):
        self.assertEqual(self.ibx.rendered_keys()['native_name'],
                         u'Native\xa0name')

    def tearDown(self):
        pass

if __name__ == '__main__':
    unittest.main()
<commit_msg>Changed last references to dummy infobox to be meta infobox<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
test_infobox_scraper
----------------------------------

Tests for `infobox_scraper` module.
"""

try:
    import unittest2 as unittest
except ImportError:
    import unittest

from wikipediabase.infobox_scraper import MetaInfobox
from wikipediabase.util import get_meta_infobox

class TestMetaInfobox(unittest.TestCase):

    def setUp(self):
        self.ibx = MetaInfobox('infobox_person')

    def test_musician(self):
        di = get_meta_infobox('Template:Infobox musical artist')
        self.assertEqual(di.rendered_keys()['origin'], "Origin")

    def test_attributes(self):
        self.assertIn((u'Native\xa0name', '!!!!!native_name!!!!!'),
                      self.ibx.html_parsed())

    def test_rendered_keys(self):
        self.assertEqual(self.ibx.rendered_keys()['native_name'],
                         u'Native\xa0name')

    def tearDown(self):
        pass

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>"""
Tests so called "in memory changesets" commit API of vcs.
"""
import vcs
import time
import datetime
import unittest2

from conf import SCM_TESTS, get_new_dir

from vcs.exceptions import EmptyRepositoryError
from vcs.exceptions import NodeAlreadyAddedError
from vcs.exceptions import NodeAlreadyExistsError
from vcs.exceptions import NodeAlreadyRemovedError
from vcs.exceptions import NodeAlreadyChangedError
from vcs.exceptions import NodeDoesNotExistError
from vcs.exceptions import NodeNotChangedError
from vcs.nodes import FileNode

class InMemoryChangesetTestMixin(object):
    """
    This is a backend independent test case class which should be created
    with ``type`` method.

    It is required to set following attributes at subclass:

    - ``backend_alias``: alias of used backend (see ``vcs.BACKENDS``)
    - ``repo_path``: path to the repository which would be created for set of
      tests
    """

    def get_backend(self):
        return vcs.get_backend(self.backend_alias)

    def setUp(self):
        Backend = self.get_backend()
        self.repo_path = get_new_dir(str(time.time()))
        self.repo = Backend(self.repo_path, create=True)
        self.imc = self.repo.in_memory_changeset
        self.nodes = [
            FileNode('foobar', content='Foo & bar'),
            FileNode('foobar2', content='Foo & bar, doubled!'),
            FileNode('foo bar with spaces', content=''),
            FileNode('foo/bar/baz', content='Inside'),
        ]

    def test_add(self):
        rev_count = len(self.repo.revisions)
        to_add = [FileNode(node.path, content=node.content)
            for node in self.nodes]
        self.imc.add(*to_add)
        message = 'Added newfile.txt and newfile2.txt'
        author = str(self.__class__)
        changeset = self.imc.commit(message=message, author=author)

        newtip = self.repo.get_changeset()
        self.assertEqual(changeset, newtip)
        self.assertEqual(rev_count + 1, len(self.repo.revisions))
        self.assertEqual(newtip.message, message)
        self.assertEqual(newtip.author, author)
        self.assertTrue(not any((self.imc.added, self.imc.changed,
            self.imc.removed)))
        for node in to_add:
            self.assertEqual(newtip.get_node(node.path).content, node.content)

    def test_add_raise_already_added(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.assertRaises(NodeAlreadyAddedError, self.imc.add, node)

    def test_check_integrity_raise_already_exist(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        self.imc.add(node)
        self.assertRaises(NodeAlreadyExistsError, self.imc.commit,
            message='new message',
            author=str(self))

    def test_change(self):
        self.test_add() # Performs first commit

        tip = self.repo.get_changeset()
        node = self.nodes[0]
        self.assertEqual(node.content, tip.get_node(node.path).content)

        # Change node's content
        node = FileNode(self.nodes[0].path, content='My **changed** content')
        self.imc.change(node)
        self.imc.commit(message='Changed %s' % node.path, author=str(self))

        newtip = self.repo.get_changeset()
        self.assertNotEqual(tip, newtip)
        self.assertNotEqual(tip.id, newtip.id)
        newnode = newtip.get_node(node.path)
        self.assertEqual(node.content, newnode.content)

    def test_change_raise_empty_repository(self):
        node = FileNode('foobar')
        self.assertRaises(EmptyRepositoryError, self.imc.change, node)

    def test_check_integrity_change_raise_node_does_not_exist(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        node = FileNode('not-foobar', content='')
        self.imc.change(node)
        self.assertRaises(NodeDoesNotExistError, self.imc.commit,
            message='Changed not existing node',
            author=str(self))

    def test_change_raise_node_already_changed(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        node = FileNode('foobar', content='more baz')
        self.imc.change(node)
        self.assertRaises(NodeAlreadyChangedError, self.imc.change, node)

    def test_check_integrity_change_raise_node_not_changed(self):
        self.test_add() # Performs first commit

        node = FileNode(self.nodes[0].path, content=self.nodes[0].content)
        self.imc.change(node)
        self.assertRaises(NodeNotChangedError, self.imc.commit,
            message='Trying to mark node as changed without touching it',
            author=str(self))

    def test_change_raise_node_already_removed(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        self.imc.remove(FileNode('foobar'))
        self.assertRaises(NodeAlreadyRemovedError, self.imc.change, node)

    def test_remove(self):
        self.test_add() # Performs first commit

        tip = self.repo.get_changeset()
        node = self.nodes[0]
        self.assertEqual(node.content, tip.get_node(node.path).content)
        self.imc.remove(node)
        self.imc.commit(message='Removed %s' % node.path, author=str(self))

        newtip = self.repo.get_changeset()
        self.assertNotEqual(tip, newtip)
        self.assertNotEqual(tip.id, newtip.id)
        self.assertRaises(NodeDoesNotExistError, newtip.get_node, node.path)

    def test_remove_raise_node_does_not_exist(self):
        self.imc.remove(self.nodes[0])
        self.assertRaises(NodeDoesNotExistError, self.imc.commit,
            message='Trying to remove node at empty repository',
            author=str(self))

    def test_check_integrity_remove_raise_node_does_not_exist(self):
        self.test_add() # Performs first commit

        node = FileNode('no-such-file')
        self.imc.remove(node)
        self.assertRaises(NodeDoesNotExistError, self.imc.commit,
            message='Trying to remove not existing node',
            author=str(self))

    def test_remove_raise_node_already_removed(self):
        self.test_add() # Performs first commit

        node = FileNode(self.nodes[0].path)
        self.imc.remove(node)
        self.assertRaises(NodeAlreadyRemovedError, self.imc.remove, node)

    def test_remove_raise_node_already_changed(self):
        self.test_add() # Performs first commit

        node = FileNode(self.nodes[0].path, content='Bending time')
        self.imc.change(node)
        self.assertRaises(NodeAlreadyChangedError, self.imc.remove, node)

    def test_reset(self):
        self.imc.add(FileNode('foo', content='bar'))
        #self.imc.change(FileNode('baz', content='new'))
        #self.imc.remove(FileNode('qwe'))
        self.imc.reset()
        self.assertTrue(not any((self.imc.added, self.imc.changed,
            self.imc.removed)))

    def test_multiple_commits(self):
        N = 3 # number of commits to perform
        last = None
        for x in xrange(N):
            fname = 'file%s' % str(x).rjust(5, '0')
            content = 'foobar\n' * x
            node = FileNode(fname, content=content)
            self.imc.add(node)
            commit = self.imc.commit("Commit no. %s" % (x + 1), author='vcs')
            self.assertTrue(last != commit)
            last = commit

        # Check commit number for same repo
        self.assertEqual(len(self.repo.revisions), N)

        # Check commit number for recreated repo
        backend = self.get_backend()
        repo = backend(self.repo_path)
        self.assertEqual(len(repo.revisions), N)

    def test_date_attr(self):
        node = FileNode('foobar.txt', content='Foobared!')
        self.imc.add(node)
        date = datetime.datetime(1985, 1, 30, 1, 45)
        commit = self.imc.commit("Committed at time when I was born ;-)",
            author='lb', date=date)

        self.assertEqual(commit.date, date)

class BackendBaseTestCase(unittest2.TestCase):
    """
    Base test class for tests which requires repository.
    """
    backend_alias = 'hg'
    commits = [
        {
            'message': 'Initial commit',
            'author': 'Joe Doe <joe.doe@example.com>',
            'date': datetime.datetime(2010, 1, 1, 20),
            'added': [
                FileNode('foobar', content='Foobar'),
                FileNode('foobar2', content='Foobar II'),
                FileNode('foo/bar/baz', content='baz here!'),
            ],
        },
    ]

    def get_backend(self):
        return vcs.get_backend(self.backend_alias)

    def get_commits(self):
        """
        Returns list of commits which builds repository for each tests.
        """
        if hasattr(self, 'commits'):
            return self.commits

    def get_new_repo_path(self):
        """
        Returns newly created repository's directory.
        """
        backend = self.get_backend()
        key = '%s-%s' % (backend.alias, str(time.time()))
        repo_path = get_new_dir(key)
        return repo_path

    def setUp(self):
        Backend = self.get_backend()
        self.backend_class = Backend
        self.repo_path = self.get_new_repo_path()
        self.repo = Backend(self.repo_path, create=True)
        self.imc = self.repo.in_memory_changeset

        for commit in self.get_commits():
            for node in commit.get('added', []):
                self.imc.add(FileNode(node.path, content=node.content))
            for node in commit.get('changed', []):
                self.imc.change(FileNode(node.path, content=node.content))
            for node in commit.get('removed', []):
                self.imc.remove(FileNode(node.path))
            self.imc.commit(message=commit['message'], author=commit['author'],
                date=commit['date'])

        self.tip = self.repo.get_changeset()

# For each backend create test case class
for alias in SCM_TESTS:
    attrs = {
        'backend_alias': alias,
    }
    cls_name = ''.join(('%s in memory changeset test' % alias).title().split())
    bases = (InMemoryChangesetTestMixin, unittest2.TestCase)
    globals()[cls_name] = type(cls_name, bases, attrs)

if __name__ == '__main__':
    unittest2.main()

<commit_msg>Splitted in-memory-changeset add tests into normal and 'in bulk'<commit_after>"""
Tests so called "in memory changesets" commit API of vcs.
"""
import vcs
import time
import datetime
import unittest2

from conf import SCM_TESTS, get_new_dir

from vcs.exceptions import EmptyRepositoryError
from vcs.exceptions import NodeAlreadyAddedError
from vcs.exceptions import NodeAlreadyExistsError
from vcs.exceptions import NodeAlreadyRemovedError
from vcs.exceptions import NodeAlreadyChangedError
from vcs.exceptions import NodeDoesNotExistError
from vcs.exceptions import NodeNotChangedError
from vcs.nodes import FileNode

class InMemoryChangesetTestMixin(object):
    """
    This is a backend independent test case class which should be created
    with ``type`` method.

    It is required to set following attributes at subclass:

    - ``backend_alias``: alias of used backend (see ``vcs.BACKENDS``)
    - ``repo_path``: path to the repository which would be created for set of
      tests
    """

    def get_backend(self):
        return vcs.get_backend(self.backend_alias)

    def setUp(self):
        Backend = self.get_backend()
        self.repo_path = get_new_dir(str(time.time()))
        self.repo = Backend(self.repo_path, create=True)
        self.imc = self.repo.in_memory_changeset
        self.nodes = [
            FileNode('foobar', content='Foo & bar'),
            FileNode('foobar2', content='Foo & bar, doubled!'),
            FileNode('foo bar with spaces', content=''),
            FileNode('foo/bar/baz', content='Inside'),
        ]

    def test_add(self):
        rev_count = len(self.repo.revisions)
        to_add = [FileNode(node.path, content=node.content)
            for node in self.nodes]
        for node in to_add:
            self.imc.add(node)
        message = 'Added: %s' % ', '.join((node.path for node in self.nodes))
        author = str(self.__class__)
        changeset = self.imc.commit(message=message, author=author)

        newtip = self.repo.get_changeset()
        self.assertEqual(changeset, newtip)
        self.assertEqual(rev_count + 1, len(self.repo.revisions))
        self.assertEqual(newtip.message, message)
        self.assertEqual(newtip.author, author)
        self.assertTrue(not any((self.imc.added, self.imc.changed,
            self.imc.removed)))
        for node in to_add:
            self.assertEqual(newtip.get_node(node.path).content, node.content)

    def test_add_in_bulk(self):
        rev_count = len(self.repo.revisions)
        to_add = [FileNode(node.path, content=node.content)
            for node in self.nodes]
        self.imc.add(*to_add)
        message = 'Added: %s' % ', '.join((node.path for node in self.nodes))
        author = str(self.__class__)
        changeset = self.imc.commit(message=message, author=author)

        newtip = self.repo.get_changeset()
        self.assertEqual(changeset, newtip)
        self.assertEqual(rev_count + 1, len(self.repo.revisions))
        self.assertEqual(newtip.message, message)
        self.assertEqual(newtip.author, author)
        self.assertTrue(not any((self.imc.added, self.imc.changed,
            self.imc.removed)))
        for node in to_add:
            self.assertEqual(newtip.get_node(node.path).content, node.content)

    def test_add_raise_already_added(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.assertRaises(NodeAlreadyAddedError, self.imc.add, node)

    def test_check_integrity_raise_already_exist(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        self.imc.add(node)
        self.assertRaises(NodeAlreadyExistsError, self.imc.commit,
            message='new message',
            author=str(self))

    def test_change(self):
        self.test_add() # Performs first commit

        tip = self.repo.get_changeset()
        node = self.nodes[0]
        self.assertEqual(node.content, tip.get_node(node.path).content)

        # Change node's content
        node = FileNode(self.nodes[0].path, content='My **changed** content')
        self.imc.change(node)
        self.imc.commit(message='Changed %s' % node.path, author=str(self))

        newtip = self.repo.get_changeset()
        self.assertNotEqual(tip, newtip)
        self.assertNotEqual(tip.id, newtip.id)
        newnode = newtip.get_node(node.path)
        self.assertEqual(node.content, newnode.content)

    def test_change_raise_empty_repository(self):
        node = FileNode('foobar')
        self.assertRaises(EmptyRepositoryError, self.imc.change, node)

    def test_check_integrity_change_raise_node_does_not_exist(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        node = FileNode('not-foobar', content='')
        self.imc.change(node)
        self.assertRaises(NodeDoesNotExistError, self.imc.commit,
            message='Changed not existing node',
            author=str(self))

    def test_change_raise_node_already_changed(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        node = FileNode('foobar', content='more baz')
        self.imc.change(node)
        self.assertRaises(NodeAlreadyChangedError, self.imc.change, node)

    def test_check_integrity_change_raise_node_not_changed(self):
        self.test_add() # Performs first commit

        node = FileNode(self.nodes[0].path, content=self.nodes[0].content)
        self.imc.change(node)
        self.assertRaises(NodeNotChangedError, self.imc.commit,
            message='Trying to mark node as changed without touching it',
            author=str(self))

    def test_change_raise_node_already_removed(self):
        node = FileNode('foobar', content='baz')
        self.imc.add(node)
        self.imc.commit(message='Added foobar', author=str(self))
        self.imc.remove(FileNode('foobar'))
        self.assertRaises(NodeAlreadyRemovedError, self.imc.change, node)

    def test_remove(self):
        self.test_add() # Performs first commit

        tip = self.repo.get_changeset()
        node = self.nodes[0]
        self.assertEqual(node.content, tip.get_node(node.path).content)
        self.imc.remove(node)
        self.imc.commit(message='Removed %s' % node.path, author=str(self))

        newtip = self.repo.get_changeset()
        self.assertNotEqual(tip, newtip)
        self.assertNotEqual(tip.id, newtip.id)
        self.assertRaises(NodeDoesNotExistError, newtip.get_node, node.path)

    def test_remove_raise_node_does_not_exist(self):
        self.imc.remove(self.nodes[0])
        self.assertRaises(NodeDoesNotExistError, self.imc.commit,
            message='Trying to remove node at empty repository',
            author=str(self))

    def test_check_integrity_remove_raise_node_does_not_exist(self):
        self.test_add() # Performs first commit

        node = FileNode('no-such-file')
        self.imc.remove(node)
        self.assertRaises(NodeDoesNotExistError, self.imc.commit,
            message='Trying to remove not existing node',
            author=str(self))

    def test_remove_raise_node_already_removed(self):
        self.test_add() # Performs first commit

        node = FileNode(self.nodes[0].path)
        self.imc.remove(node)
        self.assertRaises(NodeAlreadyRemovedError, self.imc.remove, node)

    def test_remove_raise_node_already_changed(self):
        self.test_add() # Performs first commit

        node = FileNode(self.nodes[0].path, content='Bending time')
        self.imc.change(node)
        self.assertRaises(NodeAlreadyChangedError, self.imc.remove, node)

    def test_reset(self):
        self.imc.add(FileNode('foo', content='bar'))
        #self.imc.change(FileNode('baz', content='new'))
        #self.imc.remove(FileNode('qwe'))
        self.imc.reset()
        self.assertTrue(not any((self.imc.added, self.imc.changed,
            self.imc.removed)))

    def test_multiple_commits(self):
        N = 3 # number of commits to perform
        last = None
        for x in xrange(N):
            fname = 'file%s' % str(x).rjust(5, '0')
            content = 'foobar\n' * x
            node = FileNode(fname, content=content)
            self.imc.add(node)
            commit = self.imc.commit("Commit no. %s" % (x + 1), author='vcs')
            self.assertTrue(last != commit)
            last = commit

        # Check commit number for same repo
        self.assertEqual(len(self.repo.revisions), N)

        # Check commit number for recreated repo
        backend = self.get_backend()
        repo = backend(self.repo_path)
        self.assertEqual(len(repo.revisions), N)

    def test_date_attr(self):
        node = FileNode('foobar.txt', content='Foobared!')
        self.imc.add(node)
        date = datetime.datetime(1985, 1, 30, 1, 45)
        commit = self.imc.commit("Committed at time when I was born ;-)",
            author='lb', date=date)

        self.assertEqual(commit.date, date)

class BackendBaseTestCase(unittest2.TestCase):
    """
    Base test class for tests which requires repository.
    """
    backend_alias = 'hg'
    commits = [
        {
            'message': 'Initial commit',
            'author': 'Joe Doe <joe.doe@example.com>',
            'date': datetime.datetime(2010, 1, 1, 20),
            'added': [
                FileNode('foobar', content='Foobar'),
                FileNode('foobar2', content='Foobar II'),
                FileNode('foo/bar/baz', content='baz here!'),
            ],
        },
    ]

    def get_backend(self):
        return vcs.get_backend(self.backend_alias)

    def get_commits(self):
        """
        Returns list of commits which builds repository for each tests.
        """
        if hasattr(self, 'commits'):
            return self.commits

    def get_new_repo_path(self):
        """
        Returns newly created repository's directory.
        """
        backend = self.get_backend()
        key = '%s-%s' % (backend.alias, str(time.time()))
        repo_path = get_new_dir(key)
        return repo_path

    def setUp(self):
        Backend = self.get_backend()
        self.backend_class = Backend
        self.repo_path = self.get_new_repo_path()
        self.repo = Backend(self.repo_path, create=True)
        self.imc = self.repo.in_memory_changeset

        for commit in self.get_commits():
            for node in commit.get('added', []):
                self.imc.add(FileNode(node.path, content=node.content))
            for node in commit.get('changed', []):
                self.imc.change(FileNode(node.path, content=node.content))
            for node in commit.get('removed', []):
                self.imc.remove(FileNode(node.path))
            self.imc.commit(message=commit['message'], author=commit['author'],
                date=commit['date'])

        self.tip = self.repo.get_changeset()

# For each backend create test case class
for alias in SCM_TESTS:
    attrs = {
        'backend_alias': alias,
    }
    cls_name = ''.join(('%s in memory changeset test' % alias).title().split())
    bases = (InMemoryChangesetTestMixin, unittest2.TestCase)
    globals()[cls_name] = type(cls_name, bases, attrs)

if __name__ == '__main__':
    unittest2.main()

<|endoftext|>


<commit_before>#
# Author    : Manuel Bernal Llinares
# Project   : trackhub-creator
# Timestamp : 13-09-2017 13:10
# ---
# © 2017 Manuel Bernal Llinares <mbdebian@gmail.com>
# All rights reserved.
#

"""
Document your module here
"""<commit_msg>unit tests for the parallelization module, documentation<commit_after>#
# Author    : Manuel Bernal Llinares
# Project   : trackhub-creator
# Timestamp : 13-09-2017 13:10
# ---
# © 2017 Manuel Bernal Llinares <mbdebian@gmail.com>
# All rights reserved.
#

"""
Unit tests for the parallelization module
"""<|endoftext|>