def test_frame_close(): f1 = Frame() t1 = f1.term() t1.put_atom_name('t1') assert_equal(str(t1), 't1') f1.close() with assert_raises(AttributeError): str(t1) with assert_raises(AttributeError): f1.close() with Frame() as f2: t2 = f2.term() t2.put_atom_name('t2') assert_equal(str(t2), 't2') with assert_raises(AttributeError): str(t2) with assert_raises(AttributeError): f2.close() X = Term() with Frame(): X.put_integer(1) assert_equal(str(X), '1') assert_equal(str(X), '1') eq = Predicate.from_name_arity('=', 2) X = Term() with Frame(): eq(X, Term.from_integer(1)) assert_equal(str(X), '1') assert_equal(str(X), '1')
def setup(self): self._frame = Frame()
class CheckTerm(): def __init__(self, type_, value=None, prolog_string=None, atom=None, functor=None, is_acyclic=True, pointer_value=None, is_ground=None, is_integer_like=None, is_pointer=False): self.type_ = type_ self.value = value self.prolog_string = prolog_string # SWI-Prolog is inconsistent with respect to the list terminator # constant nil ([]). Within the language, nil is not an atom. # ``atom([])`` is false. However, the foreign language API functions # behave as if nil is an atom. self.is_api_atom = self.type_ in ('atom', 'nil') if self.is_api_atom: if atom is None: raise ValueError("Argument 'atom' must be set") self.atom = atom self.is_compound = self.type_ in ('compound', 'list-pair', 'dict') if self.is_compound or self.is_api_atom: if functor is None: raise ValueError("Argument 'functor' must be set") self.functor = functor self.is_acyclic = is_acyclic self.pointer_value = pointer_value if is_ground is None: is_ground = self.type_ != 'variable' self.is_ground = is_ground if is_integer_like is None: is_integer_like = (self.type_ == 'integer') self.is_integer_like = is_integer_like self.is_pointer = is_pointer self.is_boolean_atom = (self.type_ == 'atom' and self.value in (True, False)) def setup(self): self._frame = Frame() def teardown(self): self._frame.discard() def check_value_string(self, term_string): if self.is_pointer: return variable_regex = '[A-Z_][A-Za-z0-9_]*' prolog_string_regex = ( '^' + re.escape(self.prolog_string).replace('\%v', variable_regex) + '$') assert_regex(term_string, prolog_string_regex) def test__str__(self): self.check_value_string(str(self.term)) def test__repr__(self): assert_regex(repr(self.term), "Term\(handle=\d*, type={!s}, value={!s}\)".format( re.escape(repr(self.type_)), re.escape(repr(str(self.term))))) def test__eq__(self): assert_equal(self.term, self.term) # A new unbound variable is not equal to any other term. assert_not_equal(self.term, Term()) # Regardless of what term is, comparison with non-term should fail assert_not_equal(self.term, str(self.term)) assert_not_equal(self.term, 2) assert_not_equal(2, self.term) def test__int__(self): if self.is_pointer: # No promise about value, but should complete successfully int(self.term) elif self.is_integer_like: assert_equal(int(self.term), int(self.value)) else: assert_raises(TypeError, int, self.term) def test__float__(self): if self.is_pointer: # No promise about value, but should complete successfully float(self.term) elif self.type_ in ('integer', 'float'): if math.isnan(self.value): # Checking equality of NaN doesn't work assert_true(math.isnan(float(self.term))) else: assert_equal(float(self.term), float(self.value)) else: assert_raises(TypeError, float, self.term) def test__deepcopy__(self): term_copy = copy.deepcopy(self.term) assert_equal(self.term, term_copy) term_copy.put_term(Term()) assert_not_equal(self.term, term_copy) def test_from_term(self): term_copy = Term.from_term(self.term) assert_equal(self.term, term_copy) term_copy.put_term(Term()) assert_not_equal(self.term, term_copy) def test_type(self): assert_equal(self.term.type(), self.type_) def test_is_acyclic(self): assert_equal(self.term.is_acyclic(), self.is_acyclic) def test_is_atom(self): assert_equal(self.term.is_atom(), self.type_ == 'atom') def test_is_atomic(self): assert_equal(self.term.is_atomic(), self.type_ != 'variable' and not self.is_compound) def test_is_callable(self): assert_equal(self.term.is_callable(), self.type_ in ('atom', 'compound', 'list-pair')) def test_is_compound(self): assert_equal(self.term.is_compound(), self.is_compound) def test_is_float(self): assert_equal(self.term.is_float(), self.type_ == 'float') def test_is_functor(self): different_functor = Functor('some_different_functor_', 1) assert_false(self.term.is_functor(different_functor)) if self.is_compound: assert_true(self.term.is_functor(self.functor)) name, arity = self.term.get_name_arity() assert_true(self.term.is_functor(Functor(name, arity))) assert_false(self.term.is_functor( Functor(name.get_name() + '_', arity))) assert_false(self.term.is_functor(Functor(name, arity + 1))) def test_is_ground(self): if self.is_ground is None: raise Exception('Must set is_ground') assert_equal(self.term.is_ground(), self.is_ground) def test_is_integer(self): assert_equal(self.term.is_integer(), self.type_ == 'integer') def test_is_list(self): # This is a weaker condition than prolog's is_list predicate. assert_equal(self.term.is_list(), self.type_ in ('nil', 'list-pair')) def test_is_nil(self): assert_equal(self.term.is_nil(), self.type_ == 'nil') def test_is_number(self): assert_equal(self.term.is_number(), self.type_ in ('integer', 'float')) def test_is_pair(self): assert_equal(self.term.is_pair(), self.type_ == 'list-pair') def test_is_string(self): assert_equal(self.term.is_string(), self.type_ == 'string') def test_is_variable(self): assert_equal(self.term.is_variable(), self.type_ == 'variable') def test_get_atom(self): if self.is_api_atom: assert_equal(self.term.get_atom(), self.atom) else: assert_raises(TypeError, self.term.get_atom) def test_get_atom_name(self): if self.type_ == 'atom': if self.value in (True, False): string_value = str(self.value).lower() else: string_value = self.value assert_equal(self.term.get_atom_name(), string_value) else: assert_raises(TypeError, self.term.get_atom_name) def test_get_string_chars(self): if self.type_ == 'string': assert_equal(self.term.get_string_chars(), self.value) else: assert_raises(TypeError, self.term.get_string_chars) def test_get_chars(self): self.check_value_string(self.term.get_chars()) def test_get_integer(self): if self.is_pointer: # No promise about value, but should complete successfully int(self.term) elif self.is_integer_like: assert_equal(self.term.get_integer(), int(self.value)) else: assert_raises(TypeError, self.term.get_integer) def test_get_bool(self): if self.is_boolean_atom: assert_equal(self.term.get_bool(), self.value) else: assert_raises(TypeError, self.term.get_bool) def test_get_pointer(self): if self.pointer_value is not None: assert_equal(self.term.get_pointer(), self.pointer_value) elif self.is_integer_like: # Result of interpreting non-pointer integer as pointer is # unspecified. pass else: assert_raises(TypeError, self.term.get_pointer) def test_get_functor(self): if self.is_compound or self.is_api_atom: assert_equal(self.term.get_functor(), self.functor) else: assert_raises(TypeError, self.term.get_functor) def test_unification_left(self): X = Term() assert_not_equal(self.term, X) self.term.unify(X) assert_equal(self.term, X) def test_unification_right(self): X = Term() assert_not_equal(self.term, X) X.unify(self.term) assert_equal(self.term, X) def test_unification_eq(self): X = Term() assert_not_equal(self.term, X) Predicate.from_name_arity('=', 2)(self.term, X) assert_equal(self.term, X)