Esempio n. 1
0
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')
Esempio n. 2
0
 def setup(self):
     self._frame = Frame()
Esempio n. 3
0
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)