Example #1
0
    def test_syntax_error(self) -> None:
        def f(x: int) -> int:
            """ pre: x && x """

        self.assertEqual(
            *check_messages(analyze_function(f), state=MessageType.SYNTAX_ERR)
        )
Example #2
0
 def test_methods_directly(self) -> None:
     # Running analysis on individual methods directly works a little
     # differently, especially for staticmethod/classmethod. Confirm these
     # don't explode:
     messages = analyze_any(Person.a_regular_method, AnalysisOptions())
     self.assertEqual(
         *check_messages(messages, state=MessageType.CONFIRMED))
Example #3
0
    def test_super(self):
        class FooDetector(SmokeDetector):
            def signaling_alarm(self, air_samples: List[str]):
                return super().signaling_alarm(air_samples)

        self.assertEqual(*check_messages(analyze_class(FooDetector),
                                         state=MessageType.CONFIRMED))
Example #4
0
 def test_static_method(self) -> None:
     messages = analyze_any(
         walk_qualname(Person, "a_static_method"),
         AnalysisOptionSet(per_condition_timeout=5),
     )
     self.assertEqual(
         *check_messages(messages, state=MessageType.CONFIRMED))
Example #5
0
    def test_invalid_raises(self) -> None:
        def f(x: int) -> int:
            """ raises: NotExistingError """
            return x

        self.assertEqual(
            *check_messages(analyze_function(f), state=MessageType.SYNTAX_ERR))
Example #6
0
 def test_expr_name_resolution(self):
     '''
     dataclass() generates several methods. It can be tricky to ensure
     that invariants for these methods can resolve names in the 
     correct namespace.
     '''
     self.assertEqual(*check_messages(analyze_class(ReferenceHoldingClass), state=MessageType.CONFIRMED))
Example #7
0
 def test_icontract_snapshots(self):
     messages = analyze_function(
         icontract_appender,
         DEFAULT_OPTIONS.overlay(
             analysis_kind=[AnalysisKind.icontract]),
     )
     self.assertEqual(*check_messages(
         messages, state=MessageType.POST_FAIL, line=95, column=0))
Example #8
0
 def test_old_works_in_invariants(self) -> None:
     class FrozenApples:
         ''' inv: self.count == __old__.self.count '''
         count: int
         def add_one(self):
             self.count += 1
     messages = analyze_class(FrozenApples)
     self.assertEqual(*check_messages(messages, state=MessageType.POST_FAIL))
Example #9
0
    def test_readonly_property_contract(self) -> None:
        class Clock:
            @property
            def time(self) -> int:
                """ post: _ == self.time """
                return 120

        messages = analyze_class(Clock)
        self.assertEqual(*check_messages(messages, state=MessageType.CONFIRMED))
Example #10
0
 def test_methods_directly(self) -> None:
     # Running analysis on individual methods directly works a little
     # differently, especially for staticmethod/classmethod. Confirm these
     # don't explode:
     messages = analyze_any(
         walk_qualname(Person, "a_regular_method"),
         AnalysisOptionSet(per_condition_timeout=5),
     )
     self.assertEqual(*check_messages(messages, state=MessageType.CONFIRMED))
Example #11
0
 def test_use_inherited_postconditions(self):
     class CarbonMonoxideDetector(SmokeDetector):
         def signaling_alarm(self, air_samples: List[str]) -> bool:
             '''
             post: implies('carbon_monoxide' in air_samples, _ == True)
             '''
             return 'carbon_monoxide' in air_samples  # fails: does not detect smoke
     self.assertEqual(*check_messages(analyze_class(CarbonMonoxideDetector),
                                      state=MessageType.POST_FAIL))
Example #12
0
 def test_error_message_in_unrelated_method(self) -> None:
     messages = analyze_class(OverloadedContainer)
     self.assertEqual(*check_messages(
         messages,
         state=MessageType.POST_FAIL,
         message=
         "false when calling total_weight(self = OverloadedContainer) (which returns 13)",
         line=132,
     ))
Example #13
0
    def test_bad_invariant(self):
        class Foo:
            """
            inv: self.item == 7
            """
            def do_a_thing(self) -> None:
                pass

        self.assertEqual(
            *check_messages(analyze_class(Foo), state=MessageType.PRE_UNSAT))
Example #14
0
    def test_inherited_preconditions_overridable(self):
        class SmokeDetectorWithBattery(SmokeDetector):
            _battery_power: int

            def signaling_alarm(self, air_samples: List[str]) -> bool:
                '''
                pre: self._battery_power > 0 or self._is_plugged_in
                '''
                return 'smoke' in air_samples
        self.assertEqual(*check_messages(analyze_class(SmokeDetectorWithBattery),
                                         state=MessageType.CONFIRMED))
Example #15
0
 def test_error_message_in_unrelated_method(self) -> None:
     messages = analyze_class(OverloadedContainer)
     line = ShippingContainer.total_weight.__code__.co_firstlineno + 1
     self.assertEqual(
         *check_messages(
             messages,
             state=MessageType.POST_FAIL,
             message="false when calling total_weight(self = OverloadedContainer) (which returns 13)",
             line=line,
         )
     )
Example #16
0
 def test_asserts(self):
     messages = analyze_function(
         remove_smallest_with_asserts,
         DEFAULT_OPTIONS.overlay(
             analysis_kind=[AnalysisKind.asserts],
             max_iterations=10,
             per_condition_timeout=5,
         ),
     )
     self.assertEqual(*check_messages(
         messages, state=MessageType.EXEC_ERR, line=85, column=0))
Example #17
0
 def test_icontract_snapshots(self):
     messages = analyze_function(
         icontract_appender,
         DEFAULT_OPTIONS.overlay(analysis_kind=[AnalysisKind.icontract]),
     )
     line = icontract_appender.__wrapped__.__code__.co_firstlineno + 1
     self.assertEqual(
         *check_messages(
             messages, state=MessageType.POST_FAIL, line=line, column=0
         )
     )
Example #18
0
    def TODO_test_cannot_strengthen_inherited_preconditions(self):
        class PowerHungrySmokeDetector(SmokeDetector):
            _battery_power: int

            def signaling_alarm(self, air_samples: List[str]) -> bool:
                '''
                pre: self._is_plugged_in
                pre: self._battery_power > 0
                '''
                return 'smoke' in air_samples
        self.assertEqual(*check_messages(analyze_class(PowerHungrySmokeDetector),
                                         state=MessageType.PRE_INVALID))
Example #19
0
 def test_error_message_has_unmodified_args(self) -> None:
     def f(foo: List[Pokeable]) -> None:
         '''
         pre: len(foo) == 1
         pre: foo[0].x == 10
         post[foo]: foo[0].x == 12
         '''
         foo[0].poke()
     self.assertEqual(*check_messages(
         analyze_function(f),
         state=MessageType.POST_FAIL,
         message='false when calling f(foo = [Pokeable(10)])'))
Example #20
0
 def test_hypothesis_counterexample_text():
     messages = analyze_function(
         foo,
         DEFAULT_OPTIONS.overlay(
             analysis_kind=[AnalysisKind.hypothesis],
             max_iterations=10,
             per_condition_timeout=20,
             per_path_timeout=5,
         ),
     )
     actual, expected = check_messages(
         messages,
         state=MessageType.EXEC_ERR,
         message="AssertionError: assert False when calling foo(x = False)",
     )
     assert actual == expected
Example #21
0
 def test_check_parent_conditions(self):
     # Ensure that conditions of parent classes are checked in children
     # even when not overridden.
     class Parent:
         def size(self) -> int:
             return 1
         def amount_smaller(self, other_size: int) -> int:
             '''
             pre: other_size >= 1
             post: _ >= 0
             '''
             return other_size - self.size()
     class Child(Parent):
         def size(self) -> int:
             return 2
     messages = analyze_class(Child)
     self.assertEqual(*check_messages(messages, state=MessageType.POST_FAIL))
Example #22
0
    def test_typevar(self) -> None:
        T = TypeVar('T')

        class MaybePair(Generic[T]):
            '''
            inv: (self.left is None) == (self.right is None)
            '''
            left: Optional[T]
            right: Optional[T]

            def setpair(self, left: Optional[T], right: Optional[T]):
                '''post[self]: True'''
                if (left is None) ^ (right is None):
                    raise ValueError('Populate both values or neither value in the pair')
                self.left, self.right = left, right

        messages = analyze_class(MaybePair)
        self.assertEqual(*check_messages(messages, state=MessageType.EXEC_ERR))
Example #23
0
    def test_old_works_in_invariants(self) -> None:
        @dataclasses.dataclass
        class FrozenApples:
            """ inv: self.count == __old__.self.count """

            count: int

            def add_one(self):
                self.count += 1

        messages = analyze_class(FrozenApples)
        self.assertEqual(*check_messages(messages, state=MessageType.POST_FAIL))

        # Also confirm we can create one as an argument:
        def f(a: FrozenApples) -> int:
            """post: True"""
            return 0

        self.assertEqual(*check_ok(f))
Example #24
0
 def test_recursive_postcondition_enforcement_suspension(self) -> None:
     messages = analyze_class(Measurer)
     self.assertEqual(
         *check_messages(messages, state=MessageType.POST_FAIL))
Example #25
0
 def test_inheritance_base_class_ok(self):
     self.assertEqual(*check_messages(analyze_class(SmokeDetector),
                                      state=MessageType.CONFIRMED))
Example #26
0
 def test_person_class(self) -> None:
     messages = analyze_class(Person)
     self.assertEqual(
         *check_messages(messages, state=MessageType.CONFIRMED))
Example #27
0
 def test_pokeable_class(self) -> None:
     messages = analyze_class(Pokeable)
     self.assertEqual(*check_messages(
         messages, state=MessageType.POST_FAIL, line=58, column=0))
Example #28
0
 def test_pokeable_class(self) -> None:
     messages = analyze_class(Pokeable)
     line = Pokeable.wild_pokeby.__code__.co_firstlineno
     self.assertEqual(
         *check_messages(messages, state=MessageType.POST_FAIL, line=line, column=0)
     )
Example #29
0
 def test_static_method(self) -> None:
     messages = analyze_any(Person.a_static_method, AnalysisOptions())
     self.assertEqual(*check_messages(messages, state=MessageType.CONFIRMED))