optimism 3.1__tar.gz → 3.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {optimism-3.1 → optimism-3.1.2}/PKG-INFO +3 -3
  2. optimism-3.1.2/optimism/__init__.py +21 -0
  3. optimism-3.1.2/optimism/examples/a.txt +2 -0
  4. optimism-3.1.2/optimism/examples/b.txt +3 -0
  5. optimism-3.1.2/optimism/examples/bad.py +6 -0
  6. optimism-3.1.2/optimism/examples/basic.py +72 -0
  7. optimism-3.1.2/optimism/examples/bits.py +28 -0
  8. optimism-3.1.2/optimism/examples/block.py +30 -0
  9. optimism-3.1.2/optimism/examples/catch_and_release.py +44 -0
  10. optimism-3.1.2/optimism/examples/code.py +96 -0
  11. optimism-3.1.2/optimism/examples/core.py +40 -0
  12. optimism-3.1.2/optimism/examples/doc_example.py +34 -0
  13. optimism-3.1.2/optimism/examples/doctests.py +396 -0
  14. optimism-3.1.2/optimism/examples/errors.py +6 -0
  15. optimism-3.1.2/optimism/examples/files.py +50 -0
  16. optimism-3.1.2/optimism/examples/fragments.py +23 -0
  17. optimism-3.1.2/optimism/examples/io_example.py +5 -0
  18. optimism-3.1.2/optimism/examples/literals.py +54 -0
  19. optimism-3.1.2/optimism/examples/memoryReports.py +9 -0
  20. optimism-3.1.2/optimism/examples/multi.py +16 -0
  21. optimism-3.1.2/optimism/examples/reverse_tracing.py +303 -0
  22. optimism-3.1.2/optimism/examples/runfile.py +58 -0
  23. optimism-3.1.2/optimism/examples/skip.py +38 -0
  24. optimism-3.1.2/optimism/examples/structure.py +114 -0
  25. optimism-3.1.2/optimism/examples/suites.py +67 -0
  26. optimism-3.1.2/optimism/examples/tracing.py +12 -0
  27. {optimism-3.1 → optimism-3.1.2/optimism}/optimism.py +68 -38
  28. optimism-3.1.2/optimism/py.typed +1 -0
  29. optimism-3.1.2/optimism/test_examples.py +1396 -0
  30. {optimism-3.1 → optimism-3.1.2}/optimism.egg-info/PKG-INFO +3 -3
  31. optimism-3.1.2/optimism.egg-info/SOURCES.txt +37 -0
  32. {optimism-3.1 → optimism-3.1.2}/setup.cfg +7 -3
  33. optimism-3.1/optimism.egg-info/SOURCES.txt +0 -10
  34. {optimism-3.1 → optimism-3.1.2}/LICENSE.txt +0 -0
  35. {optimism-3.1 → optimism-3.1.2}/README.md +0 -0
  36. {optimism-3.1 → optimism-3.1.2}/optimism.egg-info/dependency_links.txt +0 -0
  37. {optimism-3.1 → optimism-3.1.2}/optimism.egg-info/requires.txt +0 -0
  38. {optimism-3.1 → optimism-3.1.2}/optimism.egg-info/top_level.txt +0 -0
  39. {optimism-3.1 → optimism-3.1.2}/pyproject.toml +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: optimism
3
- Version: 3.1
4
- Summary: Very simple testing framework suitable for beginner programmers, with easy functions for accomplishing most common testing tasks like providing input. Use with Python >=3.9 for best results, but it should be compatible with Python >=3.6.
3
+ Version: 3.1.2
4
+ Summary: Very simple testing framework suitable for beginner programmers, with easy functions for accomplishing most common testing tasks like providing input. Requires Python 3.8+.
5
5
  Home-page: https://cs.wellesley.edu/~pmwh/optimism/docs/optimism.html
6
6
  Author: Peter Mawhorter
7
7
  Author-email: pmawhort@wellesley.edu
@@ -14,7 +14,7 @@ Classifier: License :: OSI Approved :: BSD License
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Natural Language :: English
16
16
  Classifier: Topic :: Education
17
- Requires-Python: >=3.6
17
+ Requires-Python: >=3.8
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE.txt
20
20
  Provides-Extra: test
@@ -0,0 +1,21 @@
1
+ """
2
+ This package init just imports everything from optimism.py, including
3
+ explicitly the version number (which otherwise would be skipped since it
4
+ starts with '_'). That way, importing optimism-the-package is the same as
5
+ importing optimism-the-file, except that private variables are not
6
+ exported by the package. So you can distribute the package OR just the
7
+ optimism.py file and both should work the same.
8
+ """
9
+
10
+ from .optimism import *
11
+
12
+ # Setuptools versions on Python 3.10 won't allow us to just import the
13
+ # version from optimism, but we want the version to be defined in that
14
+ # file so that a single-file distribution is equivalent to this packaged
15
+ # distribution. So we define a version here as well, but...
16
+ __version__ = "3.1.2"
17
+
18
+ # ...then we assert it matches so testing will catch it if I forget to
19
+ # keep them in sync before a release. T_T
20
+ from .optimism import __version__ as match
21
+ assert __version__ == match
@@ -0,0 +1,2 @@
1
+ abc
2
+ def
@@ -0,0 +1,3 @@
1
+ 1
2
+ 2
3
+ 3
@@ -0,0 +1,6 @@
1
+ def f():
2
+ """
3
+ Function which crashes.
4
+ """
5
+ z = 3 / 0
6
+ print(z)
@@ -0,0 +1,72 @@
1
+ """
2
+ Basic demonstration of optimism core testing functionality.
3
+ """
4
+
5
+ import optimism
6
+
7
+
8
+ # Simple example function
9
+ def f(x, y):
10
+ "Example function"
11
+ return x + y + 1
12
+
13
+
14
+ # Simple test for that function
15
+ t = optimism.testFunction(f)
16
+ t.case(1, 2).checkReturnValue(4) # line 16
17
+
18
+
19
+ # Function that prints multiple lines of output
20
+ def display(message):
21
+ print("The message is:")
22
+ print('-' + message + '-')
23
+
24
+
25
+ # Multi-line output test
26
+ t = optimism.testFunction(display)
27
+ t.case('hello').checkPrintedLines('The message is:', '-hello-') # line 27
28
+
29
+
30
+ def askNameAge():
31
+ "A function that uses input."
32
+ name = input("What is your name? ")
33
+ age = input("How old are you? ")
34
+ return (name, age)
35
+
36
+
37
+ # One test case with specific inputs that checks both the return value
38
+ # and what is printed
39
+ test = optimism.testFunction(askNameAge) # line 39
40
+ case = test.case()
41
+ case.provideInputs("Name", "thirty")
42
+ case.checkReturnValue(('Name', 'thirty')) # line 42
43
+ case.checkPrintedLines( # line 43
44
+ 'What is your name? Name',
45
+ 'How old are you? thirty' # line 45
46
+ )
47
+
48
+ optimism.showSummary()
49
+
50
+ # These checks will show details about the expressions used (like the
51
+ # value of x):
52
+ x = 3
53
+ y = 4
54
+ optimism.testFunction(f).case(x + x, y).checkReturnValue(10) # fails (is 11)
55
+ optimism.expect(f(x + x, y), 10) # fails; shows x
56
+
57
+ # Increase detail level
58
+ optimism.detailLevel(1)
59
+
60
+ c = optimism.testFunction(display).case('nope')
61
+ c.checkReturnValue(False) # fails (result is None)
62
+ c.checkPrintedLines('The message is:', '-nope-') # succeeds
63
+
64
+ optimism.detailLevel(0)
65
+ c.checkPrintedLines('The message is:', '-yep-') # fails
66
+
67
+ # For loop test
68
+ for x in range(3):
69
+ t = optimism.testFunction(f).case(x, x).checkReturnValue(5)
70
+ # fails except when x == 2
71
+
72
+ optimism.showSummary()
@@ -0,0 +1,28 @@
1
+ import optimism as opt
2
+
3
+ x = [1, 2, 3]
4
+ y = [4, 5, 6]
5
+ x.append(y)
6
+
7
+ opt.detailLevel(1)
8
+
9
+ opt.expect(x, [1, 2, 3, [4, 5, 6]])
10
+
11
+ y.pop()
12
+ opt.expect(x, [1, 2, 3, [4, 5]])
13
+ opt.expect(x[3], y)
14
+ opt.expect(x[3][-1], 5)
15
+
16
+ x.pop()
17
+ opt.expect(x, [1, 2, 3])
18
+ opt.expect(x[1], 2)
19
+
20
+ opt.expect(x, [1, 2, 3])
21
+ x.pop()
22
+ opt.expect(x, [1, 2])
23
+
24
+ # This... doesn't work
25
+ opt.expect(x[-1], x.pop())
26
+
27
+ opt.expectType(x, list)
28
+ opt.expectType(x[0], int)
@@ -0,0 +1,30 @@
1
+ import optimism as opt
2
+
3
+ x = 3
4
+
5
+ m = opt.testBlock(
6
+ """\
7
+ print(x)
8
+ x += 1
9
+ print(x)"""
10
+ )
11
+ c = m.case()
12
+ c.checkPrintedLines('3', '4')
13
+ c.checkVariableValue('x', 5)
14
+ c = m.case(x=5)
15
+ c.checkPrintedLines('5', '6')
16
+ c.checkVariableValue('x', 6)
17
+
18
+
19
+ m = opt.testBlock(
20
+ """\
21
+ x = 3
22
+ print(x)
23
+ x += 1
24
+ print(x)
25
+ x += 1"""
26
+ )
27
+ c = m.case()
28
+ c.checkPrintedLines('3', '4')
29
+ c.checkVariableValue('x', 5)
30
+ c.checkVariableValue('x', 6)
@@ -0,0 +1,44 @@
1
+ import optimism as opt
2
+
3
+
4
+ def interactive():
5
+ """
6
+ An interactive function for testing purposes.
7
+ """
8
+ x = input('Y?')
9
+ print(x + ' Z!')
10
+ return x
11
+
12
+
13
+ # Call it once before testing
14
+ interactive()
15
+
16
+ m = opt.testFunction(interactive)
17
+ c = m.case()
18
+ c.provideInputs('Q')
19
+ c.checkPrintedLines('Y?Q', 'Q Z!')
20
+ c.checkReturnValue('Q')
21
+
22
+ c = m.case()
23
+ c.provideInputs('A')
24
+ c.checkPrintedLines('Y?A', 'A Z!')
25
+ c.checkReturnValue('A')
26
+
27
+ c = m.case()
28
+ c.provideInputs('A')
29
+ c.provideInputs('B') # this is okay, and redefines the inputs
30
+ c.checkPrintedLines('Y?B', 'B Z!')
31
+ c.checkReturnValue('B')
32
+
33
+
34
+ # This isn't allowed
35
+ try:
36
+ c.provideInputs('N')
37
+ except opt.TestError:
38
+ print("Re-providing input was blocked.")
39
+
40
+ # Does input/output capturing mess with this?
41
+ print("Hello")
42
+
43
+ # Call it again after releasing input & output
44
+ interactive()
@@ -0,0 +1,96 @@
1
+ """
2
+ Basic demonstration of optimism code-structure checking functionality.
3
+ """
4
+
5
+ import optimism
6
+
7
+ optimism.skipChecksAfterFail(None)
8
+
9
+
10
+ def askNameAge():
11
+ "A function that uses input."
12
+ name = input("What is your name? ")
13
+ age = input("How old are you? ")
14
+ return (name, age)
15
+
16
+
17
+ # Test manager for that function
18
+ tester = optimism.testFunction(askNameAge)
19
+
20
+ # A structural check to ensure that the above function uses `input`
21
+ tester.checkCodeContains(optimism.Call('input'))
22
+
23
+ # Checks with bounds on the number of use sites
24
+ tester.checkCodeContains(optimism.Call('input', min=2))
25
+ tester.checkCodeContains(optimism.Call('input', n=2))
26
+ tester.checkCodeContains(optimism.Call('input', max=2))
27
+
28
+ # A simple loop that uses print multiple times
29
+ for x in range(4):
30
+ print(x)
31
+
32
+ # Some operators
33
+ if x < 3:
34
+ print(x not in (1, 2, 3))
35
+
36
+
37
+ # Tester for this file
38
+ fileTester = optimism.testFile(__file__)
39
+
40
+ fileTester.checkCodeContains(optimism.Def()) # succeeds
41
+ fileTester.checkCodeContains(optimism.Def('askNameAge')) # succeeds
42
+ fileTester.checkCodeContains(optimism.Def('functionName')) # fails
43
+
44
+ fileTester.checkCodeContains(optimism.Def().contains(optimism.Return())) # ✓
45
+ fileTester.checkCodeContains(optimism.Def().contains(optimism.Loop())) # ✗
46
+ fileTester.checkCodeContains(optimism.Loop().contains(optimism.Def())) # ✗
47
+ fileTester.checkCodeContains(optimism.Loop(only="while")) # ✗
48
+ fileTester.checkCodeContains(optimism.Loop(only="for")) # ✓
49
+
50
+ fileTester.checkCodeContains(
51
+ optimism.Loop().contains(optimism.Call('print'))
52
+ ) # ✓
53
+ fileTester.checkCodeContains(
54
+ optimism.Loop().contains(optimism.Call('range'))
55
+ ) # ✓
56
+ fileTester.checkCodeContains(
57
+ optimism.Loop().contains(optimism.Call('print', n=1))
58
+ ) # ✓
59
+ fileTester.checkCodeContains(
60
+ optimism.Loop().contains(optimism.Call('print', n=4))
61
+ ) # ✗
62
+ fileTester.checkCodeContains(
63
+ optimism.Loop().contains(optimism.Call('print', min=4))
64
+ ) # ✗
65
+ fileTester.checkCodeContains(
66
+ optimism.Loop().contains(optimism.Call('print', max=1))
67
+ ) # ✓
68
+ fileTester.checkCodeContains(
69
+ optimism.Loop().contains(optimism.Call('print', max=0))
70
+ ) # ✗
71
+ fileTester.checkCodeContains(
72
+ optimism.Loop().contains(optimism.Call('notCalled', min=0))
73
+ ) # ✓
74
+
75
+ fileTester.checkCodeContains(
76
+ optimism.IfElse().contains(optimism.Operator('<'))
77
+ ) # ✓
78
+ fileTester.checkCodeContains(
79
+ optimism.IfElse().contains(optimism.Operator('>'))
80
+ ) # ✗
81
+ fileTester.checkCodeContains(
82
+ optimism.IfElse().contains(optimism.Operator('in'))
83
+ ) # ✓
84
+ fileTester.checkCodeContains(
85
+ optimism.IfElse().contains(optimism.Operator('not in'))
86
+ ) # ✓
87
+
88
+ # Testing constant matching w/ types/values
89
+ ('a', 2, 5.0)
90
+ fileTester.checkCodeContains(optimism.Constant('a')) # ✓
91
+ fileTester.checkCodeContains(optimism.Constant(2)) # ✓
92
+ fileTester.checkCodeContains(optimism.Constant(4.0 / 2)) # ✓
93
+ fileTester.checkCodeContains(optimism.Constant(4.0 / 2, float)) # ✗
94
+ fileTester.checkCodeContains(optimism.Constant(4.0 / 2, int)) # ✓
95
+ fileTester.checkCodeContains(optimism.Constant(5.0, int)) # ✗
96
+ fileTester.checkCodeContains(optimism.Constant(5.0, float)) # ✓
@@ -0,0 +1,40 @@
1
+ from optimism import *
2
+
3
+ # Simple example function
4
+ def f(x, y):
5
+ "Example function"
6
+ return x + y + 1
7
+
8
+ # Simple test for that function
9
+ test = testFunction(f) # line 9
10
+ case = test.case(1, 2)
11
+ case.checkReturnValue(3) # line 11
12
+
13
+
14
+ # Function that prints multiple lines of output
15
+ def display(message):
16
+ print("The message is:")
17
+ print('-' + message + '-')
18
+
19
+
20
+ # One test case with two lines of output
21
+ test = testFunction(display) # line 20
22
+ case = test.case('hello')
23
+ case.checkPrintedLines('The message is:', '-hello-') # line 22
24
+
25
+
26
+ # A function that uses input
27
+ def askNameAge():
28
+ name = input("What is your name? ")
29
+ age = input("How old are you? ")
30
+ return (name, age)
31
+
32
+
33
+ test = testFunction(askNameAge) # line 31
34
+ case = test.case()
35
+ case.provideInputs("Name", "thirty")
36
+ case.checkReturnValue(('Name', 'thirty')) # line 34
37
+ case.checkPrintedLines(
38
+ 'What is your name? Name',
39
+ 'How old are you? thirty' # line 37
40
+ )
@@ -0,0 +1,34 @@
1
+ """
2
+ Module docstring.
3
+
4
+ >>> 5
5
+ 5
6
+ """
7
+
8
+ def f():
9
+ """
10
+ Inner docstring.
11
+
12
+ >>> f()
13
+ 5
14
+ """
15
+ return 5
16
+
17
+
18
+ class C:
19
+ """
20
+ Class docstring.
21
+
22
+ >>> C().c(10)
23
+ 5
24
+ """
25
+
26
+ def c(self, n):
27
+ """
28
+ Method docstring.
29
+
30
+ >>> c = C() # counts as an example
31
+ >>> c.c(10) # not a duplicate; different AST
32
+ 5
33
+ """
34
+ return n // 2