@o-lang/resolver-tests 1.0.0 → 1.0.2

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.
@@ -11,7 +11,7 @@
11
11
  "fixtures": {
12
12
  "inputs": [
13
13
  {
14
- "workflow": "R-001-allowlist/workflow.ol",
14
+ "workflow": "workflow.ol",
15
15
  "values": {}
16
16
  }
17
17
  ]
@@ -52,4 +52,4 @@
52
52
  "description": "No warnings should be issued for valid syntax"
53
53
  }
54
54
  ]
55
- }
55
+ }
@@ -11,7 +11,7 @@
11
11
  "fixtures": {
12
12
  "inputs": [
13
13
  {
14
- "workflow": "R-002-io-contract/workflow.ol",
14
+ "workflow": "workflow.ol",
15
15
  "values": {
16
16
  "userInput": "42"
17
17
  }
@@ -73,4 +73,4 @@
73
73
  "description": "No warnings for valid I/O contracts"
74
74
  }
75
75
  ]
76
- }
76
+ }
@@ -11,7 +11,7 @@
11
11
  "fixtures": {
12
12
  "inputs": [
13
13
  {
14
- "workflow": "R-003-failure-modes/workflow.ol",
14
+ "workflow": "workflow.ol",
15
15
  "values": {
16
16
  "userInput": "someInput"
17
17
  }
@@ -61,14 +61,8 @@
61
61
  "type": "step_failure_policies",
62
62
  "stepIndex": 1,
63
63
  "expected": {
64
- "TIMEOUT": {
65
- "action": "retry",
66
- "count": 2
67
- },
68
- "NETWORK_ERROR": {
69
- "action": "fail",
70
- "count": 0
71
- }
64
+ "TIMEOUT": { "action": "retry", "count": 2 },
65
+ "NETWORK_ERROR": { "action": "fail", "count": 0 }
72
66
  },
73
67
  "severity": "fatal",
74
68
  "description": "Failure modes and retry counts must be parsed"
@@ -81,4 +75,4 @@
81
75
  "description": "No warnings for valid failure mode syntax"
82
76
  }
83
77
  ]
84
- }
78
+ }
@@ -11,7 +11,7 @@
11
11
  "fixtures": {
12
12
  "inputs": [
13
13
  {
14
- "workflow": "R-004-invalid-syntax/workflow.ol",
14
+ "workflow": "workflow.ol",
15
15
  "values": {}
16
16
  }
17
17
  ]
@@ -54,4 +54,4 @@
54
54
  "description": "Parser must emit at least one warning"
55
55
  }
56
56
  ]
57
- }
57
+ }
@@ -11,7 +11,7 @@
11
11
  "fixtures": {
12
12
  "inputs": [
13
13
  {
14
- "resolver_contract": "R-005-resolver-metadata-contract/resolver.ol"
14
+ "resolver_contract": "resolver.js"
15
15
  }
16
16
  ]
17
17
  },
@@ -57,4 +57,4 @@
57
57
  "description": "Failure modes should be declared for production resolvers"
58
58
  }
59
59
  ]
60
- }
60
+ }
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="412" height="20">
2
+ <rect width="412" height="20" fill="green" rx="3" ry="3"/>
3
+ <text x="206" y="14"
4
+ fill="#fff"
5
+ font-family="Verdana"
6
+ font-size="12"
7
+ text-anchor="middle">
8
+ O-lang | notify-telegram v1.0.3 — Certified (2026-01-20)
9
+ </text>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="370" height="20">
2
+ <rect width="370" height="20" fill="green" rx="3" ry="3"/>
3
+ <text x="185" y="14"
4
+ fill="#fff"
5
+ font-family="Verdana"
6
+ font-size="12"
7
+ text-anchor="middle">
8
+ O-lang | unknown-resolver — Certified (2026-01-20)
9
+ </text>
10
+ </svg>
package/certified.svg ADDED
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="160" height="28">
2
+ <rect rx="4" width="160" height="28" fill="#2d2d2d"/>
3
+ <rect rx="4" x="80" width="80" height="28" fill="#4cbb17"/>
4
+ <text x="40" y="18" fill="#fff" font-size="13" font-family="Arial" text-anchor="middle">O-lang</text>
5
+ <text x="120" y="18" fill="#fff" font-size="13" font-family="Arial" text-anchor="middle">CERTIFIED</text>
6
+ </svg>
@@ -0,0 +1,10 @@
1
+ {
2
+ "resolver": "unknown",
3
+ "timestamp": "2026-01-20T15:05:20.396Z",
4
+ "results": [
5
+ {
6
+ "suite": "R-005-resolver-metadata-contract",
7
+ "status": "pass"
8
+ }
9
+ ]
10
+ }
package/lib/badge.js CHANGED
@@ -1,27 +1,63 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
+ console.log("✅ O-lang badge generator loaded");
4
+
5
+ // ----------------------
6
+ // Resolver-specific badge generator with O-lang tag
7
+ // ----------------------
8
+ function generateBadge({
9
+ resolverName = "Unknown",
10
+ version = "",
11
+ passed = false,
12
+ outputDir = process.cwd() // default to where CLI is run
13
+ }) {
14
+ const color = passed ? "green" : "red";
15
+ const statusText = passed ? "Certified" : "Failed";
16
+ const versionText = version ? ` v${version}` : "";
17
+ const timestamp = new Date().toISOString().split("T")[0]; // YYYY-MM-DD
18
+
19
+ // O-lang tag (explicit branding)
20
+ const badgeText = `O-lang | ${resolverName}${versionText} — ${statusText} (${timestamp})`;
21
+
22
+ const width = 20 + badgeText.length * 7; // approximate width per character
23
+
24
+ const badgeSvg = `
25
+ <svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="20">
26
+ <rect width="${width}" height="20" fill="${color}" rx="3" ry="3"/>
27
+ <text x="${width / 2}" y="14"
28
+ fill="#fff"
29
+ font-family="Verdana"
30
+ font-size="12"
31
+ text-anchor="middle">
32
+ ${badgeText}
33
+ </text>
34
+ </svg>
35
+ `.trim();
36
+
37
+ // ----------------------
38
+ // Ensure badges folder exists
39
+ // ----------------------
40
+ const badgesDir = path.join(outputDir, "badges");
41
+ if (!fs.existsSync(badgesDir)) {
42
+ fs.mkdirSync(badgesDir, { recursive: true });
43
+ }
44
+
45
+ // ----------------------
46
+ // Write badge file
47
+ // ----------------------
48
+ const safeName = resolverName.replace(/[^a-zA-Z0-9_-]/g, "_");
49
+ const badgePath = path.join(badgesDir, `${safeName}-badge.svg`);
50
+
51
+ fs.writeFileSync(badgePath, badgeSvg, "utf8");
52
+
53
+ console.log(`🏷 Badge written to ${badgePath}`);
3
54
 
4
- function generateBadge({ passed, outputDir }) {
5
- const badgePath = path.join(outputDir, "certified.svg");
6
-
7
- const svg = passed
8
- ? `
9
- <svg xmlns="http://www.w3.org/2000/svg" width="160" height="28">
10
- <rect rx="4" width="160" height="28" fill="#2d2d2d"/>
11
- <rect rx="4" x="80" width="80" height="28" fill="#4cbb17"/>
12
- <text x="40" y="18" fill="#fff" font-size="13" font-family="Arial" text-anchor="middle">O-lang</text>
13
- <text x="120" y="18" fill="#fff" font-size="13" font-family="Arial" text-anchor="middle">CERTIFIED</text>
14
- </svg>`
15
- : `
16
- <svg xmlns="http://www.w3.org/2000/svg" width="160" height="28">
17
- <rect rx="4" width="160" height="28" fill="#2d2d2d"/>
18
- <rect rx="4" x="80" width="80" height="28" fill="#bb2124"/>
19
- <text x="40" y="18" fill="#fff" font-size="13" font-family="Arial" text-anchor="middle">O-lang</text>
20
- <text x="120" y="18" fill="#fff" font-size="13" font-family="Arial" text-anchor="middle">FAILED</text>
21
- </svg>`;
22
-
23
- fs.writeFileSync(badgePath, svg.trim());
24
55
  return badgePath;
25
56
  }
26
57
 
27
- module.exports = { generateBadge };
58
+ // ----------------------
59
+ // Export
60
+ // ----------------------
61
+ module.exports = {
62
+ generateBadge
63
+ };
package/lib/runner.js CHANGED
@@ -1,4 +1,3 @@
1
- // lib/runner.js
2
1
  const path = require("path");
3
2
  const fs = require("fs");
4
3
 
@@ -254,9 +253,11 @@ function runAssertions(testSpec, target, status = {}) {
254
253
  // ----------------------
255
254
  async function runAllTests({ suites, resolver }) {
256
255
  let failed = 0;
256
+ // Resolve test suites from the package root (where R-001-..., R-005-... live)
257
+ const PACKAGE_ROOT = path.join(__dirname, '..');
257
258
 
258
259
  for (const suite of suites) {
259
- const suiteDir = path.join(process.cwd(), suite);
260
+ const suiteDir = path.join(PACKAGE_ROOT, suite);
260
261
  const testSpecPath = path.join(suiteDir, "test.json");
261
262
 
262
263
  if (!fs.existsSync(testSpecPath)) {
@@ -334,4 +335,4 @@ async function runAllTests({ suites, resolver }) {
334
335
  module.exports = {
335
336
  runAssertions,
336
337
  runAllTests,
337
- };
338
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@o-lang/resolver-tests",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Official O-Lang Resolver Test Harness — locked single entrypoint",
5
5
  "main": "run.js",
6
6
  "type": "commonjs",
package/run.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
-
2
+ console.log("🚀 Starting O-lang resolver test runner...");
3
3
  const path = require("path");
4
4
  const fs = require("fs");
5
5
 
@@ -75,7 +75,6 @@ const { generateBadge } = require("./lib/badge");
75
75
  "R-001-allowlist",
76
76
  "R-002-io-contract",
77
77
  "R-003-failure-modes",
78
- "R-004-invalid-syntax",
79
78
  "R-005-resolver-metadata-contract"
80
79
  ];
81
80
 
@@ -88,7 +87,7 @@ const { generateBadge } = require("./lib/badge");
88
87
  // Generate conformance report
89
88
  // ----------------------
90
89
  const conformanceReport = {
91
- resolver: resolver?.resolverName || "unknown",
90
+ resolver: resolver?.resolverDeclaration?.resolverName || resolver?.resolverName || "unknown",
92
91
  timestamp: new Date().toISOString(),
93
92
  results: suites.map(suite => ({
94
93
  suite,
@@ -102,12 +101,23 @@ const { generateBadge } = require("./lib/badge");
102
101
  );
103
102
 
104
103
  // ----------------------
105
- // Generate certification badge
106
- // ----------------------
107
- generateBadge({
108
- passed: result.failed === 0,
109
- outputDir: process.cwd()
110
- });
104
+ // Generate certification badge
105
+ // ----------------------
106
+ const meta = resolver.resolverDeclaration || resolver;
107
+
108
+ console.log("🏷 Badge metadata being sent:", {
109
+ resolverName: meta.resolverName,
110
+ version: meta.version,
111
+ passed: result.failed === 0,
112
+ outputDir: process.cwd()
113
+ });
114
+
115
+ generateBadge({
116
+ resolverName: meta.resolverName || "unknown-resolver",
117
+ version: meta.version || "",
118
+ passed: result.failed === 0,
119
+ outputDir: process.cwd()
120
+ });
111
121
 
112
122
  // ----------------------
113
123
  // Output handling
@@ -1,18 +0,0 @@
1
- <svg xmlns='http://www.w3.org/2000/svg' width='120' height='20'>
2
- <linearGradient id='b' x2='0' y2='100%'>
3
- <stop offset='0' stop-color='#bbb' stop-opacity='.1'/>
4
- <stop offset='1' stop-opacity='.1'/>
5
- </linearGradient>
6
- <mask id='a'>
7
- <rect width='120' height='20' rx='3' fill='#fff'/>
8
- </mask>
9
- <g mask='url(#a)'>
10
- <rect width='70' height='20' fill='#555'/>
11
- <rect x='70' width='50' height='20' fill='red'/>
12
- <rect width='120' height='20' fill='url(#b)'/>
13
- </g>
14
- <g fill='#fff' text-anchor='middle' font-family='Verdana' font-size='11'>
15
- <text x='35' y='14'>Certified</text>
16
- <text x='95' y='14'>fail</text>
17
- </g>
18
- </svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="159" height="20" role="img" aria-label="O-Lang v1: Conformant"><title>O-Lang v1: Conformant</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="159" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="84" height="20" fill="#555"/><rect x="84" width="75" height="20" fill="#4c1"/><rect width="159" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+R2l0SHViPC90aXRsZT48cGF0aCBkPSJNMTIgLjI5N2MtNi42MyAwLTEyIDUuMzczLTEyIDEyIDAgNS4zMDMgMy40MzggOS44IDguMjA1IDExLjM4NS42LjExMy44Mi0uMjU4LjgyLS41NzcgMC0uMjg1LS4wMS0xLjA0LS4wMTUtMi4wNC0zLjMzOC43MjQtNC4wNDItMS42MS00LjA0Mi0xLjYxQzQuNDIyIDE4LjA3IDMuNjMzIDE3LjcgMy42MzMgMTcuN2MtMS4wODctLjc0NC4wODQtLjcyOS4wODQtLjcyOSAxLjIwNS4wODQgMS44MzggMS4yMzYgMS44MzggMS4yMzYgMS4wNyAxLjgzNSAyLjgwOSAxLjMwNSAzLjQ5NS45OTguMTA4LS43NzYuNDE3LTEuMzA1Ljc2LTEuNjA1LTIuNjY1LS4zLTUuNDY2LTEuMzMyLTUuNDY2LTUuOTMgMC0xLjMxLjQ2NS0yLjM4IDEuMjM1LTMuMjItLjEzNS0uMzAzLS41NC0xLjUyMy4xMDUtMy4xNzYgMCAwIDEuMDA1LS4zMjIgMy4zIDEuMjMuOTYtLjI2NyAxLjk4LS4zOTkgMy0uNDA1IDEuMDIuMDA2IDIuMDQuMTM4IDMgLjQwNSAyLjI4LTEuNTUyIDMuMjg1LTEuMjMgMy4yODUtMS4yMy42NDUgMS42NTMuMjQgMi44NzMuMTIgMy4xNzYuNzY1Ljg0IDEuMjMgMS45MSAxLjIzIDMuMjIgMCA0LjYxLTIuODA1IDUuNjI1LTUuNDc1IDUuOTIuNDIuMzYuODEgMS4wOTYuODEgMi4yMiAwIDEuNjA2LS4wMTUgMi44OTYtLjAxNSAzLjI4NiAwIC4zMTUuMjEuNjkuODI1LjU3QzIwLjU2NSAyMi4wOTIgMjQgMTcuNTkyIDI0IDEyLjI5N2MwLTYuNjI3LTUuMzczLTEyLTEyLTEyIi8+PC9zdmc+"/><text aria-hidden="true" x="515" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="570">O-Lang v1</text><text x="515" y="140" transform="scale(.1)" fill="#fff" textLength="570">O-Lang v1</text><text aria-hidden="true" x="1205" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="650">Conformant</text><text x="1205" y="140" transform="scale(.1)" fill="#fff" textLength="650">Conformant</text></g></svg>