Ejemplo n.º 1
0
    def setUp(self):
        self.original_root_communication_channel_parameter_space = SimpleHypergrid(
            name='communication_channel_parameter_space',
            dimensions=[
                DiscreteDimension(name='num_readers', min=1, max=64),
                DiscreteDimension(name='log2_buffer_size', min=10, max=24),
                CategoricalDimension(name='use_emergency_buffer',
                                     values=[True, False])
            ])

        self.original_emergency_buffer_settings = SimpleHypergrid(
            name='emergency_buffer_config',
            dimensions=[
                DiscreteDimension(name='log2_emergency_buffer_size',
                                  min=0,
                                  max=16),
                CategoricalDimension(name='use_colors', values=[True, False])
            ])

        self.original_emergency_buffer_color = SimpleHypergrid(
            name='emergency_buffer_color',
            dimensions=[
                CategoricalDimension(name='color',
                                     values=['Maroon', 'Crimson', 'Tanager'])
            ])

        self.original_emergency_buffer_settings_with_color = self.original_emergency_buffer_settings.join(
            subgrid=self.original_emergency_buffer_color,
            on_external_dimension=CategoricalDimension(name='use_colors',
                                                       values=[True]))

        self.original_hierarchical_settings = self.original_root_communication_channel_parameter_space.join(
            subgrid=self.original_emergency_buffer_settings_with_color,
            on_external_dimension=CategoricalDimension(
                name='use_emergency_buffer', values=[True]),
        )

        self.root_communication_channel_parameter_space = json.loads(
            json.dumps(
                self.original_root_communication_channel_parameter_space,
                cls=HypergridJsonEncoder),
            cls=HypergridJsonDecoder)
        self.emergency_buffer_settings = json.loads(json.dumps(
            self.original_emergency_buffer_settings, cls=HypergridJsonEncoder),
                                                    cls=HypergridJsonDecoder)
        self.emergency_buffer_color = json.loads(json.dumps(
            self.original_emergency_buffer_color, cls=HypergridJsonEncoder),
                                                 cls=HypergridJsonDecoder)
        self.emergency_buffer_settings_with_color = json.loads(
            json.dumps(self.original_emergency_buffer_settings_with_color,
                       cls=HypergridJsonEncoder),
            cls=HypergridJsonDecoder)
        self.hierarchical_settings = json.loads(json.dumps(
            self.original_hierarchical_settings, cls=HypergridJsonEncoder),
                                                cls=HypergridJsonDecoder)
Ejemplo n.º 2
0
 def setup_method(self, method):
     self.empty = ContinuousDimension(name='x',
                                      min=0,
                                      max=0,
                                      include_min=False,
                                      include_max=False)
     self.unbounded_continuous = ContinuousDimension(name='x',
                                                     min=0,
                                                     max=math.inf)
     self.unbounded_discrete = DiscreteDimension(name='x',
                                                 min=0,
                                                 max=math.inf)
     self.should_be_empty = ContinuousDimension(name='x',
                                                min=0,
                                                max=0,
                                                include_min=False,
                                                include_max=True)
     self.should_be_empty_too = ContinuousDimension(name='x',
                                                    min=0,
                                                    max=0,
                                                    include_min=True,
                                                    include_max=False)
     self.should_contain_zero = ContinuousDimension(name='x',
                                                    min=0,
                                                    max=0,
                                                    include_min=True,
                                                    include_max=True)
     self.closed = ContinuousDimension(name='x', min=0, max=1)
     self.left_open = ContinuousDimension(name='x',
                                          min=0,
                                          max=1,
                                          include_min=False)
     self.right_open = ContinuousDimension(name='x',
                                           min=0,
                                           max=1,
                                           include_max=False)
     self.open = ContinuousDimension(name='x',
                                     min=0,
                                     max=1,
                                     include_min=False,
                                     include_max=False)
     self.inner = ContinuousDimension(name='x', min=0.2, max=0.8)
     self.outer = ContinuousDimension(name='x', min=-0.2, max=1.2)
     self.left_overlapping = ContinuousDimension(name='x',
                                                 min=-0.2,
                                                 max=0.8)
     self.right_overlapping = ContinuousDimension(name='x',
                                                  min=0.2,
                                                  max=1.2)
     self.inner_wrongly_named = ContinuousDimension(name='y',
                                                    min=0.2,
                                                    max=0.8)
     self.one_to_five = ContinuousDimension(name='x', min=1, max=5)
     self.six_to_ten = ContinuousDimension(name='x', min=6, max=10)
Ejemplo n.º 3
0
    def test_composition_of_arbitrary_dimensions(self):
        C1 = ContinuousDimension(name='x', min=0, max=1)
        C2 = ContinuousDimension(name='x', min=1, max=2)
        C3 = C1 - C2
        D = DiscreteDimension(name='x', min=0, max=1)

        with pytest.raises(TypeError):
            C1.intersection(D)
        with pytest.raises(TypeError):
            C3.intersection(D)
        with pytest.raises(TypeError):
            D.intersection(C1)
Ejemplo n.º 4
0
    def setup_method(self, method) -> None:
        self.small_square = SimpleHypergrid(name="small_square",
                                            dimensions=[
                                                ContinuousDimension(name='x',
                                                                    min=1,
                                                                    max=2),
                                                ContinuousDimension(name='y',
                                                                    min=1,
                                                                    max=2)
                                            ])

        self.big_square = SimpleHypergrid(name="big_square",
                                          dimensions=[
                                              ContinuousDimension(name='x',
                                                                  min=0,
                                                                  max=3),
                                              ContinuousDimension(name='y',
                                                                  min=0,
                                                                  max=3)
                                          ])

        self.small_grid = SimpleHypergrid(name="small_grid",
                                          dimensions=[
                                              DiscreteDimension(name='x',
                                                                min=1,
                                                                max=2),
                                              DiscreteDimension(name='y',
                                                                min=1,
                                                                max=2)
                                          ])

        self.big_grid = SimpleHypergrid(name="big_grid",
                                        dimensions=[
                                            DiscreteDimension(name='x',
                                                              min=0,
                                                              max=3),
                                            DiscreteDimension(name='y',
                                                              min=0,
                                                              max=3),
                                            DiscreteDimension(name='z',
                                                              min=0,
                                                              max=3)
                                        ])

        self.all_grids = [
            self.small_square,
            self.big_square,
            self.small_grid,
            self.big_grid,
        ]
Ejemplo n.º 5
0
    def test_composition_of_arbitrary_dimensions(self):
        C1 = ContinuousDimension(name='x', min=0, max=1)
        C2 = ContinuousDimension(name='x', min=1, max=2)
        C3 = C1 - C2
        D = DiscreteDimension(name='x', min=0, max=1)

        self.assertRaises(TypeError, C1.intersection, D)
        self.assertRaises(TypeError, C3.intersection, D)
        self.assertRaises(TypeError, D.intersection, C1)
Ejemplo n.º 6
0
    def test_containment(self):
        long_segment = ContinuousDimension(name='x', min=0, max=100 * 1000)
        short_segment = ContinuousDimension(name='x', min=0, max=100)

        long_linear_sequence = DiscreteDimension(name='x',
                                                 min=0,
                                                 max=100 * 1000)
        short_linear_sequence = DiscreteDimension(name='x',
                                                  min=0,
                                                  max=100 * 1000)

        long_fibonacci_sequence = OrdinalDimension(
            name='x',
            ordered_values=[i for i in fibonacci(max=100 * 1000)],
            ascending=True)

        short_fibonacci_sequence = OrdinalDimension(
            name='x',
            ordered_values=[i for i in fibonacci(max=100)],
            ascending=True)

        a_few_options = CategoricalDimension(name='x', values=[5, 13, 34])

        boolean_choice = CategoricalDimension(name='x', values=[True, False])

        for dimension in [
                short_segment, long_linear_sequence, short_linear_sequence,
                long_fibonacci_sequence, short_fibonacci_sequence,
                a_few_options
        ]:
            self.assertTrue(dimension in long_segment)

        self.assertTrue(short_fibonacci_sequence in long_fibonacci_sequence)
        self.assertTrue(a_few_options in short_fibonacci_sequence)
        self.assertTrue(True in boolean_choice)
        self.assertTrue(12 in long_segment)
Ejemplo n.º 7
0
    def setup_method(self, method):
        self.just_one = DiscreteDimension(name='x', min=1, max=1)
        self.one_two = DiscreteDimension(name='x', min=1, max=2)
        self.one_two_three = DiscreteDimension(name='x', min=1, max=3)
        self.one_two_three_four = DiscreteDimension(name='x', min=1, max=4)
        self.one_to_hundred = DiscreteDimension(name='x', min=1, max=100)

        self.all_dims = [
            self.just_one,
            self.one_two,
            self.one_two_three,
            self.one_two_three_four,
            self.one_to_hundred,
        ]
Ejemplo n.º 8
0
    def setUp(self):
        self.just_one = DiscreteDimension(name='x', min=1, max=1)
        self.one_two = DiscreteDimension(name='x', min=1, max=2)
        self.one_two_three = DiscreteDimension(name='x', min=1, max=3)
        self.one_to_hundred = DiscreteDimension(name='x', min=1, max=100)
        #self.even_one_to_hundred = DiscreteDimension(name='x', min=2, max=100, stride=2)
        #self.odd_one_to_hundred = DiscreteDimension(name='x', min=1, max=99, stride=2)
        #self.divisible_by_three_one_to_hundred = DiscreteDimension(name='x', min=3, max=99, stride=3)
        #self.divisible_by_six_one_to_hundred = DiscreteDimension(name='x', min=6, max=96, stride=6)

        self.all_dims = [
            self.just_one,
            self.one_two,
            self.one_two_three,
            self.one_to_hundred,
            #self.even_one_to_hundred,
            #self.odd_one_to_hundred,
            #self.divisible_by_three_one_to_hundred,
            #self.divisible_by_six_one_to_hundred
        ]
Ejemplo n.º 9
0
class TestDiscreteDimension(unittest.TestCase):
    def setUp(self):
        self.just_one = DiscreteDimension(name='x', min=1, max=1)
        self.one_two = DiscreteDimension(name='x', min=1, max=2)
        self.one_two_three = DiscreteDimension(name='x', min=1, max=3)
        self.one_to_hundred = DiscreteDimension(name='x', min=1, max=100)
        #self.even_one_to_hundred = DiscreteDimension(name='x', min=2, max=100, stride=2)
        #self.odd_one_to_hundred = DiscreteDimension(name='x', min=1, max=99, stride=2)
        #self.divisible_by_three_one_to_hundred = DiscreteDimension(name='x', min=3, max=99, stride=3)
        #self.divisible_by_six_one_to_hundred = DiscreteDimension(name='x', min=6, max=96, stride=6)

        self.all_dims = [
            self.just_one,
            self.one_two,
            self.one_two_three,
            self.one_to_hundred,
            #self.even_one_to_hundred,
            #self.odd_one_to_hundred,
            #self.divisible_by_three_one_to_hundred,
            #self.divisible_by_six_one_to_hundred
        ]

    def test_string_representation(self):
        self.assertTrue(str(self.just_one) == "x: {1}")
        self.assertTrue(str(self.one_two) == "x: {1, 2}")
        self.assertTrue(str(self.one_two_three) == "x: {1, 2, 3}")
        self.assertTrue(str(self.one_to_hundred) == "x: {1, 2, 3, ... , 100}")
        #self.assertTrue(str(self.even_one_to_hundred) == "x: {2, 2 + 2, ... , 100}")
        #self.assertTrue(str(self.odd_one_to_hundred) == "x: {1, 1 + 2, ... , 99}")
        #self.assertTrue(str(self.divisible_by_three_one_to_hundred) == "x: {3, 3 + 3, ... , 99}")

    def test_point_containment(self):
        self.assertTrue(1 in self.just_one)

        #self.assertTrue(2 in self.even_one_to_hundred)
        #self.assertTrue(20 in self.even_one_to_hundred)
        #self.assertTrue(100 in self.even_one_to_hundred)
        #self.assertTrue(7 not in self.even_one_to_hundred)
        #self.assertTrue(-1 not in self.even_one_to_hundred)
        #self.assertTrue(102 not in self.even_one_to_hundred)

        #self.assertTrue(3 in self.divisible_by_three_one_to_hundred)
        #self.assertTrue(66 in self.divisible_by_three_one_to_hundred)
        #self.assertTrue(99 in self.divisible_by_three_one_to_hundred)

    def test_discrete_dimension_containment(self):
        self.assertTrue(self.just_one in self.one_two)
        self.assertTrue(self.just_one in self.one_two_three)
        #self.assertTrue(self.even_one_to_hundred in self.one_to_hundred)
        #self.assertTrue(self.odd_one_to_hundred in self.one_to_hundred)
        #self.assertTrue(self.divisible_by_three_one_to_hundred in self.one_to_hundred)
        #self.assertTrue(self.divisible_by_six_one_to_hundred in self.divisible_by_three_one_to_hundred)
        #self.assertTrue(self.divisible_by_six_one_to_hundred in self.even_one_to_hundred)
        #self.assertTrue(self.divisible_by_three_one_to_hundred not in self.odd_one_to_hundred)
        #self.assertTrue(self.divisible_by_three_one_to_hundred not in self.even_one_to_hundred)

    def test_discrete_dimension_set_operations(self):
        #self.assertTrue(self.divisible_by_three_one_to_hundred in self.even_one_to_hundred.union(self.odd_one_to_hundred))
        #self.assertTrue(self.divisible_by_six_one_to_hundred in self.divisible_by_three_one_to_hundred.intersection(self.even_one_to_hundred))
        self.assertTrue(self.just_one not in self.one_two_three - self.one_two)
        #self.assertTrue(self.divisible_by_six_one_to_hundred not in self.one_to_hundred - self.even_one_to_hundred)
        self.assertTrue(1 in self.just_one.intersection(
            self.one_two).intersection(self.one_two_three))
        self.assertTrue(1 not in self.just_one - self.just_one)
        #self.assertTrue(42 not in self.even_one_to_hundred.intersection(self.odd_one_to_hundred))
        self.assertTrue(42 not in self.just_one.union(self.just_one))

    def test_arbitrary_composition_of_discrete_dimensions(self):

        random.seed(1)
        for k in range(1, 10):
            # let's do random mixes of our dimensions and make sure they behave sanely
            unions = random.choices(self.all_dims, k=k)
            diffs = random.choices(self.all_dims, k=k)
            intersects = random.choices(self.all_dims, k=k)

            # let's put together the resulting set
            resulting_set = unions[0]
            for i in range(k):
                resulting_set = resulting_set.union(unions[i])
                resulting_set = resulting_set.difference(diffs[i])
                resulting_set = resulting_set.intersection(intersects[i])

            # now let's iterate over values in unions and make sure they belong
            for union in unions:
                for value in union.linspace():
                    # let's see if it should belong to the resulting_set
                    should_belong = False
                    for j in range(k):
                        should_belong = should_belong or (value in unions[j])
                        should_belong = should_belong and (value
                                                           not in diffs[j])
                        should_belong = should_belong and (value
                                                           in intersects[j])

                    if not should_belong == (value in resulting_set):
                        self.assertTrue(False)

    def test_random(self):
        self.assertTrue(self.just_one.random() in self.just_one)
        for _ in range(10):
            self.assertTrue(self.one_two.random() in self.one_two_three)
    def setup_method(self, method):
        self.original_root_communication_channel_parameter_space = SimpleHypergrid(
            name='communication_channel_parameter_space',
            dimensions=[
                DiscreteDimension(name='num_readers', min=1, max=64),
                DiscreteDimension(name='log2_buffer_size', min=10, max=24),
                CategoricalDimension(name='use_emergency_buffer', values=[True, False])
            ]
        )

        self.original_emergency_buffer_settings = SimpleHypergrid(
            name='emergency_buffer_config',
            dimensions=[
                DiscreteDimension(name='log2_emergency_buffer_size', min=0, max=16),
                CategoricalDimension(name='use_colors', values=[True, False])
            ]
        )

        self.original_emergency_buffer_color = SimpleHypergrid(
            name='emergency_buffer_color',
            dimensions=[
                CategoricalDimension(name='color', values=['Maroon', 'Crimson', 'Tanager'])
            ]
        )

        self.original_emergency_buffer_settings_with_color = self.original_emergency_buffer_settings.join(
            subgrid=self.original_emergency_buffer_color,
            on_external_dimension=CategoricalDimension(name='use_colors', values=[True])
        )

        self.original_hierarchical_settings = self.original_root_communication_channel_parameter_space.join(
            subgrid=self.original_emergency_buffer_settings_with_color,
            on_external_dimension=CategoricalDimension(name='use_emergency_buffer', values=[True]),
        )

        self.root_communication_channel_parameter_space = json.loads(json.dumps(self.original_root_communication_channel_parameter_space, cls=HypergridJsonEncoder), cls=HypergridJsonDecoder)
        self.emergency_buffer_settings = json.loads(json.dumps(self.original_emergency_buffer_settings, cls=HypergridJsonEncoder), cls=HypergridJsonDecoder)
        self.emergency_buffer_color = json.loads(json.dumps(self.original_emergency_buffer_color, cls=HypergridJsonEncoder), cls=HypergridJsonDecoder)
        self.emergency_buffer_settings_with_color = json.loads(json.dumps(self.original_emergency_buffer_settings_with_color, cls=HypergridJsonEncoder), cls=HypergridJsonDecoder)
        self.hierarchical_settings = json.loads(json.dumps(self.original_hierarchical_settings, cls=HypergridJsonEncoder), cls=HypergridJsonDecoder)

        self.serialized_configs_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "SerializedUnitTestConfigs")
        self.serialized_configs_filenames = [
            (self.original_root_communication_channel_parameter_space, "original_root_communication_channel_parameter_space.json"),
            (self.original_emergency_buffer_settings, "original_emergency_buffer_settings.json"),
            (self.original_emergency_buffer_color, "original_emergency_buffer_color.json"),
            (self.original_emergency_buffer_settings_with_color, "original_emergency_buffer_settings_with_color.json"),
            (self.original_hierarchical_settings, "original_hierarchical_settings.json")
        ]

        self.serialized_configs_file_paths = [
            (hypergrid, os.path.join(self.serialized_configs_dir, serialized_config_filename))
            for hypergrid, serialized_config_filename
            in self.serialized_configs_filenames
        ]

        self.expected_print_outputs_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "ExpectedPrintOutputs")
        self.expected_print_outputs_filenames = [
            (self.original_root_communication_channel_parameter_space, "original_root_communication_channel_parameter_space.txt"),
            (self.original_emergency_buffer_settings, "original_emergency_buffer_settings.txt"),
            (self.original_emergency_buffer_color, "original_emergency_buffer_color.txt"),
            (self.original_emergency_buffer_settings_with_color, "original_emergency_buffer_settings_with_color.txt"),
            (self.original_hierarchical_settings, "original_hierarchical_settings.txt")
        ]

        self.expected_print_outputs_file_paths = [
            (hypergrid, os.path.join(self.expected_print_outputs_dir, expected_print_output_filename))
            for hypergrid, expected_print_output_filename
            in self.expected_print_outputs_filenames
        ]
Ejemplo n.º 11
0
class TestContinuousDimension:
    def setup_method(self, method):
        self.empty = ContinuousDimension(name='x',
                                         min=0,
                                         max=0,
                                         include_min=False,
                                         include_max=False)
        self.unbounded_continuous = ContinuousDimension(name='x',
                                                        min=0,
                                                        max=math.inf)
        self.unbounded_discrete = DiscreteDimension(name='x',
                                                    min=0,
                                                    max=math.inf)
        self.should_be_empty = ContinuousDimension(name='x',
                                                   min=0,
                                                   max=0,
                                                   include_min=False,
                                                   include_max=True)
        self.should_be_empty_too = ContinuousDimension(name='x',
                                                       min=0,
                                                       max=0,
                                                       include_min=True,
                                                       include_max=False)
        self.should_contain_zero = ContinuousDimension(name='x',
                                                       min=0,
                                                       max=0,
                                                       include_min=True,
                                                       include_max=True)
        self.closed = ContinuousDimension(name='x', min=0, max=1)
        self.left_open = ContinuousDimension(name='x',
                                             min=0,
                                             max=1,
                                             include_min=False)
        self.right_open = ContinuousDimension(name='x',
                                              min=0,
                                              max=1,
                                              include_max=False)
        self.open = ContinuousDimension(name='x',
                                        min=0,
                                        max=1,
                                        include_min=False,
                                        include_max=False)
        self.inner = ContinuousDimension(name='x', min=0.2, max=0.8)
        self.outer = ContinuousDimension(name='x', min=-0.2, max=1.2)
        self.left_overlapping = ContinuousDimension(name='x',
                                                    min=-0.2,
                                                    max=0.8)
        self.right_overlapping = ContinuousDimension(name='x',
                                                     min=0.2,
                                                     max=1.2)
        self.inner_wrongly_named = ContinuousDimension(name='y',
                                                       min=0.2,
                                                       max=0.8)
        self.one_to_five = ContinuousDimension(name='x', min=1, max=5)
        self.six_to_ten = ContinuousDimension(name='x', min=6, max=10)

    def test_string_representation(self):
        assert str(self.empty) == "x: (0.00, 0.00)"
        assert str(self.should_be_empty) == "x: (0.00, 0.00)"
        assert str(self.should_be_empty_too) == "x: (0.00, 0.00)"
        assert str(self.should_contain_zero) == "x: [0.00, 0.00]"
        assert str(self.closed) == "x: [0.00, 1.00]"
        assert str(self.left_open) == "x: (0.00, 1.00]"
        assert str(self.right_open) == "x: [0.00, 1.00)"
        assert str(self.open) == "x: (0.00, 1.00)"
        assert str(self.inner) == "x: [0.20, 0.80]"
        assert str(self.outer) == "x: [-0.20, 1.20]"
        assert str(self.left_overlapping) == "x: [-0.20, 0.80]"
        assert str(self.right_overlapping) == "x: [0.20, 1.20]"
        assert str(self.inner_wrongly_named) == "y: [0.20, 0.80]"

    def test_point_containment(self):

        assert (0 not in self.empty and 0 not in self.should_be_empty
                and 0 not in self.should_be_empty_too
                and 0 in self.should_contain_zero)

        assert (-1 not in self.closed and -1 not in self.left_open
                and -1 not in self.right_open and -1 not in self.open)

        assert (0 in self.closed and 0 not in self.left_open
                and 0 in self.right_open and 0 not in self.open)

        assert (0.5 in self.closed and 0.5 in self.left_open
                and 0.5 in self.right_open and 0.5 in self.open)

        assert (1 in self.closed and 1 in self.left_open
                and 1 not in self.right_open and 1 not in self.open)

        assert (2 not in self.closed and 2 not in self.left_open
                and 2 not in self.right_open and 2 not in self.open)

    def test_continuous_dimension_containment(self):
        assert self.open in self.closed
        assert self.left_open in self.closed
        assert self.right_open in self.closed

        assert self.left_open not in self.open
        assert self.right_open not in self.open
        assert self.closed not in self.open

        assert self.left_open not in self.right_open
        assert self.right_open not in self.left_open

        assert self.inner in self.closed
        assert self.inner in self.open
        assert self.inner in self.left_open
        assert self.inner in self.right_open

        assert self.closed in self.outer
        assert self.open in self.outer
        assert self.left_open in self.outer
        assert self.right_open in self.outer

        assert self.inner_wrongly_named not in self.closed
        assert self.inner_wrongly_named not in self.open
        assert self.inner_wrongly_named not in self.left_open
        assert self.inner_wrongly_named not in self.right_open

    def test_continuous_dimension_set_operations(self):
        assert self.inner in self.inner.union(self.closed)
        assert self.inner in self.inner.intersection(self.closed)

        assert self.open in self.open.intersection(self.closed)
        assert self.closed not in self.open.intersection(self.closed)
        assert self.closed in self.open.union(self.closed)
        assert self.closed in self.left_open.union(self.right_open)
        assert self.left_open.intersection(self.right_open) in self.open

    def test_random(self):
        with pytest.raises(ValueError):
            self.empty.random()
        with pytest.raises(ValueError):
            self.unbounded_continuous.random()
        with pytest.raises(OverflowError):
            self.unbounded_discrete.random()

        assert self.outer.random() in self.outer
        for _ in range(1000):
            assert self.one_to_five.random() not in self.six_to_ten
Ejemplo n.º 12
0
class TestDiscreteDimension:
    def setup_method(self, method):
        self.just_one = DiscreteDimension(name='x', min=1, max=1)
        self.one_two = DiscreteDimension(name='x', min=1, max=2)
        self.one_two_three = DiscreteDimension(name='x', min=1, max=3)
        self.one_two_three_four = DiscreteDimension(name='x', min=1, max=4)
        self.one_to_hundred = DiscreteDimension(name='x', min=1, max=100)

        self.all_dims = [
            self.just_one,
            self.one_two,
            self.one_two_three,
            self.one_two_three_four,
            self.one_to_hundred,
        ]

    def test_string_representation(self):
        assert str(self.just_one) == "x: {1}"
        assert str(self.one_two) == "x: {1, 2}"
        assert str(self.one_two_three) == "x: {1, 2, 3}"
        assert str(self.one_two_three_four) == "x: {1, 2, ... , 4}"
        assert str(self.one_to_hundred) == "x: {1, 2, ... , 100}"

    def test_point_containment(self):
        assert 1 in self.just_one

    def test_discrete_dimension_containment(self):
        assert self.just_one in self.one_two
        assert self.just_one in self.one_two_three

    def test_discrete_dimension_set_operations(self):

        assert self.just_one not in self.one_two_three - self.one_two
        assert 1 in self.just_one.intersection(self.one_two).intersection(
            self.one_two_three)
        assert 1 not in self.just_one - self.just_one
        assert 42 not in self.just_one.union(self.just_one)

    def test_arbitrary_composition_of_discrete_dimensions(self):

        random.seed(1)
        for k in range(1, 10):
            # let's do random mixes of our dimensions and make sure they behave sanely
            unions = random.choices(self.all_dims, k=k)
            diffs = random.choices(self.all_dims, k=k)
            intersects = random.choices(self.all_dims, k=k)

            # let's put together the resulting set
            resulting_set = unions[0]
            for i in range(k):
                resulting_set = resulting_set.union(unions[i])
                resulting_set = resulting_set.difference(diffs[i])
                resulting_set = resulting_set.intersection(intersects[i])

            # now let's iterate over values in unions and make sure they belong
            for union in unions:
                for value in union.linspace():
                    # let's see if it should belong to the resulting_set
                    should_belong = False
                    for j in range(k):
                        should_belong = should_belong or (value in unions[j])
                        should_belong = should_belong and (value
                                                           not in diffs[j])
                        should_belong = should_belong and (value
                                                           in intersects[j])

                    if not should_belong == (value in resulting_set):
                        assert False

    def test_random(self):
        assert self.just_one.random() in self.just_one
        for _ in range(10):
            assert self.one_two.random() in self.one_two_three