File: test_column_property.py

package info (click to toggle)
python-sqlalchemy-utils 0.41.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,252 kB
  • sloc: python: 13,566; makefile: 141
file content (132 lines) | stat: -rw-r--r-- 3,678 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import pytest
import sqlalchemy as sa

from sqlalchemy_utils.observer import observes


@pytest.mark.usefixtures('postgresql_dsn')
class TestObservesForColumn:

    @pytest.fixture
    def Product(self, Base):
        class Product(Base):
            __tablename__ = 'product'
            id = sa.Column(sa.Integer, primary_key=True)
            price = sa.Column(sa.Integer)

            @observes('price')
            def product_price_observer(self, price):
                self.price = price * 2
        return Product

    @pytest.fixture
    def init_models(self, Product):
        pass

    def test_simple_insert(self, session, Product):
        product = Product(price=100)
        session.add(product)
        session.flush()
        assert product.price == 200


@pytest.mark.usefixtures('postgresql_dsn')
class TestObservesForColumnWithoutActualChanges:

    @pytest.fixture
    def Product(self, Base):
        class Product(Base):
            __tablename__ = 'product'
            id = sa.Column(sa.Integer, primary_key=True)
            price = sa.Column(sa.Integer)

            @observes('price')
            def product_price_observer(self, price):
                raise Exception('Trying to change price')
        return Product

    @pytest.fixture
    def init_models(self, Product):
        pass

    def test_only_notifies_observer_on_actual_changes(self, session, Product):
        product = Product()
        session.add(product)
        session.flush()

        with pytest.raises(Exception) as e:
            product.price = 500
            session.commit()
        assert str(e.value) == 'Trying to change price'


@pytest.mark.usefixtures('postgresql_dsn')
class TestObservesForMultipleColumns:

    @pytest.fixture
    def Order(self, Base):
        class Order(Base):
            __tablename__ = 'order'
            id = sa.Column(sa.Integer, primary_key=True)
            unit_price = sa.Column(sa.Integer)
            amount = sa.Column(sa.Integer)
            total_price = sa.Column(sa.Integer)

            @observes('amount', 'unit_price')
            def total_price_observer(self, amount, unit_price):
                self.total_price = amount * unit_price
        return Order

    @pytest.fixture
    def init_models(self, Order):
        pass

    def test_only_notifies_observer_on_actual_changes(self, session, Order):
        order = Order()
        order.amount = 2
        order.unit_price = 10
        session.add(order)
        session.flush()

        order.amount = 1
        session.flush()
        assert order.total_price == 10

        order.unit_price = 100
        session.flush()
        assert order.total_price == 100


@pytest.mark.usefixtures('postgresql_dsn')
class TestObservesForMultipleColumnsFiresOnlyOnce:

    @pytest.fixture
    def Order(self, Base):
        class Order(Base):
            __tablename__ = 'order'
            id = sa.Column(sa.Integer, primary_key=True)
            unit_price = sa.Column(sa.Integer)
            amount = sa.Column(sa.Integer)

            @observes('amount', 'unit_price')
            def total_price_observer(self, amount, unit_price):
                self.call_count = self.call_count + 1
        return Order

    @pytest.fixture
    def init_models(self, Order):
        pass

    def test_only_notifies_observer_on_actual_changes(self, session, Order):
        order = Order()
        order.amount = 2
        order.unit_price = 10
        order.call_count = 0
        session.add(order)
        session.flush()
        assert order.call_count == 1

        order.amount = 1
        order.unit_price = 100
        session.flush()
        assert order.call_count == 2