1# Copyright 2017 CodiLime
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from __future__ import unicode_literals
16
17import unittest
18
19import six
20
21from veles.data.bindata import BinData
22from veles.schema import fields
23from veles.schema.model import Model
24from veles.proto.exceptions import SchemaError
25
26
27class Piwo(Model):
28    a = fields.Boolean()
29
30
31class Zlew(Model):
32    b = fields.List(fields.Map(fields.String(), fields.BinData()))
33
34
35class TurboZlew(Zlew):
36    c = fields.Set(fields.Binary())
37    d = fields.Object(Piwo)
38    e = fields.Integer(default=3)
39
40
41class TestModel(unittest.TestCase):
42    def test_field_name(self):
43        self.assertEqual(Piwo.a.name, 'a')
44        self.assertEqual(Zlew.b.name, 'b')
45        self.assertEqual(Zlew.b.element.name, 'b.element')
46        self.assertEqual(Zlew.b.element.key.name, 'b.element.key')
47        self.assertEqual(Zlew.b.element.value.name, 'b.element.value')
48        self.assertEqual(TurboZlew.c.name, 'c')
49        self.assertEqual(TurboZlew.c.element.name, 'c.element')
50        self.assertEqual(set(Piwo.fields), {Piwo.a})
51        self.assertEqual(set(Zlew.fields), {Zlew.b})
52        self.assertEqual(set(TurboZlew.fields), {
53            Zlew.b, TurboZlew.c, TurboZlew.d, TurboZlew.e})
54
55    if six.PY3:
56        def test_ordering(self):
57            class MultiZlew(Model):
58                a = fields.Boolean()
59                b = fields.Boolean()
60                c = fields.Boolean()
61                d = fields.Boolean()
62                e = fields.Boolean()
63                f = fields.Boolean()
64                g = fields.Boolean()
65                h = fields.Boolean()
66                i = fields.Boolean()
67
68            self.assertEqual(MultiZlew.fields, [
69                MultiZlew.a,
70                MultiZlew.b,
71                MultiZlew.c,
72                MultiZlew.d,
73                MultiZlew.e,
74                MultiZlew.f,
75                MultiZlew.g,
76                MultiZlew.h,
77                MultiZlew.i,
78            ])
79
80    def test_init(self):
81        a = Piwo(a=True)
82        b = Piwo(a=True)
83        c = Piwo(a=False)
84        d = Zlew()
85        e = TurboZlew(d=a)
86        self.assertEqual(a.a, True)
87        self.assertEqual(c.a, False)
88        self.assertEqual(d.b, [])
89        self.assertEqual(e.b, [])
90        self.assertEqual(e.c, set())
91        self.assertEqual(e.d, a)
92        self.assertEqual(e.e, 3)
93        self.assertEqual(a, a)
94        self.assertEqual(d, d)
95        self.assertEqual(e, e)
96        self.assertEqual(a, b)
97        self.assertNotEqual(a, c)
98        self.assertNotEqual(a, d)
99        self.assertNotEqual(a, e)
100        self.assertNotEqual(d, e)
101        with self.assertRaises(SchemaError):
102            Piwo(a=None)
103        with self.assertRaises(SchemaError):
104            Piwo()
105        with self.assertRaises(TypeError):
106            Piwo(a=True, b='zlew')
107        with self.assertRaises(SchemaError):
108            TurboZlew()
109        with self.assertRaises(SchemaError):
110            TurboZlew(d=d)
111
112    def test_dump(self):
113        a = Piwo(a=True)
114        da = a.dump()
115        self.assertEqual(da, {'a': True})
116        for x in da:
117            self.assertIsInstance(x, six.text_type)
118
119        b = Zlew(b=[{'a': BinData(8, []), 'b': BinData(12, [0x123])}, {}])
120        db = b.dump()
121        self.assertEqual(db, {
122            'b': [
123                {
124                    'a': BinData(8, []),
125                    'b': BinData(12, [0x123]),
126                },
127                {},
128            ]
129        })
130        for x in db:
131            self.assertIsInstance(x, six.text_type)
132
133        c = TurboZlew(b=[{}], c={b'abc', b'def'}, d=Piwo(a=False), e=7)
134        dc = c.dump()
135        self.assertEqual(dc, {
136            'b': [{}],
137            'c': dc['c'],
138            'd': {'a': False},
139            'e': 7,
140        })
141        self.assertIsInstance(dc['c'], list)
142        self.assertEqual(set(dc['c']), {b'abc', b'def'})
143
144        d = TurboZlew(d=a)
145        dd = d.dump()
146        self.assertEqual(dd, {
147            'b': [],
148            'c': [],
149            'd': {'a': True},
150            'e': 3,
151        })
152
153    def test_load(self):
154        a = Piwo.load({
155            'a': True,
156        })
157        self.assertEqual(a, Piwo(a=True))
158        b = Zlew.load({})
159        self.assertEqual(b, Zlew())
160        c = Zlew.load({'b': [{}]})
161        self.assertEqual(c, Zlew(b=[{}]))
162        d = TurboZlew.load({
163            'd': {'a': True}
164        })
165        self.assertEqual(d, TurboZlew(d=a))
166        with self.assertRaises(SchemaError):
167            Piwo.load({})
168        with self.assertRaises(SchemaError):
169            Piwo.load({'a': None})
170        with self.assertRaises(SchemaError):
171            Piwo.load({'a': True, 'b': True})
172        with self.assertRaises(SchemaError):
173            Piwo.load('piwo')
174        with self.assertRaises(SchemaError):
175            Zlew.load([])
176        with self.assertRaises(SchemaError):
177            Zlew.load({'b': {}})
178        with self.assertRaises(SchemaError):
179            Zlew.load({'d': {'a': False}})
180