testeranto 0.198.0 → 0.200.0

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 (157) hide show
  1. package/bin/test_runner +0 -0
  2. package/bin/testeranto +0 -0
  3. package/bundle.js +2 -2
  4. package/cmd/test_runner/main.go +65 -0
  5. package/cmd/testeranto/main.go +37 -0
  6. package/dist/common/src/PM/main.js +126 -11
  7. package/dist/common/src/PM/pitonoRunner.js +54 -0
  8. package/dist/common/src/components/pure/TestPageView.js +180 -65
  9. package/dist/common/src/components/stateful/TestPage.js +50 -11
  10. package/dist/common/src/lib/abstractBase.test/index.js +1 -0
  11. package/dist/common/src/run.js +48 -82
  12. package/dist/common/src/{build.js → testeranto.js} +107 -55
  13. package/dist/common/src/utils/golingvuMetafile.js +116 -0
  14. package/dist/common/src/utils/logFiles.js +2 -1
  15. package/dist/common/src/utils/pitonoMetafile.js +67 -0
  16. package/dist/common/src/utils.js +40 -1
  17. package/dist/common/testeranto.config.js +23 -21
  18. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  19. package/dist/module/src/PM/main.js +126 -11
  20. package/dist/module/src/PM/pitonoRunner.js +47 -0
  21. package/dist/module/src/components/pure/TestPageView.js +180 -65
  22. package/dist/module/src/components/stateful/TestPage.js +50 -11
  23. package/dist/module/src/lib/abstractBase.test/index.js +1 -0
  24. package/dist/module/src/run.js +49 -45
  25. package/dist/module/src/{build.js → testeranto.js} +107 -55
  26. package/dist/module/src/utils/golingvuMetafile.js +109 -0
  27. package/dist/module/src/utils/logFiles.js +2 -1
  28. package/dist/module/src/utils/pitonoMetafile.js +60 -0
  29. package/dist/module/src/utils.js +40 -1
  30. package/dist/module/testeranto.config.js +23 -21
  31. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  32. package/dist/prebuild/App.js +81 -17
  33. package/dist/types/src/PM/main.d.ts +2 -0
  34. package/dist/types/src/PM/pitonoRunner.d.ts +7 -0
  35. package/dist/types/src/Types.d.ts +1 -1
  36. package/dist/types/src/run.d.ts +0 -1
  37. package/dist/types/src/utils/golingvuMetafile.d.ts +19 -0
  38. package/dist/types/src/utils/logFiles.d.ts +5 -1
  39. package/dist/types/src/utils/pitonoMetafile.d.ts +7 -0
  40. package/dist/types/src/utils.d.ts +5 -0
  41. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  42. package/docs/index.md +13 -13
  43. package/example/test_example.py +106 -0
  44. package/go.mod +3 -0
  45. package/package.json +14 -14
  46. package/pitono/__init__.py +54 -0
  47. package/pitono/base_given.py +131 -0
  48. package/pitono/base_suite.py +95 -0
  49. package/pitono/base_then.py +50 -0
  50. package/pitono/base_when.py +52 -0
  51. package/pitono/core_generator.py +110 -0
  52. package/pitono/pitono.egg-info/PKG-INFO +17 -0
  53. package/pitono/pitono.egg-info/SOURCES.txt +7 -0
  54. package/pitono/pitono.egg-info/dependency_links.txt +1 -0
  55. package/pitono/pitono.egg-info/entry_points.txt +2 -0
  56. package/pitono/pitono.egg-info/top_level.txt +1 -0
  57. package/pitono/pyproject.toml +26 -0
  58. package/pitono/setup.py +40 -0
  59. package/pitono/simple_adapter.py +24 -0
  60. package/pitono/types.py +78 -0
  61. package/sampleMetafile.json +56 -0
  62. package/src/PM/main.ts +146 -17
  63. package/src/PM/pitonoRunner.ts +49 -0
  64. package/src/Types.ts +1 -1
  65. package/src/components/pure/TestPageView.tsx +175 -8
  66. package/src/components/stateful/TestPage.tsx +57 -16
  67. package/src/core/types.go +36 -0
  68. package/src/golingvu/README.md +3 -0
  69. package/src/golingvu/base_given.go +76 -0
  70. package/src/golingvu/base_suite.go +39 -0
  71. package/src/golingvu/base_suite_test.go +197 -0
  72. package/src/golingvu/base_then.go +21 -0
  73. package/src/golingvu/base_when.go +21 -0
  74. package/src/golingvu/golingvu.go +179 -0
  75. package/src/golingvu/test_adapter.go +33 -0
  76. package/src/golingvu/types.go +86 -0
  77. package/src/lib/abstractBase.test/index.ts +1 -0
  78. package/src/pitono/README.md +3 -0
  79. package/src/run.ts +48 -48
  80. package/src/templates/frontpage.html +26 -17
  81. package/src/{build.ts → testeranto.ts} +128 -58
  82. package/src/utils/golingvuMetafile.ts +165 -0
  83. package/src/utils/logFiles.ts +2 -1
  84. package/src/utils/pitonoMetafile.ts +68 -0
  85. package/src/utils.ts +38 -1
  86. package/testeranto/App.js +81 -17
  87. package/testeranto/metafiles/golang/core.json +72 -0
  88. package/testeranto/metafiles/node/core.json +21 -459
  89. package/testeranto/metafiles/pure/core.json +18 -119
  90. package/testeranto/metafiles/web/core.json +37 -16797
  91. package/testeranto/reports/core/config.json +8 -40
  92. package/testeranto/reports/core/src/lib/BaseSuite.test/node.test/node/lint_errors.txt +6 -0
  93. package/testeranto/reports/core/src/lib/BaseSuite.test/node.test/node/prompt.txt +12 -1
  94. package/testeranto/reports/core/src/lib/BaseSuite.test/pure.test/pure/lint_errors.txt +2 -0
  95. package/testeranto/reports/core/src/lib/BaseSuite.test/pure.test/pure/prompt.txt +11 -1
  96. package/testeranto/reports/core/src/lib/BaseSuite.test/web.test/web/lint_errors.txt +2 -0
  97. package/testeranto/reports/core/src/lib/BaseSuite.test/web.test/web/prompt.txt +13 -3
  98. package/testeranto/reports/core/summary.json +9 -45
  99. package/testeranto.config.ts +25 -21
  100. package/tsc.log +46 -7
  101. package/dist/common/src/lib/mocks.test.js +0 -11
  102. package/dist/module/src/lib/mocks.test.js +0 -11
  103. package/dist/prebuild/build.mjs +0 -578
  104. package/dist/prebuild/run.mjs +0 -2290
  105. package/dist/tsconfig.tsbuildinfo +0 -1
  106. package/dist/types/src/lib/mocks.test.d.ts +0 -0
  107. package/src/lib/mocks.test.ts +0 -11
  108. package/testeranto/reports/core/src/Pure.test/pure/exit.log +0 -0
  109. package/testeranto/reports/core/src/Pure.test/pure/lint_errors.txt +0 -0
  110. package/testeranto/reports/core/src/Pure.test/pure/message.txt +0 -17
  111. package/testeranto/reports/core/src/Pure.test/pure/prompt.txt +0 -14
  112. package/testeranto/reports/core/src/Pure.test/pure/type_errors.txt +0 -66
  113. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/debug.log +0 -0
  114. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/error.log +0 -67
  115. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/exit.log +0 -1
  116. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/info.log +0 -2
  117. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/lint_errors.txt +0 -0
  118. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/message.txt +0 -17
  119. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/prompt.txt +0 -16
  120. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/tests.json +0 -68
  121. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/type_errors.txt +0 -56
  122. package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/warn.log +0 -0
  123. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/debug.log +0 -0
  124. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/error.log +0 -22
  125. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/exit.log +0 -1
  126. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/info.log +0 -2
  127. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/lint_errors.txt +0 -13
  128. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/message.txt +0 -17
  129. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/prompt.txt +0 -16
  130. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/tests.json +0 -88
  131. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/type_errors.txt +0 -45
  132. package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/warn.log +0 -0
  133. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/debug.log +0 -0
  134. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/error.log +0 -0
  135. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/exit.log +0 -1
  136. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/info.log +0 -2
  137. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/lint_errors.txt +0 -47
  138. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/message.txt +0 -17
  139. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/prompt.txt +0 -17
  140. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/tests.json +0 -57
  141. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/type_errors.txt +0 -99
  142. package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/warn.log +0 -0
  143. package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/exit.log +0 -1
  144. package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/lint_errors.txt +0 -0
  145. package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/message.txt +0 -17
  146. package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/prompt.txt +0 -17
  147. package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/stderr.log +0 -18
  148. package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/stdout.log +0 -0
  149. package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/type_errors.txt +0 -32
  150. package/testeranto/reports/core/src/lib/pmProxy.test/index/node/exit.log +0 -1
  151. package/testeranto/reports/core/src/lib/pmProxy.test/index/node/lint_errors.txt +0 -15
  152. package/testeranto/reports/core/src/lib/pmProxy.test/index/node/message.txt +0 -17
  153. package/testeranto/reports/core/src/lib/pmProxy.test/index/node/prompt.txt +0 -17
  154. package/testeranto/reports/core/src/lib/pmProxy.test/index/node/stderr.log +0 -66
  155. package/testeranto/reports/core/src/lib/pmProxy.test/index/node/stdout.log +0 -10
  156. package/testeranto/reports/core/src/lib/pmProxy.test/index/node/type_errors.txt +0 -47
  157. /package/dist/types/src/{build.d.ts → testeranto.d.ts} +0 -0
@@ -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
@@ -0,0 +1,110 @@
1
+ import json
2
+ import os
3
+ import sys
4
+ from typing import Dict, List, Any
5
+ from pathlib import Path
6
+
7
+ class PitonoCoreGenerator:
8
+ def __init__(self, test_name: str, entry_points: List[str]):
9
+ self.test_name = test_name
10
+ self.entry_points = entry_points
11
+ self.output_dir = Path("testeranto") / "pitono" / test_name
12
+ self.output_dir.mkdir(parents=True, exist_ok=True)
13
+
14
+ def generate_core_json(self) -> Dict[str, Any]:
15
+ """Generate a core.json file similar to esbuild's output"""
16
+ return {
17
+ "testName": self.test_name,
18
+ "entryPoints": self.entry_points,
19
+ "outputs": self._generate_outputs(),
20
+ "metafile": {
21
+ "inputs": self._generate_inputs(),
22
+ "outputs": self._generate_metafile_outputs()
23
+ },
24
+ "timestamp": self._get_timestamp(),
25
+ "runtime": "pitono"
26
+ }
27
+
28
+ def _generate_outputs(self) -> Dict[str, Any]:
29
+ """Generate outputs section similar to esbuild"""
30
+ outputs = {}
31
+ for entry_point in self.entry_points:
32
+ # For pitono, the "output" is the test file itself
33
+ # Use the absolute path to the original file
34
+ absolute_path = os.path.abspath(entry_point)
35
+ outputs[absolute_path] = {
36
+ "imports": [],
37
+ "exports": [],
38
+ "entryPoint": entry_point,
39
+ "inputs": {
40
+ ep: {
41
+ "bytes": os.path.getsize(ep) if os.path.exists(ep) else 1024,
42
+ "imports": []
43
+ }
44
+ for ep in self.entry_points
45
+ },
46
+ "bytes": os.path.getsize(entry_point) if os.path.exists(entry_point) else 2048
47
+ }
48
+ return outputs
49
+
50
+ def _generate_inputs(self) -> Dict[str, Any]:
51
+ """Generate inputs section for metafile"""
52
+ inputs = {}
53
+ for entry_point in self.entry_points:
54
+ # Use absolute paths
55
+ absolute_path = os.path.abspath(entry_point)
56
+ inputs[absolute_path] = {
57
+ "bytes": os.path.getsize(entry_point) if os.path.exists(entry_point) else 1024,
58
+ "imports": []
59
+ }
60
+ return inputs
61
+
62
+ def _generate_metafile_outputs(self) -> Dict[str, Any]:
63
+ """Generate outputs section for metafile"""
64
+ outputs = {}
65
+ for entry_point in self.entry_points:
66
+ # Use the absolute path to the original file
67
+ absolute_path = os.path.abspath(entry_point)
68
+ outputs[absolute_path] = {
69
+ "bytes": os.path.getsize(entry_point) if os.path.exists(entry_point) else 2048,
70
+ "inputs": {
71
+ ep: {
72
+ "bytesInOutput": os.path.getsize(ep) if os.path.exists(ep) else 1024
73
+ }
74
+ for ep in self.entry_points
75
+ },
76
+ "exports": [],
77
+ "entryPoint": entry_point
78
+ }
79
+ return outputs
80
+
81
+ def _get_timestamp(self) -> int:
82
+ """Get current timestamp"""
83
+ import time
84
+ return int(time.time() * 1000)
85
+
86
+ def write_core_json(self):
87
+ """Write the core.json file to disk"""
88
+ core_data = self.generate_core_json()
89
+ core_file_path = self.output_dir / "core.json"
90
+
91
+ with open(core_file_path, 'w') as f:
92
+ json.dump(core_data, f, indent=2)
93
+
94
+ print(f"Pitono core.json written to: {core_file_path}")
95
+ return core_file_path
96
+
97
+ def main():
98
+ if len(sys.argv) < 3:
99
+ print("Usage: pitono-core-generator <test_name> <entry_point1> [entry_point2 ...]")
100
+ sys.exit(1)
101
+
102
+ test_name = sys.argv[1]
103
+ # Convert entry points to absolute paths
104
+ entry_points = [os.path.abspath(ep) for ep in sys.argv[2:]]
105
+
106
+ generator = PitonoCoreGenerator(test_name, entry_points)
107
+ generator.write_core_json()
108
+
109
+ if __name__ == "__main__":
110
+ main()
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: pitono
3
+ Version: 0.1.0
4
+ Summary: Python implementation of Testeranto
5
+ Author: Testeranto Team
6
+ Author-email:
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.7
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Requires-Python: >=3.7
16
+ Description-Content-Type: text/markdown
17
+ Dynamic: requires-python
@@ -0,0 +1,7 @@
1
+ pyproject.toml
2
+ setup.py
3
+ pitono.egg-info/PKG-INFO
4
+ pitono.egg-info/SOURCES.txt
5
+ pitono.egg-info/dependency_links.txt
6
+ pitono.egg-info/entry_points.txt
7
+ pitono.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pitono-core-generator = core_generator:main
@@ -0,0 +1,26 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pitono"
7
+ version = "0.1.0"
8
+ description = "Python implementation of Testeranto"
9
+ readme = "README.md"
10
+ requires-python = ">=3.7"
11
+ authors = [
12
+ { name = "Testeranto Team" }
13
+ ]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.7",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ ]
24
+
25
+ [project.scripts]
26
+ pitono-core-generator = "core_generator:main"
@@ -0,0 +1,40 @@
1
+ from setuptools import setup, find_packages
2
+ import os
3
+
4
+ # Get the long description from the README file
5
+ readme_path = os.path.join(os.path.dirname(__file__), 'README.md')
6
+ long_description = ''
7
+ if os.path.exists(readme_path):
8
+ with open(readme_path, 'r', encoding='utf-8') as f:
9
+ long_description = f.read()
10
+
11
+ setup(
12
+ name="pitono",
13
+ version="0.1.0",
14
+ packages=find_packages(where='.'),
15
+ package_dir={'': '.'},
16
+ entry_points={
17
+ 'console_scripts': [
18
+ 'pitono-core-generator=core_generator:main',
19
+ ],
20
+ },
21
+ python_requires='>=3.7',
22
+ install_requires=[
23
+ # Add any dependencies here
24
+ ],
25
+ author="Testeranto Team",
26
+ author_email="",
27
+ description="Python implementation of Testeranto",
28
+ long_description=long_description,
29
+ long_description_content_type="text/markdown",
30
+ classifiers=[
31
+ "Development Status :: 3 - Alpha",
32
+ "Intended Audience :: Developers",
33
+ "License :: OSI Approved :: MIT License",
34
+ "Programming Language :: Python :: 3",
35
+ "Programming Language :: Python :: 3.7",
36
+ "Programming Language :: Python :: 3.8",
37
+ "Programming Language :: Python :: 3.9",
38
+ "Programming Language :: Python :: 3.10",
39
+ ],
40
+ )
@@ -0,0 +1,24 @@
1
+ from .types import ITestAdapter, ITTestResourceConfiguration
2
+
3
+ class SimpleTestAdapter(ITestAdapter):
4
+ def before_all(self, input_val, tr, pm):
5
+ return input_val
6
+
7
+ def after_all(self, store, pm):
8
+ return store
9
+
10
+ def before_each(self, subject, initializer, test_resource, initial_values, pm):
11
+ return subject
12
+
13
+ def after_each(self, store, key, pm):
14
+ return store
15
+
16
+ def and_when(self, store, when_cb, test_resource, pm):
17
+ return store
18
+
19
+ def but_then(self, store, then_cb, test_resource, pm):
20
+ return store
21
+
22
+ def assert_this(self, t):
23
+ # Simple implementation - always return True for now
24
+ return True
@@ -0,0 +1,78 @@
1
+ from typing import TypeVar, Generic, Callable, Any, Dict, List, Optional
2
+
3
+ # Type variables for BDD input/output types
4
+ Iinput = TypeVar('Iinput')
5
+ Isubject = TypeVar('Isubject')
6
+ Istore = TypeVar('Istore')
7
+ Iselection = TypeVar('Iselection')
8
+ Then = TypeVar('Then')
9
+ Given = TypeVar('Given')
10
+
11
+ # Test resource configuration
12
+ class ITTestResourceConfiguration:
13
+ def __init__(
14
+ self,
15
+ name: str,
16
+ fs: str,
17
+ ports: List[int],
18
+ browser_ws_endpoint: Optional[str] = None,
19
+ timeout: Optional[int] = None,
20
+ retries: Optional[int] = None,
21
+ environment: Optional[Dict[str, str]] = None
22
+ ):
23
+ self.name = name
24
+ self.fs = fs
25
+ self.ports = ports
26
+ self.browser_ws_endpoint = browser_ws_endpoint
27
+ self.timeout = timeout
28
+ self.retries = retries
29
+ self.environment = environment or {}
30
+
31
+ # Test adapter interface
32
+ class ITestAdapter:
33
+ def before_all(self, input_val: Any, tr: ITTestResourceConfiguration, pm: Any) -> Any:
34
+ raise NotImplementedError()
35
+
36
+ def after_all(self, store: Any, pm: Any) -> Any:
37
+ raise NotImplementedError()
38
+
39
+ def before_each(self, subject: Any, initializer: Any, test_resource: ITTestResourceConfiguration,
40
+ initial_values: Any, pm: Any) -> Any:
41
+ raise NotImplementedError()
42
+
43
+ def after_each(self, store: Any, key: str, pm: Any) -> Any:
44
+ raise NotImplementedError()
45
+
46
+ def and_when(self, store: Any, when_cb: Any, test_resource: Any, pm: Any) -> Any:
47
+ raise NotImplementedError()
48
+
49
+ def but_then(self, store: Any, then_cb: Any, test_resource: Any, pm: Any) -> Any:
50
+ raise NotImplementedError()
51
+
52
+ def assert_this(self, t: Any) -> bool:
53
+ raise NotImplementedError()
54
+
55
+ # Test specification function type
56
+ ITestSpecification = Callable[[Any, Any, Any, Any], Any]
57
+
58
+ # Test implementation structure
59
+ class ITestImplementation:
60
+ def __init__(self, suites: Dict[str, Any], givens: Dict[str, Any],
61
+ whens: Dict[str, Any], thens: Dict[str, Any]):
62
+ self.suites = suites
63
+ self.givens = givens
64
+ self.whens = whens
65
+ self.thens = thens
66
+
67
+ # Test resource request
68
+ class ITTestResourceRequest:
69
+ def __init__(self, ports: int):
70
+ self.ports = ports
71
+
72
+ # Final results
73
+ class IFinalResults:
74
+ def __init__(self, failed: bool, fails: int, artifacts: List[Any], features: List[str]):
75
+ self.failed = failed
76
+ self.fails = fails
77
+ self.artifacts = artifacts
78
+ self.features = features
@@ -0,0 +1,56 @@
1
+ {
2
+ "errors": [],
3
+ "warnings": [],
4
+ "metafile": {
5
+ "outputs": {
6
+ "testeranto/bundles/node/core/src/lib/BaseSuite.test/node.test.mjs": {
7
+ "entryPoint": "src/lib/BaseSuite.test/node.test.ts",
8
+ "inputs": {
9
+ "dist/cjs-shim.js": {
10
+ "bytesInOutput": 167
11
+ },
12
+ "src/lib/index.ts": {
13
+ "bytesInOutput": 672
14
+ },
15
+ "src/PM/node.ts": {
16
+ "bytesInOutput": 5315
17
+ },
18
+ "src/PM/index.ts": {
19
+ "bytesInOutput": 20
20
+ },
21
+ "src/lib/pmProxy.ts": {
22
+ "bytesInOutput": 6590
23
+ },
24
+ "src/lib/BaseGiven.ts": {
25
+ "bytesInOutput": 2911
26
+ },
27
+ "src/lib/BaseWhen.ts": {
28
+ "bytesInOutput": 1127
29
+ },
30
+ "src/lib/BaseThen.ts": {
31
+ "bytesInOutput": 1581
32
+ },
33
+ "src/lib/BaseSuite.ts": {
34
+ "bytesInOutput": 2451
35
+ },
36
+ "src/lib/Tiposkripto.ts": {
37
+ "bytesInOutput": 5299
38
+ },
39
+ "src/Node.ts": {
40
+ "bytesInOutput": 1203
41
+ },
42
+ "src/lib/BaseSuite.test/mock.ts": {
43
+ "bytesInOutput": 1481
44
+ },
45
+ "src/lib/BaseSuite.test/test.ts": {
46
+ "bytesInOutput": 7643
47
+ },
48
+ "src/lib/BaseSuite.test/node.test.ts": {
49
+ "bytesInOutput": 103
50
+ }
51
+ },
52
+ "bytes": 37067
53
+ }
54
+ }
55
+ }
56
+ }
package/src/PM/main.ts CHANGED
@@ -83,6 +83,12 @@ function runtimeLogs(
83
83
  return {
84
84
  exit: fs.createWriteStream(`${safeDest}/exit.log`),
85
85
  };
86
+ } else if (runtime === "pitono") {
87
+ return {
88
+ stdout: fs.createWriteStream(`${safeDest}/stdout.log`),
89
+ stderr: fs.createWriteStream(`${safeDest}/stderr.log`),
90
+ exit: fs.createWriteStream(`${safeDest}/exit.log`),
91
+ };
86
92
  } else {
87
93
  throw `unknown runtime: ${runtime}`;
88
94
  }
@@ -239,6 +245,7 @@ export class PM_Main extends PM_WithEslintAndTsc {
239
245
  webMetafileWatcher: fs.FSWatcher;
240
246
  nodeMetafileWatcher: fs.FSWatcher;
241
247
  importMetafileWatcher: fs.FSWatcher;
248
+ pitonoMetafileWatcher: fs.FSWatcher;
242
249
  pureSidecars: Record<number, Sidecar>;
243
250
  nodeSidecars: Record<number, ChildProcess>;
244
251
  webSidecars: Record<number, Page>;
@@ -641,7 +648,7 @@ export class PM_Main extends PM_WithEslintAndTsc {
641
648
  );
642
649
  }
643
650
 
644
- const { nodeEntryPoints, webEntryPoints, pureEntryPoints } =
651
+ const { nodeEntryPoints, webEntryPoints, pureEntryPoints, pitonoEntryPoints } =
645
652
  this.getRunnables(this.configs.tests, this.name);
646
653
 
647
654
  [
@@ -669,6 +676,14 @@ export class PM_Main extends PM_WithEslintAndTsc {
669
676
  this.importMetafileWatcher = w;
670
677
  },
671
678
  ],
679
+ [
680
+ pitonoEntryPoints,
681
+ this.launchPitono,
682
+ "pitono",
683
+ (w) => {
684
+ this.pitonoMetafileWatcher = w;
685
+ },
686
+ ],
672
687
  ].forEach(
673
688
  async ([eps, launcher, runtime, watcher]: [
674
689
  Record<string, string>,
@@ -676,9 +691,22 @@ export class PM_Main extends PM_WithEslintAndTsc {
676
691
  IRunTime,
677
692
  (f: fs.FSWatcher) => void
678
693
  ]) => {
679
- const metafile = `./testeranto/metafiles/${runtime}/${this.name}.json`;
694
+ let metafile: string;
695
+ if (runtime === "pitono") {
696
+ metafile = `./testeranto/metafiles/python/core.json`;
697
+ // Ensure the directory exists before trying to watch
698
+ const metafileDir = path.dirname(metafile);
699
+ if (!fs.existsSync(metafileDir)) {
700
+ fs.mkdirSync(metafileDir, { recursive: true });
701
+ }
702
+ } else {
703
+ metafile = `./testeranto/metafiles/${runtime}/${this.name}.json`;
704
+ }
680
705
 
681
- await pollForFile(metafile);
706
+ // Only poll for file if it's not a pitono runtime
707
+ if (runtime !== "pitono") {
708
+ await pollForFile(metafile);
709
+ }
682
710
 
683
711
  Object.entries(eps).forEach(
684
712
  async ([inputFile, outputFile]: [string, string]) => {
@@ -707,14 +735,45 @@ export class PM_Main extends PM_WithEslintAndTsc {
707
735
 
708
736
  this.metafileOutputs(runtime);
709
737
 
710
- watcher(
711
- watch(metafile, async (e, filename) => {
712
- console.log(
713
- ansiC.yellow(ansiC.inverse(`< ${e} ${filename} (${runtime})`))
738
+ // For pitono, we need to wait for the file to be created
739
+ if (runtime === "pitono") {
740
+ // Use polling to wait for the file to exist
741
+ const checkFileExists = () => {
742
+ if (fs.existsSync(metafile)) {
743
+ console.log(
744
+ ansiC.green(ansiC.inverse(`Pitono metafile found: ${metafile}`))
745
+ );
746
+ // Set up the watcher once the file exists
747
+ watcher(
748
+ watch(metafile, async (e, filename) => {
749
+ console.log(
750
+ ansiC.yellow(ansiC.inverse(`< ${e} ${filename} (${runtime})`))
751
+ );
752
+ this.metafileOutputs(runtime);
753
+ })
754
+ );
755
+ // Read the metafile immediately
756
+ this.metafileOutputs(runtime);
757
+ } else {
758
+ // Check again after a delay
759
+ setTimeout(checkFileExists, 1000);
760
+ }
761
+ };
762
+ // Start checking for the file
763
+ checkFileExists();
764
+ } else {
765
+ // For other runtimes, only set up watcher if the file exists
766
+ if (fs.existsSync(metafile)) {
767
+ watcher(
768
+ watch(metafile, async (e, filename) => {
769
+ console.log(
770
+ ansiC.yellow(ansiC.inverse(`< ${e} ${filename} (${runtime})`))
771
+ );
772
+ this.metafileOutputs(runtime);
773
+ })
714
774
  );
715
- this.metafileOutputs(runtime);
716
- })
717
- );
775
+ }
776
+ }
718
777
  }
719
778
  );
720
779
 
@@ -760,6 +819,9 @@ export class PM_Main extends PM_WithEslintAndTsc {
760
819
  this.nodeMetafileWatcher.close();
761
820
  this.webMetafileWatcher.close();
762
821
  this.importMetafileWatcher.close();
822
+ if (this.pitonoMetafileWatcher) {
823
+ this.pitonoMetafileWatcher.close();
824
+ }
763
825
 
764
826
  // Close any remaining log streams
765
827
  Object.values(this.logStreams || {}).forEach((logs) => logs.closeAll());
@@ -799,13 +861,44 @@ export class PM_Main extends PM_WithEslintAndTsc {
799
861
  };
800
862
 
801
863
  async metafileOutputs(platform: IRunTime) {
802
- const metafile = JSON.parse(
803
- fs
804
- .readFileSync(`./testeranto/metafiles/${platform}/${this.name}.json`)
805
- .toString()
806
- ).metafile;
807
-
808
- if (!metafile) return;
864
+ let metafilePath: string;
865
+ if (platform === "pitono") {
866
+ metafilePath = `./testeranto/metafiles/python/core.json`;
867
+ } else {
868
+ metafilePath = `./testeranto/metafiles/${platform}/${this.name}.json`;
869
+ }
870
+
871
+ // Check if the file exists
872
+ if (!fs.existsSync(metafilePath)) {
873
+ if (platform === "pitono") {
874
+ console.log(
875
+ ansiC.yellow(ansiC.inverse(`Pitono metafile not found yet: ${metafilePath}`))
876
+ );
877
+ }
878
+ return;
879
+ }
880
+
881
+ let metafile;
882
+ try {
883
+ const fileContent = fs.readFileSync(metafilePath).toString();
884
+ const parsedData = JSON.parse(fileContent);
885
+ // Handle different metafile structures
886
+ if (platform === "pitono") {
887
+ // Pitono metafile might be the entire content or have a different structure
888
+ metafile = parsedData.metafile || parsedData;
889
+ } else {
890
+ metafile = parsedData.metafile;
891
+ }
892
+ if (!metafile) {
893
+ console.log(
894
+ ansiC.yellow(ansiC.inverse(`No metafile found in ${metafilePath}`))
895
+ );
896
+ return;
897
+ }
898
+ } catch (error) {
899
+ console.error(`Error reading metafile at ${metafilePath}:`, error);
900
+ return;
901
+ }
809
902
 
810
903
  const outputs: IOutputs = metafile.outputs;
811
904
 
@@ -1609,6 +1702,42 @@ export class PM_Main extends PM_WithEslintAndTsc {
1609
1702
  // }
1610
1703
  };
1611
1704
 
1705
+ launchPitono = async (src: string, dest: string) => {
1706
+ console.log(ansiC.green(ansiC.inverse(`pitono < ${src}`)));
1707
+ this.bddTestIsRunning(src);
1708
+
1709
+ const reportDest = `testeranto/reports/${this.name}/${src
1710
+ .split(".")
1711
+ .slice(0, -1)
1712
+ .join(".")}/pitono`;
1713
+ if (!fs.existsSync(reportDest)) {
1714
+ fs.mkdirSync(reportDest, { recursive: true });
1715
+ }
1716
+
1717
+ const logs = createLogStreams(reportDest, "node"); // Use node-style logs for pitono
1718
+
1719
+ try {
1720
+ // Execute the Python test using the pitono runner
1721
+ const { PitonoRunner } = await import('./pitonoRunner');
1722
+ const runner = new PitonoRunner(this.configs, this.name);
1723
+ await runner.run();
1724
+
1725
+ this.bddTestIsNowDone(src, 0);
1726
+ statusMessagePretty(0, src, "pitono");
1727
+ } catch (error) {
1728
+ logs.writeExitCode(-1, error);
1729
+ console.log(
1730
+ ansiC.red(
1731
+ ansiC.inverse(
1732
+ `${src} errored with: ${error}. Check logs for more info`
1733
+ )
1734
+ )
1735
+ );
1736
+ this.bddTestIsNowDone(src, -1);
1737
+ statusMessagePretty(-1, src, "pitono");
1738
+ }
1739
+ };
1740
+
1612
1741
  launchWeb = async (src: string, dest: string) => {
1613
1742
  console.log(ansiC.green(ansiC.inverse(`web < ${src}`)));
1614
1743
  this.bddTestIsRunning(src);