testeranto 0.199.0 → 0.200.1
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.
- package/bin/test_runner +0 -0
- package/bin/testeranto +0 -0
- package/bundle.js +5 -4
- package/cmd/test_runner/main.go +65 -0
- package/cmd/testeranto/main.go +37 -0
- package/dist/common/src/PM/main.js +126 -11
- package/dist/common/src/PM/pitonoRunner.js +54 -0
- package/dist/common/src/components/pure/TestPageView.js +180 -65
- package/dist/common/src/components/stateful/TestPage.js +50 -11
- package/dist/common/src/lib/abstractBase.test/index.js +1 -0
- package/dist/common/src/run.js +48 -82
- package/dist/common/src/{build.js → testeranto.js} +107 -55
- package/dist/common/src/utils/golingvuMetafile.js +116 -0
- package/dist/common/src/utils/logFiles.js +2 -1
- package/dist/common/src/utils/pitonoMetafile.js +67 -0
- package/dist/common/src/utils.js +40 -1
- package/dist/common/testeranto.config.js +23 -21
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/module/src/PM/main.js +126 -11
- package/dist/module/src/PM/pitonoRunner.js +47 -0
- package/dist/module/src/components/pure/TestPageView.js +180 -65
- package/dist/module/src/components/stateful/TestPage.js +50 -11
- package/dist/module/src/lib/abstractBase.test/index.js +1 -0
- package/dist/module/src/run.js +49 -45
- package/dist/module/src/{build.js → testeranto.js} +107 -55
- package/dist/module/src/utils/golingvuMetafile.js +109 -0
- package/dist/module/src/utils/logFiles.js +2 -1
- package/dist/module/src/utils/pitonoMetafile.js +60 -0
- package/dist/module/src/utils.js +40 -1
- package/dist/module/testeranto.config.js +23 -21
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/prebuild/App.js +81 -17
- package/dist/prebuild/testeranto.mjs +3249 -0
- package/dist/types/src/PM/main.d.ts +2 -0
- package/dist/types/src/PM/pitonoRunner.d.ts +7 -0
- package/dist/types/src/Types.d.ts +1 -1
- package/dist/types/src/run.d.ts +0 -1
- package/dist/types/src/utils/golingvuMetafile.d.ts +19 -0
- package/dist/types/src/utils/logFiles.d.ts +5 -1
- package/dist/types/src/utils/pitonoMetafile.d.ts +7 -0
- package/dist/types/src/utils.d.ts +5 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/index.md +13 -13
- package/example/test_example.py +106 -0
- package/go.mod +3 -0
- package/package.json +2 -2
- package/pitono/__init__.py +54 -0
- package/pitono/base_given.py +131 -0
- package/pitono/base_suite.py +95 -0
- package/pitono/base_then.py +50 -0
- package/pitono/base_when.py +52 -0
- package/pitono/core_generator.py +110 -0
- package/pitono/pitono.egg-info/PKG-INFO +17 -0
- package/pitono/pitono.egg-info/SOURCES.txt +7 -0
- package/pitono/pitono.egg-info/dependency_links.txt +1 -0
- package/pitono/pitono.egg-info/entry_points.txt +2 -0
- package/pitono/pitono.egg-info/top_level.txt +1 -0
- package/pitono/pyproject.toml +26 -0
- package/pitono/setup.py +40 -0
- package/pitono/simple_adapter.py +24 -0
- package/pitono/types.py +78 -0
- package/sampleMetafile.json +56 -0
- package/src/PM/main.ts +146 -17
- package/src/PM/pitonoRunner.ts +49 -0
- package/src/Types.ts +1 -1
- package/src/components/pure/TestPageView.tsx +175 -8
- package/src/components/stateful/TestPage.tsx +57 -16
- package/src/core/types.go +36 -0
- package/src/golingvu/README.md +3 -0
- package/src/golingvu/base_given.go +76 -0
- package/src/golingvu/base_suite.go +39 -0
- package/src/golingvu/base_suite_test.go +197 -0
- package/src/golingvu/base_then.go +21 -0
- package/src/golingvu/base_when.go +21 -0
- package/src/golingvu/golingvu.go +179 -0
- package/src/golingvu/test_adapter.go +33 -0
- package/src/golingvu/types.go +86 -0
- package/src/lib/abstractBase.test/index.ts +1 -0
- package/src/pitono/README.md +3 -0
- package/src/run.ts +48 -48
- package/src/templates/frontpage.html +26 -17
- package/src/{build.ts → testeranto.ts} +128 -58
- package/src/utils/golingvuMetafile.ts +165 -0
- package/src/utils/logFiles.ts +2 -1
- package/src/utils/pitonoMetafile.ts +68 -0
- package/src/utils.ts +38 -1
- package/testeranto/App.js +81 -17
- package/testeranto/metafiles/golang/core.json +72 -0
- package/testeranto/metafiles/node/core.json +21 -459
- package/testeranto/metafiles/pure/core.json +18 -119
- package/testeranto/metafiles/web/core.json +37 -16797
- package/testeranto/reports/core/config.json +8 -40
- package/testeranto/reports/core/src/lib/BaseSuite.test/node.test/node/lint_errors.txt +6 -0
- package/testeranto/reports/core/src/lib/BaseSuite.test/node.test/node/prompt.txt +12 -1
- package/testeranto/reports/core/src/lib/BaseSuite.test/pure.test/pure/lint_errors.txt +2 -0
- package/testeranto/reports/core/src/lib/BaseSuite.test/pure.test/pure/prompt.txt +11 -1
- package/testeranto/reports/core/src/lib/BaseSuite.test/web.test/web/lint_errors.txt +2 -0
- package/testeranto/reports/core/src/lib/BaseSuite.test/web.test/web/prompt.txt +13 -3
- package/testeranto/reports/core/summary.json +9 -45
- package/testeranto.config.ts +25 -21
- package/tsc.log +46 -7
- package/dist/common/src/lib/mocks.test.js +0 -11
- package/dist/module/src/lib/mocks.test.js +0 -11
- package/dist/prebuild/ReportServer.mjs +0 -227
- package/dist/prebuild/build.mjs +0 -578
- package/dist/prebuild/mothership/index.mjs +0 -22
- package/dist/prebuild/run.mjs +0 -2290
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/types/src/lib/mocks.test.d.ts +0 -0
- package/src/lib/mocks.test.ts +0 -11
- package/testeranto/reports/core/src/Pure.test/pure/exit.log +0 -0
- package/testeranto/reports/core/src/Pure.test/pure/lint_errors.txt +0 -0
- package/testeranto/reports/core/src/Pure.test/pure/message.txt +0 -17
- package/testeranto/reports/core/src/Pure.test/pure/prompt.txt +0 -14
- package/testeranto/reports/core/src/Pure.test/pure/type_errors.txt +0 -66
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/debug.log +0 -0
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/error.log +0 -67
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/exit.log +0 -1
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/info.log +0 -2
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/lint_errors.txt +0 -0
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/message.txt +0 -17
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/prompt.txt +0 -16
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/tests.json +0 -68
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/type_errors.txt +0 -56
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/warn.log +0 -0
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/debug.log +0 -0
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/error.log +0 -22
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/exit.log +0 -1
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/info.log +0 -2
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/lint_errors.txt +0 -13
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/message.txt +0 -17
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/prompt.txt +0 -16
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/tests.json +0 -88
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/type_errors.txt +0 -45
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/warn.log +0 -0
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/debug.log +0 -0
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/error.log +0 -0
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/exit.log +0 -1
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/info.log +0 -2
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/lint_errors.txt +0 -47
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/message.txt +0 -17
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/prompt.txt +0 -17
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/tests.json +0 -57
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/type_errors.txt +0 -99
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/warn.log +0 -0
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/exit.log +0 -1
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/lint_errors.txt +0 -0
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/message.txt +0 -17
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/prompt.txt +0 -17
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/stderr.log +0 -18
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/stdout.log +0 -0
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/type_errors.txt +0 -32
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/exit.log +0 -1
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/lint_errors.txt +0 -15
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/message.txt +0 -17
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/prompt.txt +0 -17
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/stderr.log +0 -66
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/stdout.log +0 -10
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/type_errors.txt +0 -47
- /package/dist/types/src/{build.d.ts → testeranto.d.ts} +0 -0
package/docs/index.md
CHANGED
|
@@ -35,7 +35,7 @@ async <I extends Ibdd_in_any, O extends Ibdd_out, M>(
|
|
|
35
35
|
input: I["iinput"],
|
|
36
36
|
testSpecification: ITestSpecification<I, O>,
|
|
37
37
|
testImplementation: ITestImplementation<I, O, M>,
|
|
38
|
-
testAdapter: Partial<
|
|
38
|
+
testAdapter: Partial<ITestAdapter<I>>,
|
|
39
39
|
testResourceRequirement: ITTestResourceRequest = defaultTestResourceRequirement
|
|
40
40
|
): Promise<Testeranto<I, O, M>>
|
|
41
41
|
```
|
|
@@ -52,7 +52,7 @@ import Testeranto from "testeranto/src/Node"; // <- import the Node main functio
|
|
|
52
52
|
|
|
53
53
|
import { implementation } from "./Rectangle.test.implementation";
|
|
54
54
|
import { specification } from "./Rectangle.test.specification";
|
|
55
|
-
import {
|
|
55
|
+
import { adapter } from "./Rectangle.test.adapter";
|
|
56
56
|
|
|
57
57
|
// Note the type parameters I, O, and M: these will be important later
|
|
58
58
|
export default Testeranto<
|
|
@@ -63,7 +63,7 @@ export default Testeranto<
|
|
|
63
63
|
Rectangle.prototype, // <- the subject of the test.
|
|
64
64
|
specification,
|
|
65
65
|
implementation,
|
|
66
|
-
|
|
66
|
+
adapter
|
|
67
67
|
);
|
|
68
68
|
```
|
|
69
69
|
|
|
@@ -75,7 +75,7 @@ import Testeranto from "testeranto/src/Web"; // <- import the Web main function
|
|
|
75
75
|
|
|
76
76
|
import { implementation } from "./Rectangle.test.implementation";
|
|
77
77
|
import { specification } from "./Rectangle.test.specification";
|
|
78
|
-
import {
|
|
78
|
+
import { adapter } from "./Rectangle.test.adapter";
|
|
79
79
|
|
|
80
80
|
// Note the type parameters I, O, and M: these will be important later
|
|
81
81
|
export default Testeranto<
|
|
@@ -86,7 +86,7 @@ export default Testeranto<
|
|
|
86
86
|
Rectangle.prototype, // <- the subject of the test.
|
|
87
87
|
specification,
|
|
88
88
|
implementation,
|
|
89
|
-
|
|
89
|
+
adapter
|
|
90
90
|
);
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -98,7 +98,7 @@ import Testeranto from "testeranto/src/Pure"; // <- import the Pure main functio
|
|
|
98
98
|
|
|
99
99
|
import { implementation } from "./Rectangle.test.implementation";
|
|
100
100
|
import { specification } from "./Rectangle.test.specification";
|
|
101
|
-
import {
|
|
101
|
+
import { adapter } from "./Rectangle.test.adapter";
|
|
102
102
|
|
|
103
103
|
// Note the type parameters I, O, and M: these will be important later
|
|
104
104
|
export default Testeranto<
|
|
@@ -109,7 +109,7 @@ export default Testeranto<
|
|
|
109
109
|
Rectangle.prototype, // <- the subject of the test.
|
|
110
110
|
specification,
|
|
111
111
|
implementation,
|
|
112
|
-
|
|
112
|
+
adapter
|
|
113
113
|
);
|
|
114
114
|
```
|
|
115
115
|
|
|
@@ -230,18 +230,18 @@ export const implementation: ITestImplementation<
|
|
|
230
230
|
};
|
|
231
231
|
```
|
|
232
232
|
|
|
233
|
-
#### The
|
|
233
|
+
#### The Adapter aka ITestAdapter
|
|
234
234
|
|
|
235
|
-
The test
|
|
235
|
+
The test adapter is code which is NOT business logic. The adapter adapts your test subject so that the BDD hooks can be applied. The adapter implements the traditional BDD steps "before all", "after all", "before each", "after each", etc
|
|
236
236
|
|
|
237
237
|
```ts
|
|
238
238
|
import {
|
|
239
239
|
Ibdd_in,
|
|
240
|
-
|
|
240
|
+
ITestAdapter,
|
|
241
241
|
} from "testeranto/src/CoreTypes";
|
|
242
242
|
|
|
243
243
|
// Note the type parameter. This is important!
|
|
244
|
-
export const testAdapter:
|
|
244
|
+
export const testAdapter: ITestAdapter<
|
|
245
245
|
I extends Ibdd_in,
|
|
246
246
|
> = {
|
|
247
247
|
beforeEach: async (subject, i) => {
|
|
@@ -358,7 +358,7 @@ import {
|
|
|
358
358
|
Ibdd_out,
|
|
359
359
|
ITestImplementation,
|
|
360
360
|
ITestSpecification,
|
|
361
|
-
|
|
361
|
+
ITestAdapter,
|
|
362
362
|
} from "testeranto/src/CoreTypes";
|
|
363
363
|
|
|
364
364
|
// The test subject
|
|
@@ -440,7 +440,7 @@ type M = {
|
|
|
440
440
|
};
|
|
441
441
|
};
|
|
442
442
|
|
|
443
|
-
const testAdapter:
|
|
443
|
+
const testAdapter: ITestAdapter<
|
|
444
444
|
I extends Ibdd_in,
|
|
445
445
|
> = {
|
|
446
446
|
beforeEach: async (subject, i) => {
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from pitono import Pitono, SimpleTestAdapter
|
|
3
|
+
from pitono.types import ITestSpecification, ITestImplementation, ITTestResourceRequest
|
|
4
|
+
from pitono.core_generator import PitonoCoreGenerator
|
|
5
|
+
|
|
6
|
+
# Define a simple test specification
|
|
7
|
+
def test_specification(suites, givens, whens, thens):
|
|
8
|
+
return {
|
|
9
|
+
'suites': suites,
|
|
10
|
+
'givens': givens,
|
|
11
|
+
'whens': whens,
|
|
12
|
+
'thens': thens
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
# Create a simple test implementation
|
|
16
|
+
test_implementation = ITestImplementation(
|
|
17
|
+
suites={},
|
|
18
|
+
givens={},
|
|
19
|
+
whens={},
|
|
20
|
+
thens={}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# Create a test resource requirement
|
|
24
|
+
test_resource_requirement = ITTestResourceRequest(ports=0)
|
|
25
|
+
|
|
26
|
+
# Create a test adapter
|
|
27
|
+
test_adapter = SimpleTestAdapter()
|
|
28
|
+
|
|
29
|
+
# Create uber_catcher
|
|
30
|
+
def uber_catcher(func):
|
|
31
|
+
try:
|
|
32
|
+
func()
|
|
33
|
+
except Exception as e:
|
|
34
|
+
print(f"Error: {e}")
|
|
35
|
+
|
|
36
|
+
# Create Pitono instance
|
|
37
|
+
pitono = Pitono(
|
|
38
|
+
input_val=None,
|
|
39
|
+
test_specification=test_specification,
|
|
40
|
+
test_implementation=test_implementation,
|
|
41
|
+
test_resource_requirement=test_resource_requirement,
|
|
42
|
+
test_adapter=test_adapter,
|
|
43
|
+
uber_catcher=uber_catcher
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
print("Pitono initialized successfully!")
|
|
47
|
+
|
|
48
|
+
# Test the core generator
|
|
49
|
+
def test_core_generator():
|
|
50
|
+
entry_points = ["example/test1.py", "example/test2.py"]
|
|
51
|
+
generator = PitonoCoreGenerator("test_suite", entry_points)
|
|
52
|
+
generator.write_core_json()
|
|
53
|
+
print("Core generator test completed!")
|
|
54
|
+
|
|
55
|
+
# Let's test running a simple suite
|
|
56
|
+
async def test_suite():
|
|
57
|
+
from pitono.base_suite import BaseSuite
|
|
58
|
+
from pitono.base_given import BaseGiven
|
|
59
|
+
from pitono.base_when import BaseWhen
|
|
60
|
+
from pitono.base_then import BaseThen
|
|
61
|
+
|
|
62
|
+
# Create a simple then implementation
|
|
63
|
+
class SimpleThen(BaseThen):
|
|
64
|
+
async def but_then(self, store, then_cb, test_resource_configuration, pm):
|
|
65
|
+
return True
|
|
66
|
+
|
|
67
|
+
# Create a simple when implementation
|
|
68
|
+
class SimpleWhen(BaseWhen):
|
|
69
|
+
async def and_when(self, store, when_cb, test_resource, pm):
|
|
70
|
+
return store
|
|
71
|
+
|
|
72
|
+
# Create a simple given implementation
|
|
73
|
+
class SimpleGiven(BaseGiven):
|
|
74
|
+
async def given_that(self, subject, test_resource_configuration, artifactory, given_cb, initial_values, pm):
|
|
75
|
+
return {"initial": "store"}
|
|
76
|
+
|
|
77
|
+
# Create test instances
|
|
78
|
+
then = SimpleThen("test then", lambda: True)
|
|
79
|
+
when = SimpleWhen("test when", lambda: None)
|
|
80
|
+
given = SimpleGiven("test given", ["test feature"], [when], [then], lambda: None, {})
|
|
81
|
+
|
|
82
|
+
suite = BaseSuite("test suite", {"test_given": given})
|
|
83
|
+
|
|
84
|
+
# Mock functions
|
|
85
|
+
def artifactory(path, value):
|
|
86
|
+
print(f"Artifactory: {path} -> {value}")
|
|
87
|
+
|
|
88
|
+
def t_log(*args):
|
|
89
|
+
print("LOG:", *args)
|
|
90
|
+
|
|
91
|
+
# Run the suite
|
|
92
|
+
result = await suite.run(
|
|
93
|
+
None,
|
|
94
|
+
None,
|
|
95
|
+
artifactory,
|
|
96
|
+
t_log,
|
|
97
|
+
None
|
|
98
|
+
)
|
|
99
|
+
print(f"Suite result: {result.to_obj()}")
|
|
100
|
+
|
|
101
|
+
if __name__ == "__main__":
|
|
102
|
+
# Test core generator
|
|
103
|
+
test_core_generator()
|
|
104
|
+
|
|
105
|
+
# Run the test suite
|
|
106
|
+
asyncio.run(test_suite())
|
package/go.mod
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testeranto",
|
|
3
3
|
"description": "the AI powered BDD test framework for typescript projects",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.200.1",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "18.18.0"
|
|
7
7
|
},
|
|
@@ -129,6 +129,7 @@
|
|
|
129
129
|
"type-fix": "aider --model deepseek/deepseek-chat --load type-fix.txt",
|
|
130
130
|
"t-build": "tsx src/build.ts",
|
|
131
131
|
"t-run": "tsx src/run.ts",
|
|
132
|
+
"testeranto": "tsx src/testeranto.ts",
|
|
132
133
|
"t-init": "tsx dist/prebuild/init-docs.mjs",
|
|
133
134
|
"t-report": "tsx dist/prebuild/ReportServer.mjs",
|
|
134
135
|
"compile-docs": "node scripts/compile-docs.js",
|
|
@@ -178,7 +179,6 @@
|
|
|
178
179
|
"@types/fabric": "^5.3.10",
|
|
179
180
|
"@types/file-saver": "^2.0.7",
|
|
180
181
|
"@types/node-static": "^0.7.11",
|
|
181
|
-
"@types/react-router-dom": "^5.3.3",
|
|
182
182
|
"@types/xmldom": "^0.1.34",
|
|
183
183
|
"@ungap/structured-clone": "^1.3.0",
|
|
184
184
|
"@xterm/addon-fit": "^0.10.0",
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from typing import Any, List, Dict, Callable
|
|
2
|
+
from .types import ITestSpecification, ITestImplementation, ITestAdapter, ITTestResourceRequest
|
|
3
|
+
from .simple_adapter import SimpleTestAdapter
|
|
4
|
+
|
|
5
|
+
class Pitono:
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
input_val: Any,
|
|
9
|
+
test_specification: ITestSpecification,
|
|
10
|
+
test_implementation: ITestImplementation,
|
|
11
|
+
test_resource_requirement: ITTestResourceRequest,
|
|
12
|
+
test_adapter: ITestAdapter,
|
|
13
|
+
uber_catcher: Callable[[Callable], None]
|
|
14
|
+
):
|
|
15
|
+
self.test_resource_requirement = test_resource_requirement
|
|
16
|
+
self.artifacts: List[Any] = []
|
|
17
|
+
self.test_jobs: List[Any] = []
|
|
18
|
+
self.test_specification = test_specification
|
|
19
|
+
self.suites_overrides: Dict[str, Any] = {}
|
|
20
|
+
self.given_overrides: Dict[str, Any] = {}
|
|
21
|
+
self.when_overrides: Dict[str, Any] = {}
|
|
22
|
+
self.then_overrides: Dict[str, Any] = {}
|
|
23
|
+
self.puppet_master: Any = None
|
|
24
|
+
self.specs: Any = None
|
|
25
|
+
self.assert_this_func = test_adapter.assert_this
|
|
26
|
+
|
|
27
|
+
# Generate specs
|
|
28
|
+
self.specs = test_specification(
|
|
29
|
+
self.suites(),
|
|
30
|
+
self.given(),
|
|
31
|
+
self.when(),
|
|
32
|
+
self.then()
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def suites(self) -> Dict[str, Any]:
|
|
36
|
+
return self.suites_overrides
|
|
37
|
+
|
|
38
|
+
def given(self) -> Dict[str, Any]:
|
|
39
|
+
return self.given_overrides
|
|
40
|
+
|
|
41
|
+
def when(self) -> Dict[str, Any]:
|
|
42
|
+
return self.when_overrides
|
|
43
|
+
|
|
44
|
+
def then(self) -> Dict[str, Any]:
|
|
45
|
+
return self.then_overrides
|
|
46
|
+
|
|
47
|
+
def get_test_jobs(self) -> List[Any]:
|
|
48
|
+
return self.test_jobs
|
|
49
|
+
|
|
50
|
+
def get_specs(self) -> Any:
|
|
51
|
+
return self.specs
|
|
52
|
+
|
|
53
|
+
def assert_this(self, t: Any) -> Any:
|
|
54
|
+
return self.assert_this_func(t)
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
from typing import List, Dict, Any, Callable, Optional
|
|
2
|
+
from .types import Isubject, Istore, Iselection, Then, Given
|
|
3
|
+
|
|
4
|
+
class BaseGiven:
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
name: str,
|
|
8
|
+
features: List[str],
|
|
9
|
+
whens: List[Any],
|
|
10
|
+
thens: List[Any],
|
|
11
|
+
given_cb: Given,
|
|
12
|
+
initial_values: Any
|
|
13
|
+
):
|
|
14
|
+
self.name = name
|
|
15
|
+
self.features = features or []
|
|
16
|
+
self.whens = whens or []
|
|
17
|
+
self.thens = thens or []
|
|
18
|
+
self.given_cb = given_cb
|
|
19
|
+
self.initial_values = initial_values
|
|
20
|
+
self.artifacts: List[str] = []
|
|
21
|
+
self.error: Optional[Exception] = None
|
|
22
|
+
self.failed = False
|
|
23
|
+
self.store: Optional[Istore] = None
|
|
24
|
+
self.key: Optional[str] = None
|
|
25
|
+
|
|
26
|
+
def add_artifact(self, path: str) -> None:
|
|
27
|
+
# Normalize path separators
|
|
28
|
+
normalized_path = path.replace('\\', '/')
|
|
29
|
+
self.artifacts.append(normalized_path)
|
|
30
|
+
|
|
31
|
+
def to_obj(self) -> Dict[str, Any]:
|
|
32
|
+
return {
|
|
33
|
+
'key': self.key,
|
|
34
|
+
'name': self.name,
|
|
35
|
+
'whens': [w.to_obj() if hasattr(w, 'to_obj') else {} for w in self.whens],
|
|
36
|
+
'thens': [t.to_obj() if hasattr(t, 'to_obj') else {} for t in self.thens],
|
|
37
|
+
'error': str(self.error) if self.error else None,
|
|
38
|
+
'failed': self.failed,
|
|
39
|
+
'features': self.features,
|
|
40
|
+
'artifacts': self.artifacts
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async def given_that(
|
|
44
|
+
self,
|
|
45
|
+
subject: Isubject,
|
|
46
|
+
test_resource_configuration,
|
|
47
|
+
artifactory: Callable[[str, Any], None],
|
|
48
|
+
given_cb: Given,
|
|
49
|
+
initial_values: Any,
|
|
50
|
+
pm: Any
|
|
51
|
+
) -> Istore:
|
|
52
|
+
raise NotImplementedError()
|
|
53
|
+
|
|
54
|
+
async def after_each(
|
|
55
|
+
self,
|
|
56
|
+
store: Istore,
|
|
57
|
+
key: str,
|
|
58
|
+
artifactory: Callable[[str, Any], None],
|
|
59
|
+
pm: Any
|
|
60
|
+
) -> Istore:
|
|
61
|
+
return store
|
|
62
|
+
|
|
63
|
+
def uber_catcher(self, e: Exception) -> None:
|
|
64
|
+
self.error = e
|
|
65
|
+
|
|
66
|
+
async def give(
|
|
67
|
+
self,
|
|
68
|
+
subject: Isubject,
|
|
69
|
+
key: str,
|
|
70
|
+
test_resource_configuration,
|
|
71
|
+
tester: Callable[[Any], bool],
|
|
72
|
+
artifactory: Callable[[str, Any], None],
|
|
73
|
+
t_log: Callable[..., None],
|
|
74
|
+
pm: Any,
|
|
75
|
+
suite_ndx: int
|
|
76
|
+
) -> Istore:
|
|
77
|
+
self.key = key
|
|
78
|
+
t_log(f"\n {self.key}")
|
|
79
|
+
t_log(f"\n Given: {self.name}")
|
|
80
|
+
|
|
81
|
+
def given_artifactory(f_path: str, value: Any):
|
|
82
|
+
artifactory(f"given-{key}/{f_path}", value)
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
# Call given_that to set up the initial state
|
|
86
|
+
self.store = await self.given_that(
|
|
87
|
+
subject,
|
|
88
|
+
test_resource_configuration,
|
|
89
|
+
given_artifactory,
|
|
90
|
+
self.given_cb,
|
|
91
|
+
self.initial_values,
|
|
92
|
+
pm
|
|
93
|
+
)
|
|
94
|
+
except Exception as e:
|
|
95
|
+
self.failed = True
|
|
96
|
+
self.error = e
|
|
97
|
+
raise e
|
|
98
|
+
|
|
99
|
+
try:
|
|
100
|
+
# Process whens
|
|
101
|
+
for when_ndx, when_step in enumerate(self.whens):
|
|
102
|
+
await when_step.test(
|
|
103
|
+
self.store,
|
|
104
|
+
test_resource_configuration,
|
|
105
|
+
t_log,
|
|
106
|
+
pm,
|
|
107
|
+
f"suite-{suite_ndx}/given-{key}/when/{when_ndx}"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Process thens
|
|
111
|
+
for then_ndx, then_step in enumerate(self.thens):
|
|
112
|
+
result = await then_step.test(
|
|
113
|
+
self.store,
|
|
114
|
+
test_resource_configuration,
|
|
115
|
+
t_log,
|
|
116
|
+
pm,
|
|
117
|
+
f"suite-{suite_ndx}/given-{key}/then-{then_ndx}"
|
|
118
|
+
)
|
|
119
|
+
tester(result)
|
|
120
|
+
except Exception as e:
|
|
121
|
+
self.error = e
|
|
122
|
+
self.failed = True
|
|
123
|
+
raise e
|
|
124
|
+
finally:
|
|
125
|
+
try:
|
|
126
|
+
await self.after_each(self.store, self.key, given_artifactory, pm)
|
|
127
|
+
except Exception as e:
|
|
128
|
+
self.failed = True
|
|
129
|
+
raise e
|
|
130
|
+
|
|
131
|
+
return self.store
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from typing import Dict, List, Any, Callable
|
|
2
|
+
|
|
3
|
+
class BaseSuite:
|
|
4
|
+
def __init__(self, name: str, givens: Dict[str, Any]):
|
|
5
|
+
self.name = name
|
|
6
|
+
self.givens = givens
|
|
7
|
+
self.store: Any = None
|
|
8
|
+
self.test_resource_configuration: Any = None
|
|
9
|
+
self.index: int = 0
|
|
10
|
+
self.failed = False
|
|
11
|
+
self.fails = 0
|
|
12
|
+
self.artifacts: List[str] = []
|
|
13
|
+
|
|
14
|
+
def add_artifact(self, path: str) -> None:
|
|
15
|
+
normalized_path = path.replace('\\', '/')
|
|
16
|
+
self.artifacts.append(normalized_path)
|
|
17
|
+
|
|
18
|
+
def features(self) -> List[str]:
|
|
19
|
+
features = []
|
|
20
|
+
seen = set()
|
|
21
|
+
for given in self.givens.values():
|
|
22
|
+
for feature in given.features:
|
|
23
|
+
if feature not in seen:
|
|
24
|
+
features.append(feature)
|
|
25
|
+
seen.add(feature)
|
|
26
|
+
return features
|
|
27
|
+
|
|
28
|
+
def to_obj(self) -> Dict[str, Any]:
|
|
29
|
+
givens = [given.to_obj() for given in self.givens.values()]
|
|
30
|
+
return {
|
|
31
|
+
'name': self.name,
|
|
32
|
+
'givens': givens,
|
|
33
|
+
'fails': self.fails,
|
|
34
|
+
'failed': self.failed,
|
|
35
|
+
'features': self.features()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async def setup(
|
|
39
|
+
self,
|
|
40
|
+
s: Any,
|
|
41
|
+
artifactory: Callable[[str, Any], None],
|
|
42
|
+
tr: Any,
|
|
43
|
+
pm: Any
|
|
44
|
+
) -> Any:
|
|
45
|
+
return s
|
|
46
|
+
|
|
47
|
+
def assert_that(self, t: Any) -> bool:
|
|
48
|
+
return bool(t)
|
|
49
|
+
|
|
50
|
+
def after_all(self, store: Any, artifactory: Callable[[str, Any], None], pm: Any) -> Any:
|
|
51
|
+
return store
|
|
52
|
+
|
|
53
|
+
async def run(
|
|
54
|
+
self,
|
|
55
|
+
input_val: Any,
|
|
56
|
+
test_resource_configuration,
|
|
57
|
+
artifactory: Callable[[str, Any], None],
|
|
58
|
+
t_log: Callable[..., None],
|
|
59
|
+
pm: Any
|
|
60
|
+
) -> 'BaseSuite':
|
|
61
|
+
self.test_resource_configuration = test_resource_configuration
|
|
62
|
+
|
|
63
|
+
def suite_artifactory(f_path: str, value: Any):
|
|
64
|
+
artifactory(f'suite-{self.index}-{self.name}/{f_path}', value)
|
|
65
|
+
|
|
66
|
+
subject = await self.setup(
|
|
67
|
+
input_val,
|
|
68
|
+
suite_artifactory,
|
|
69
|
+
test_resource_configuration,
|
|
70
|
+
pm
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
for g_key, g in self.givens.items():
|
|
74
|
+
try:
|
|
75
|
+
self.store = await g.give(
|
|
76
|
+
subject,
|
|
77
|
+
g_key,
|
|
78
|
+
test_resource_configuration,
|
|
79
|
+
self.assert_that,
|
|
80
|
+
suite_artifactory,
|
|
81
|
+
t_log,
|
|
82
|
+
pm,
|
|
83
|
+
self.index
|
|
84
|
+
)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
self.failed = True
|
|
87
|
+
self.fails += 1
|
|
88
|
+
raise e
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
self.after_all(self.store, artifactory, pm)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
print(f"Error in after_all: {e}")
|
|
94
|
+
|
|
95
|
+
return self
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Any, Dict, List
|
|
2
|
+
|
|
3
|
+
class BaseThen:
|
|
4
|
+
def __init__(self, name: str, then_cb: Any):
|
|
5
|
+
self.name = name
|
|
6
|
+
self.then_cb = then_cb
|
|
7
|
+
self.error = False
|
|
8
|
+
self.artifacts: List[str] = []
|
|
9
|
+
|
|
10
|
+
def add_artifact(self, path: str) -> None:
|
|
11
|
+
normalized_path = path.replace('\\', '/')
|
|
12
|
+
self.artifacts.append(normalized_path)
|
|
13
|
+
|
|
14
|
+
def to_obj(self) -> Dict[str, Any]:
|
|
15
|
+
return {
|
|
16
|
+
'name': self.name,
|
|
17
|
+
'error': self.error,
|
|
18
|
+
'artifacts': self.artifacts
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async def but_then(
|
|
22
|
+
self,
|
|
23
|
+
store: Any,
|
|
24
|
+
then_cb: Any,
|
|
25
|
+
test_resource_configuration,
|
|
26
|
+
pm: Any
|
|
27
|
+
) -> Any:
|
|
28
|
+
raise NotImplementedError()
|
|
29
|
+
|
|
30
|
+
async def test(
|
|
31
|
+
self,
|
|
32
|
+
store: Any,
|
|
33
|
+
test_resource_configuration,
|
|
34
|
+
t_log: Any,
|
|
35
|
+
pm: Any,
|
|
36
|
+
filepath: str
|
|
37
|
+
) -> Any:
|
|
38
|
+
try:
|
|
39
|
+
add_artifact = self.add_artifact
|
|
40
|
+
# Simple implementation for now
|
|
41
|
+
result = await self.but_then(
|
|
42
|
+
store,
|
|
43
|
+
self.then_cb,
|
|
44
|
+
test_resource_configuration,
|
|
45
|
+
pm
|
|
46
|
+
)
|
|
47
|
+
return result
|
|
48
|
+
except Exception as e:
|
|
49
|
+
self.error = True
|
|
50
|
+
raise e
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import Any, Dict, List
|
|
2
|
+
|
|
3
|
+
class BaseWhen:
|
|
4
|
+
def __init__(self, name: str, when_cb: Any):
|
|
5
|
+
self.name = name
|
|
6
|
+
self.when_cb = when_cb
|
|
7
|
+
self.artifacts: List[str] = []
|
|
8
|
+
self.error: Any = None
|
|
9
|
+
|
|
10
|
+
def add_artifact(self, path: str) -> None:
|
|
11
|
+
normalized_path = path.replace('\\', '/')
|
|
12
|
+
self.artifacts.append(normalized_path)
|
|
13
|
+
|
|
14
|
+
def to_obj(self) -> Dict[str, Any]:
|
|
15
|
+
return {
|
|
16
|
+
'name': self.name,
|
|
17
|
+
'error': str(self.error) if self.error else None,
|
|
18
|
+
'artifacts': self.artifacts
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async def and_when(
|
|
22
|
+
self,
|
|
23
|
+
store: Any,
|
|
24
|
+
when_cb: Any,
|
|
25
|
+
test_resource: Any,
|
|
26
|
+
pm: Any
|
|
27
|
+
) -> Any:
|
|
28
|
+
raise NotImplementedError()
|
|
29
|
+
|
|
30
|
+
async def test(
|
|
31
|
+
self,
|
|
32
|
+
store: Any,
|
|
33
|
+
test_resource_configuration,
|
|
34
|
+
t_log: Any,
|
|
35
|
+
pm: Any,
|
|
36
|
+
filepath: str
|
|
37
|
+
) -> Any:
|
|
38
|
+
try:
|
|
39
|
+
# Ensure add_artifact is properly bound to 'this'
|
|
40
|
+
add_artifact = self.add_artifact
|
|
41
|
+
# In Python, we can just pass self.add_artifact directly
|
|
42
|
+
# For now, we'll implement a simple version
|
|
43
|
+
result = await self.and_when(
|
|
44
|
+
store,
|
|
45
|
+
self.when_cb,
|
|
46
|
+
test_resource_configuration,
|
|
47
|
+
pm
|
|
48
|
+
)
|
|
49
|
+
return result
|
|
50
|
+
except Exception as e:
|
|
51
|
+
self.error = e
|
|
52
|
+
raise e
|