1# Change the following to True to get a much more comprehensive set of tests
2# to run, albeit, which take considerably longer.
3
4full_tests = False
5
6
7def test(fmt, *args):
8    print("{:8s}".format(fmt) + ">" + fmt.format(*args) + "<")
9
10
11def test_fmt(conv, fill, alignment, sign, prefix, width, precision, type, arg):
12    fmt = "{"
13    if conv:
14        fmt += "!"
15        fmt += conv
16    fmt += ":"
17    if alignment:
18        fmt += fill
19        fmt += alignment
20    fmt += sign
21    fmt += prefix
22    fmt += width
23    if precision:
24        fmt += "."
25        fmt += precision
26    fmt += type
27    fmt += "}"
28    test(fmt, arg)
29    if fill == "0" and alignment == "=":
30        fmt = "{:"
31        fmt += sign
32        fmt += prefix
33        fmt += width
34        if precision:
35            fmt += "."
36            fmt += precision
37        fmt += type
38        fmt += "}"
39        test(fmt, arg)
40
41
42eg_nums = (
43    0.0,
44    -0.0,
45    0.1,
46    1.234,
47    12.3459,
48    1.23456789,
49    123456789.0,
50    -0.0,
51    -0.1,
52    -1.234,
53    -12.3459,
54    1e4,
55    1e-4,
56    1e5,
57    1e-5,
58    1e6,
59    1e-6,
60    1e10,
61    1e37,
62    -1e37,
63    1e-37,
64    -1e-37,
65    1.23456e8,
66    1.23456e7,
67    1.23456e6,
68    1.23456e5,
69    1.23456e4,
70    1.23456e3,
71    1.23456e2,
72    1.23456e1,
73    1.23456e0,
74    1.23456e-1,
75    1.23456e-2,
76    1.23456e-3,
77    1.23456e-4,
78    1.23456e-5,
79    1.23456e-6,
80    1.23456e-7,
81    1.23456e-8,
82    -1.23456e8,
83    -1.23456e7,
84    -1.23456e6,
85    -1.23456e5,
86    -1.23456e4,
87    -1.23456e3,
88    -1.23456e2,
89    -1.23456e1,
90    -1.23456e0,
91    -1.23456e-1,
92    -1.23456e-2,
93    -1.23456e-3,
94    -1.23456e-4,
95    -1.23456e-5,
96    -1.23456e-6,
97    -1.23456e-7,
98    -1.23456e-8,
99)
100
101if full_tests:
102    for type in ("e", "E", "g", "G", "n"):
103        for width in ("", "4", "6", "8", "10"):
104            for alignment in ("", "<", ">", "=", "^"):
105                for fill in ("", "@", "0", " "):
106                    for sign in ("", "+", "-", " "):
107                        for prec in ("", "1", "3", "6"):
108                            for num in eg_nums:
109                                test_fmt("", fill, alignment, sign, "", width, prec, type, num)
110
111# Note: We use 1.23459 rather than 1.2345 because '{:3f}'.format(1.2345)
112#       rounds differently than print("%.3f", 1.2345);
113
114f_nums = (
115    0.0,
116    -0.0,
117    0.0001,
118    0.001,
119    0.01,
120    0.1,
121    1.0,
122    10.0,
123    0.0012,
124    0.0123,
125    0.1234,
126    1.23459,
127    12.3456,
128    -0.0001,
129    -0.001,
130    -0.01,
131    -0.1,
132    -1.0,
133    -10.0,
134    -0.0012,
135    -0.0123,
136    -0.1234,
137    -1.23459,
138    -12.3456,
139)
140
141if full_tests:
142    for type in ("f", "F"):
143        for width in ("", "4", "6", "8", "10"):
144            for alignment in ("", "<", ">", "=", "^"):
145                for fill in ("", " ", "0", "@"):
146                    for sign in ("", "+", "-", " "):
147                        # An empty precision defaults to 6, but when uPy is
148                        # configured to use a float, we can only use a
149                        # precision of 6 with numbers less than 10 and still
150                        # get results that compare to CPython (which uses
151                        # long doubles).
152                        for prec in ("1", "2", "3"):
153                            for num in f_nums:
154                                test_fmt("", fill, alignment, sign, "", width, prec, type, num)
155                        for num in int_nums2:
156                            test_fmt("", fill, alignment, sign, "", width, "", type, num)
157
158pct_nums1 = (0.1, 0.58, 0.99, -0.1, -0.58, -0.99)
159pct_nums2 = (True, False, 1, 0, -1)
160
161if full_tests:
162    type = "%"
163    for width in ("", "4", "6", "8", "10"):
164        for alignment in ("", "<", ">", "=", "^"):
165            for fill in ("", " ", "0", "@"):
166                for sign in ("", "+", "-", " "):
167                    # An empty precision defaults to 6, but when uPy is
168                    # configured to use a float, we can only use a
169                    # precision of 6 with numbers less than 10 and still
170                    # get results that compare to CPython (which uses
171                    # long doubles).
172                    for prec in ("1", "2", "3"):
173                        for num in pct_nums1:
174                            test_fmt("", fill, alignment, sign, "", width, prec, type, num)
175                    for num in pct_nums2:
176                        test_fmt("", fill, alignment, sign, "", width, "", type, num)
177else:
178    for num in pct_nums1:
179        test_fmt("", "", "", "", "", "", "1", "%", num)
180
181# We don't currently test a type of '' with floats (see the detailed comment
182# in  objstr.c)
183