def test_does_not_hide_error_in_generate(): def broken(r): raise ValueError() machine = TestMachine() machine.add(generate(broken, "broken")) with pytest.raises(ValueError): machine.run()
""" Find an example demonstrating that lists can contain the same element multiple times. Example output: t1 = 1 t2 = [t1, t1] assert unique(t2) """ from testmachine import TestMachine from testmachine.common import ints, lists machine = TestMachine() # Populate the ints varstack with integer values ints(machine) # Populate the intlists varstack with lists whose elements are drawn from the # ints varstack lists(machine, source="ints", target="intlists") # Check whether a list contains only unique elements. If it contains duplicates # raise an error. machine.check( lambda s: len(s) == len(set(s)), argspec=("intlists",), name="unique" ) if __name__ == '__main__': # Find a program that creates a list with non-unique elements. machine.run()
""" Find an example demonstrating that lists can contain the same element multiple times. Example output: t1 = 1 t2 = [t1, t1] assert unique(t2) """ from testmachine import TestMachine from testmachine.common import ints, lists, check machine = TestMachine() machine.add( # Populate the ints varstack with integer values ints(), # Populate the intlists varstack with lists whose elements are drawn from # the ints varstack lists(source="ints", target="intlists"), # Check whether a list contains only unique elements. If it contains # duplicates raise an error. check( lambda s: len(s) == len(set(s)), argspec=("intlists",), name="unique" ), ) if __name__ == '__main__': # Find a program that creates a list with non-unique elements. machine.main()
def __len__(self): return len(self.child0) + len(self.child1) def balanced(self): if not (self.child0.balanced() and self.child1.balanced()): return False return ( (len(self.child0) <= len(self.child1) + 1) and (len(self.child1) <= len(self.child0) + 1) ) # Business as usual machine = TestMachine() # Because we might as well machine.add(basic_operations("trees")) # We can always generate leaf nodes. We ignore the Random argument we're given # because all Leaves are created equal. machine.add(generate(lambda _: Leaf(), "trees")) # Given two trees, we can join them together into a new tree machine.add(operation( argspec=("trees", "trees"), target="trees", function=lambda x, y: x.join(y), pattern="{0}.join({1})"
Find an example demonstrating that floating point addition is not associative Example output: t1 = 0.11945064104636571 t2 = t1 / t1 t3 = 0.16278913131835504 t4 = 0.6323432862008465 assert associative_add(t4, t3, t2) """ from testmachine import TestMachine from random import Random # This is the object that we use to define the kind of test case we want to # generate. machine = TestMachine() # testmachine.common defines a number of standard operations on different types # of variables. We're going to use some of those rather than implementing our # own. from testmachine.common import ( basic_operations, arithmetic_operations, generate, check ) # We only have one type of variable. We'll call that floats, but this is just # an arbitrary name. We could call it steve if we wanted to. # We generate our basic floats as random numbers between 0 and 1. machine.add(generate(Random.random, "floats")) # These are basic stack manipulation operations. They aren't very exciting, but # they expand the likelihood of producing interesting programs. Most machines
Find an example demonstrating that floating point addition is not associative Example output: t1 = 0.11945064104636571 t2 = t1 / t1 t3 = 0.16278913131835504 t4 = 0.6323432862008465 assert associative_add(t4, t3, t2) """ from testmachine import TestMachine from random import Random # This is the object that we use to define the kind of test case we want to # generate. machine = TestMachine() # testmachine.common defines a number of standard operations on different types # of variables. We're going to use some of those rather than implementing our # own. from testmachine.common import basic_operations, arithmetic_operations # We only have one type of variable. We'll call that floats, but this is just # an arbitrary name. We could call it steve if we wanted to. # We generate our basic floats as random numbers between 0 and 1. machine.generate(Random.random, "floats") # These are basic stack manipulation operations. They aren't very exciting, but # they expand the likelihood of producing interesting programs. Most machines # will use these. basic_operations(machine, "floats")
def __len__(self): return len(self.child0) + len(self.child1) def balanced(self): if not (self.child0.balanced() and self.child1.balanced()): return False return ( (len(self.child0) <= len(self.child1) + 1) and (len(self.child1) <= len(self.child0) + 1) ) # Business as usual machine = TestMachine() # Because we might as well basic_operations(machine, "trees") # We can always generate leaf nodes. We ignore the Random argument we're given # because all Leaves are created equal. machine.generate(lambda _: Leaf(), "trees") # Given two trees, we can join them together into a new tree machine.operation( argspec=("trees", "trees"), target="trees", function = lambda x, y: x.join(y), pattern="%s.join(%s)"