def test_any_value_substitution(self): allowed_values = [ { "foo": AnyValue(), "bar": ValueSet(123) }, { "foo": ValueSet(2), "bar": ValueSet(321) }, { "foo": ValueSet(3), "bar": ValueSet(123) }, ] # No substitution assert allowed_values_for(allowed_values, "foo", {"bar": 123}) == AnyValue() # With substitution assert (allowed_values_for( allowed_values, "foo", {"bar": 123}, ValueSet(1, 2, 3, 4), ) == ValueSet(1, 2, 3, 4))
def test_combine(self): a1 = AnyValue() a2 = AnyValue() vs = ValueSet() for a in [a1, a2, vs]: for b in [a1, a2, vs]: if not (a == b == vs): assert isinstance(a + b, AnyValue)
def test_level_assumptions(self): # The test case generator assumes that levels either require the slice # prefix bytes to be zero or allow it to be anything -- any condition # other than this would require the test case generator to be more # flexible than it is. # # The above assumption is verified below for values in LEVEL_CONSTRAINTS: if Profiles.high_quality in values["profile"]: assert values["slice_prefix_bytes"] == AnyValue() or values[ "slice_prefix_bytes" ] == ValueSet(0)
def test_read_constraints_from_csv(): constraints = read_constraints_from_csv( os.path.join(os.path.dirname(__file__), "sample_constraint_table.csv")) # Every column included (incl. empty column!) assert len(constraints) == 4 # All columns should have all row names assert all( set(c) == set(["foo", "bar", "baz", "quo", "qux"]) for c in constraints) # Plain integers in 'foo' assert constraints[0]["foo"] == ValueSet(1) assert constraints[1]["foo"] == ValueSet(2) assert constraints[2]["foo"] == ValueSet() # Empty assert constraints[3]["foo"] == ValueSet(3) # Multiple integers in 'bar' assert constraints[0]["bar"] == ValueSet(10, 100) assert constraints[1]["bar"] == ValueSet(20, 200) assert constraints[2]["bar"] == ValueSet() # Empty assert constraints[3]["bar"] == ValueSet(30, 300) # 'Ditto' used in 'baz' assert constraints[0]["baz"] == ValueSet(12) assert constraints[1]["baz"] == ValueSet(12) # Ditto'd assert constraints[2]["baz"] == ValueSet() # Empty assert constraints[3]["baz"] == ValueSet(3) # 'any', ranges and empty values used in 'quo' assert constraints[0]["quo"] == AnyValue() assert constraints[1]["quo"] == ValueSet((2, 200), (300, 3000)) assert constraints[2]["quo"] == ValueSet() # Empty assert constraints[3]["quo"] == ValueSet() # Booleans in 'qux' assert constraints[0]["qux"] == ValueSet(False) assert constraints[1]["qux"] == ValueSet(True) assert constraints[2]["qux"] == ValueSet() # Empty assert constraints[3]["qux"] == ValueSet(True, False)
def test_str(self): assert str(AnyValue()) == "{<any value>}"
def test_repr(self): assert repr(AnyValue()) == "AnyValue()"
def test_is_disjoint(self): assert AnyValue().is_disjoint(AnyValue()) is False assert AnyValue().is_disjoint(ValueSet()) is True assert AnyValue().is_disjoint(ValueSet(1)) is False
def test_compare(self): assert AnyValue() == AnyValue() assert AnyValue() != ValueSet() assert ValueSet() != AnyValue()
def test_add(self): a = AnyValue() # Should do nothing a.add_value(123) a.add_range(10, 20)
def test_contains_everything(self): a = AnyValue() assert None in a assert 123 in a assert "foo" in a
class TestValueSet(object): def test_constructor_empty(self): vs = ValueSet() assert vs._values == set() assert vs._ranges == set() def test_add_value(self): vs = ValueSet() # Duplicate values not allowed vs.add_value(123) vs.add_value(123) assert list(vs) == [123] # Values already in a range not allowed vs.add_range(10, 20) vs.add_value(10) vs.add_value(15) vs.add_value(20) assert list(vs) == [123, (10, 20)] def test_add_range_non_overlapping(self): vs = ValueSet() vs.add_range(10, 20) vs.add_range(30, 40) vs.add_range(22, 27) assert sorted(vs) == [(10, 20), (22, 27), (30, 40)] def test_add_range_overlap_single_values(self): vs = ValueSet() vs.add_value(5) vs.add_value(10) vs.add_value(15) vs.add_value(20) vs.add_value(25) vs.add_range(10, 20) assert vs._values == set([5, 25]) assert vs._ranges == set([(10, 20)]) @pytest.mark.parametrize( "ranges", [ # Touching [(10, 20), (20, 30)], [(20, 30), (10, 20)], # Overlapping [(10, 25), (15, 30)], [(15, 30), (10, 25)], # Super/subset [(10, 30), (15, 25)], [(15, 25), (10, 30)], # Many combined [(10, 15), (17, 22), (25, 30), (14, 26)], ], ) def test_add_range_overlap_existing_ranges(self, ranges): vs = ValueSet() for r in ranges: vs.add_range(*r) assert vs._ranges == set([(10, 30)]) def test_constructor_works(self): vs = ValueSet(5, 10, 15, 20, 25, (10, 15), (15, 21)) assert vs._values == set([5, 25]) assert vs._ranges == set([(10, 21)]) def test_empty(self): empty = ValueSet() assert None not in empty assert 123 not in empty assert "foo" not in empty def test_individual_values(self): vs = ValueSet() vs.add_value(123) assert 123 in vs assert 321 not in vs vs.add_value("foo") assert 123 in vs assert "foo" in vs assert 321 not in vs assert "bar" not in vs def test_ranges(self): vs = ValueSet() vs.add_range(10, 20) assert 9 not in vs assert 9.9999 not in vs assert 10 in vs assert 15 in vs assert 20 in vs assert 20.0001 not in vs assert 21 not in vs vs.add_range(30, 40) assert 9 not in vs assert 9.9999 not in vs assert 10 in vs assert 15 in vs assert 20 in vs assert 20.0001 not in vs assert 21 not in vs assert 29 not in vs assert 29.9999 not in vs assert 30 in vs assert 35 in vs assert 40 in vs assert 40.0001 not in vs assert 41 not in vs def test_combination(self): vs = ValueSet() vs.add_value(1) vs.add_range(10, 20) assert 0 not in vs assert 1 in vs assert 2 not in vs assert 9 not in vs assert 10 in vs assert 15 in vs assert 20 in vs assert 21 not in vs def test_combine_value_sets(self): vs1 = ValueSet() vs1.add_value(1) vs1.add_range(10, 20) vs2 = ValueSet() vs2.add_value(2) vs2.add_range(20, 30) vs = vs1 + vs2 assert 0 not in vs assert 1 in vs assert 2 in vs assert 3 not in vs assert 9 not in vs assert 10 in vs assert 15 in vs assert 20 in vs assert 25 in vs assert 30 in vs assert 31 not in vs @pytest.mark.parametrize( "a,b,expected", [ # Empty is always disjoint with other value sets (ValueSet(), ValueSet(), True), (ValueSet(1, 2, 3), ValueSet(), True), (ValueSet((1, 3)), ValueSet(), True), (AnyValue(), ValueSet(), True), # Individual values (ValueSet(1), ValueSet(2), True), (ValueSet(1), ValueSet(1), False), (ValueSet(1, 2, 3), ValueSet(4, 5, 6), True), (ValueSet(1, 2, 3), ValueSet(3, 4, 5), False), # Values and ranges (ValueSet(1), ValueSet((2, 10)), True), (ValueSet(2), ValueSet((2, 10)), False), (ValueSet(5), ValueSet((2, 10)), False), (ValueSet(10), ValueSet((2, 10)), False), (ValueSet(11), ValueSet((2, 10)), True), # Ranges: don't intersect (ValueSet((1, 3)), ValueSet((4, 6)), True), # Ranges: ends touch (ValueSet((1, 3)), ValueSet((3, 6)), False), # Ranges: partial overlap (ValueSet((1, 4)), ValueSet((3, 6)), False), # Ranges: identical (ValueSet((3, 6)), ValueSet((3, 6)), False), # Ranges: superset (ValueSet((2, 6)), ValueSet((3, 6)), False), (ValueSet((3, 7)), ValueSet((3, 6)), False), (ValueSet((2, 7)), ValueSet((3, 6)), False), ], ) def test_is_disjoint(self, a, b, expected): assert a.is_disjoint(b) is expected assert b.is_disjoint(a) is expected def test_iter(self): vs = ValueSet() assert set(vs) == set() vs.add_value(1) vs.add_value(2) vs.add_value(3) assert set(vs) == set([1, 2, 3]) vs.add_range(10, 20) vs.add_range(30, 40) assert set(vs) == set([1, 2, 3, (10, 20), (30, 40)]) def test_iter_values(self): vs = ValueSet() assert set(vs.iter_values()) == set() vs.add_value(1) vs.add_value(2) vs.add_value(3) assert set(vs.iter_values()) == set([1, 2, 3]) vs.add_range(10, 13) vs.add_range(15, 20) assert set(vs.iter_values()) == set( [1, 2, 3, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20]) def test_compare(self): assert ValueSet() == ValueSet() assert ValueSet(1, 2, (3, 4)) == ValueSet((3, 4), 2, 1) assert ValueSet(1) != ValueSet(2) assert ValueSet(1, 2) != ValueSet(1, 2, 3) assert ValueSet(1, 2) != ValueSet(1, (2, 3)) assert ValueSet((2, 3)) != ValueSet((3, 2)) def test_repr(self): vs = ValueSet() assert repr(vs) == "ValueSet()" vs.add_value(123) vs.add_range(10, 20) assert repr(vs) == "ValueSet(123, (10, 20))" def test_str(self): vs = ValueSet() assert str(vs) == "{<no values>}" vs.add_value(10) vs.add_value(20) vs.add_value(30) assert str(vs) == "{10, 20, 30}" vs.add_range(3, 7) vs.add_range(13, 17) vs.add_range(20, 25) vs.add_range(33, 37) assert str(vs) == "{3-7, 10, 13-17, 20-25, 30, 33-37}" def test_str_uses_repr(self): vs = ValueSet() vs.add_value("foo") assert str(vs) == "{'foo'}"
def custom_quantization_matrix(codec_features): """ **Tests that a custom quantization matrix can be specified.** A series of bitstreams with different custom quantisation matrices are generated as follows: ``custom_quantization_matrix[zeros]`` Specifies a custom quantisation matrix with all matrix values set to zero. ``custom_quantization_matrix[arbitrary]`` Specifies a custom quantisation matrix with all matrix values set to different, though arbitrary, values. ``custom_quantization_matrix[default]`` Specifies a custom quantisation matrix containing the same values as the default quantisation matrix. This test case is only generated when a default quantization matrix is defined for the codec. These test cases are only generated when permitted by the VC-2 level in use. .. note:: For lossy coding modes, the encoded picture will contain a noise signal (see the :decoder-test-case:`static_noise` test case). For lossless coding modes, the encoded picture will be the test pattern used by the :decoder-test-case:`lossless_quantization` test case. This test pattern is designed to be losslessly encodable when some quantization is applied. """ # Skip if the level disallows custom quantisation matrices constrained_values = codec_features_to_trivial_level_constraints(codec_features) constrained_values["custom_quant_matrix"] = True allowed_quant_matrix_values = allowed_values_for( LEVEL_CONSTRAINTS, "quant_matrix_values", constrained_values ) if allowed_quant_matrix_values == ValueSet(): return # A set of alternative quantisation matrices to test # [(description, quantization_matrix), ...] candidate_matrices = [] # A special case: a flat (all zeros) quantisation matrix candidate_matrices.append( ("zeros", quantization_matrix_from_generator(codec_features, repeat(0))) ) # An arbitrary quantisation matrix with different values in each entry (if # possible) if allowed_quant_matrix_values == AnyValue(): values = count() else: values = cycle(sorted(allowed_quant_matrix_values.iter_values())) candidate_matrices.append( ("arbitrary", quantization_matrix_from_generator(codec_features, values)) ) # If a default quantisation matrix is available, try explicitly giving the # values from the default quant matrix wavelet_specification = ( codec_features["wavelet_index"], codec_features["wavelet_index_ho"], codec_features["dwt_depth"], codec_features["dwt_depth_ho"], ) if wavelet_specification in QUANTISATION_MATRICES: candidate_matrices.append( ( "default", QUANTISATION_MATRICES[wavelet_specification], ) ) # Generate test cases for each custom quantisation matrix. for description, quantization_matrix in candidate_matrices: # If we happen to have generated the quantization matrix specified in # the codec features, skip that case... if quantization_matrix == codec_features["quantization_matrix"]: continue # If we the level restricts the quantisation matrix values such that # the generated cases is not allowed, skip it. if not all( value in allowed_quant_matrix_values for orients in quantization_matrix.values() for value in orients.values() ): continue stream = generate_test_stream( CodecFeatures( codec_features, quantization_matrix=quantization_matrix, ) ) if stream is not None: yield TestCase(stream, description)