@o-lang/resolver-tests 1.0.0 → 1.0.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.
@@ -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
+ }
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": "notify-telegram",
3
+ "timestamp": "2026-01-20T13:48:24.716Z",
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/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.1",
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>