import os
import itertools

import numpy as np
import pytest

from PIL import Image

from utils.filters import Noop, GaussianBlur, GaussianNoise, UniformNoise, \
                          Vignette


@pytest.fixture()
def image(scope='module'):
    image_path = os.path.join(os.path.dirname(__file__), 'lena.jpg')
    return Image.open(image_path)


GAUSSIAN_BLUR_PARAMS = [1, 2, 5]
GAUSSIAN_NOISE_PARAMS = list(itertools.product(
    (0.1, 0.5, 0.9),
    (0, 128, 255),
    (10, 100, 200)))
UNIFORM_NOISE_PARAMS = [0.1, 0.5, 0.9]
VIGNETTE_PARAMS = [
    ((0, 0, 0), 0.5),
    ((255, 255, 255), 0.75)]


# Very basic test to check if a filter changes anything in
# an image
@pytest.mark.parametrize("filter_instance",
        [GaussianBlur(radius) for radius in GAUSSIAN_BLUR_PARAMS] +
        [GaussianNoise(alpha, loc, scale)
            for alpha, loc, scale in GAUSSIAN_NOISE_PARAMS] +
        [UniformNoise(alpha) for alpha in UNIFORM_NOISE_PARAMS] +
        [Vignette(alpha, color) for alpha, color in VIGNETTE_PARAMS])
def test_filter_changes_image(filter_instance, image):
    image_after_filter = filter_instance.apply(image)
    assert image.tobytes() != image_after_filter.tobytes()


import os
import itertools

import numpy as np
import pytest

from PIL import Image

from utils.filters import Noop, GaussianBlur, GaussianNoise, UniformNoise, \
                          Vignette


@pytest.fixture()
def image(scope='module'):
    image_path = os.path.join(os.path.dirname(__file__), 'lena.jpg')
    return Image.open(image_path)


FILTER_PARAMETER_SETS = {
    # Noop: [()],
    GaussianBlur: [1, 2, 5],
    GaussianNoise: itertools.product(
        (0.1, 0.5, 0.9),
        (0, 128, 255),
        (10, 100, 200)),
    UniformNoise: [0.1, 0.5, 0.9],
    Vignette: [
        ((0, 0, 0), 0.5),
        ((255, 255, 255), 0.75)],
}


def generate_filter_instances(filter_param_sets):
    """
    Generate a list of filters instantiated with corresponding
    params from filter_param_sets
    """
    filter_instances = []
    for filter_class, param_set in filter_param_sets.items():
        batch = []
        for params in param_set:
            try:
                len(params)
            except TypeError:
                params = [params]
            batch.append(filter_class(*params))
        filter_instances.extend(batch)
    return filter_instances


# Very basic test to check if a filter changes anything in
# an image
@pytest.mark.parametrize("filter_instance",
        generate_filter_instances(FILTER_PARAMETER_SETS))
def test_filter_changes_image(filter_instance, image):
    image_after_filter = filter_instance.apply(image)
    assert image.tobytes() != image_after_filter.tobytes()


Refactor tests