File: test_basic.py

package info (click to toggle)
python-super-collections 0.6.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 208 kB
  • sloc: python: 1,065; sh: 34; makefile: 3
file content (164 lines) | stat: -rw-r--r-- 4,097 bytes parent folder | download
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import os
import json
from dataclasses import dataclass
from typing import Dict


import pytest
from rich import print as rprint


from super_collections import SuperDict, SuperList

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))

SOLAR_SYSTEM = 'solar_system.json'


def test_dict():
    """
    Test Superdict
    """
    DATA = """{
        "name": "Mercury",
        "size": 4880,
        "mass": 3.30e23,
        "orbit": 57900000,
        "orbit_from": "Sun",
        "length_of_year": 88,
        "moons": [],
        "foo bar": 50,
        "items": "foobar"
      }"""
    
    mercury = json.loads(DATA)
    mercury = SuperDict(mercury)

    # normal diction
    assert 'name' in mercury
    assert 'size' in mercury

    # attributes
    assert mercury.name == 'Mercury'
    assert mercury.size == 4880
    assert mercury.orbit_from == "Sun"

    # discrovery
    assert 'name' in mercury.properties()
    assert 'name' in dir(mercury)
    assert 'orbit_from' in dir(mercury)

    # invalid identifier
    invalid_id = 'foo bar'
    assert invalid_id in mercury
    assert invalid_id not in dir(mercury)
    assert mercury[invalid_id] == 50 # but reachable as a dict key

    # not a valid property (is masked by the standard method `items()`)
    assert mercury['items'] == 'foobar'
    assert 'items' not in mercury.properties()
    assert mercury.items != 'foobar'
    assert callable(mercury.items)
    assert ('size', 4880) in mercury.items()
 



def test_update_list():
    "Update super lists"

    l = SuperList(({'foo': 5, 'bar': 5}, 'baz'))
    assert l[0].foo == 5

    l2 = [6, {'barbaz': 45}]
    l.extend(l2)

    last = l[-1]
    assert last.barbaz == 45


    l3 = ["hello", {'foobar': 30}]

    # add a list to a SuperList -> Superlist
    r1 = l + l3
    assert isinstance(r1, SuperList)
    last = r1[-1]
    assert last.foobar == 30 # this is a SuperDict

    # CAUTION: add a SuperList to a List -> list
    r2 = l3 + l
    assert not isinstance(r2, SuperList)
    with pytest.raises(AttributeError):
        second = r2[1]
        second.foobar # this is NOT a SuperDict


def test_fancy_types():
    """
    Test fancy classes
    """
    class Person:
        def __init__(self, name: str, age: int, active: bool = True) -> None:
            self.name = name
            self.age = age
            self.active = active

        def __repr__(self) -> str:
            return f"Person(name={self.name!r}, age={self.age}, active={self.active})"

        def dict(self) -> Dict[str, object]:
            return {
                "name": self.name,
                "age": self.age,
                "active": self.active
            }


    p = Person("Joe", 42)
    rprint(SuperDict(p).to_json())

    # -----------
    # Dataclass
    # -----------
    @dataclass
    class Book:
        title: str
        author: str
        year: int
    b = Book(title="1984", author="George Orwell", year=1949)
    rprint(SuperDict(b).to_json())
    


def test_read_json_file():
    """
    Read the JSON file using the function and convert it into a SuperDict
    """
    filename = os.path.join(CURRENT_DIR, SOLAR_SYSTEM)
    with open(filename, 'r') as file:
        data = json.load(file)
    solar_system = SuperDict(data)

    # attributes are recursively available, including with lists:
    units = solar_system.units
    assert units.size == 'km'
    for planet in solar_system.planets:
        assert isinstance(planet, SuperDict)
        print (planet.name, planet.size)
        for moon in planet.moons:
            print(f"- {moon.name}", moon.size)

    ADDITIONAL = [{'name': 'Foo', 'size': 45895},
                  {'name': 'Bar', 'size': 59383}]
    new_planet_list = solar_system.planets + ADDITIONAL
    assert isinstance(new_planet_list, SuperList)
    last_planet = new_planet_list[-1]
    assert last_planet.name == 'Bar'
    assert last_planet.size == 59383
    with pytest.raises(AttributeError):
        last_planet.orbit
    last_planet.orbit = 5930590
    assert last_planet.orbit == 5930590 

if __name__ == "__main__":
    pytest.main()