Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
481 changes: 481 additions & 0 deletions packages/bridge-parser/src/bridge-printer.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions packages/bridge-parser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export {
serializeBridge,
} from "./bridge-format.ts";

// ── Formatter ───────────────────────────────────────────────────────────────

export { formatBridge } from "./bridge-printer.ts";

// ── Language service ────────────────────────────────────────────────────────

export { BridgeLanguageService } from "./language-service.ts";
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-parser/src/parser/lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const WS = createToken({
export const Comment = createToken({
name: "Comment",
pattern: /#[^\r\n]*/,
group: Lexer.SKIPPED,
group: "comments",
});

// ── Identifiers (defined first — keywords reference via longer_alt) ────────
Expand Down
179 changes: 179 additions & 0 deletions packages/bridge/test/bridge-printer-examples.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import assert from "node:assert/strict";
import { describe, test } from "node:test";
import { formatBridge } from "../src/index.ts";

/**
* ============================================================================
* FULL EXAMPLE TEST CASES
*
* These tests show complete Bridge DSL snippets with expected formatting.
* Edit these to define the canonical style.
* ============================================================================
*/

describe("formatBridge - full examples", () => {
test("simple tool declaration", () => {
const input = `version 1.5
tool geo from std.httpCall`;
const expected = `version 1.5

tool geo from std.httpCall
`;
assert.equal(formatBridge(input), expected);
});

test("tool with body", () => {
const input = `version 1.5

tool geo from std.httpCall{
.baseUrl="https://example.com"
.method=GET
}`;
const expected = `version 1.5

tool geo from std.httpCall {
.baseUrl = "https://example.com"
.method = GET
}
`;
assert.equal(formatBridge(input), expected);
});

test("bridge block with assignments", () => {
const input = `version 1.5

bridge Query.test{
with input as i
with output as o
o.value<-i.value
}`;
const expected = `version 1.5

bridge Query.test {
with input as i
with output as o

o.value <- i.value
}
`;
assert.equal(formatBridge(input), expected);
});

test("define block", () => {
const input = `define myHelper{
with input as i
o.x<-i.y
}`;
const expected = `define myHelper {
with input as i

o.x <- i.y
}
`;
assert.equal(formatBridge(input), expected);
});

test("bridge with comment, tool handles, and pipes", () => {
const input = `version 1.5

bridge Query.greet {
#comment
with std.str.toUpperCase as uc
with std.str.toLowerCase as lc

with input as i
with output as o

o.message <- i.name
o.upper <- uc: i.name
o.lower <- lc: i.name
}`;
const expected = `version 1.5

bridge Query.greet {
#comment
with std.str.toUpperCase as uc
with std.str.toLowerCase as lc
with input as i
with output as o

o.message <- i.name
o.upper <- uc:i.name
o.lower <- lc:i.name
}
`;
assert.equal(formatBridge(input), expected);
});

test("ternary expressions preserve formatting", () => {
const input = `version 1.5

bridge Query.pricing {
with input as i
with output as o

# String literal branches
o.tier <- i.isPro ? "premium" : "basic"

# Numeric literal branches
o.discount <- i.isPro ? 20 : 5

# Source ref branches — selects proPrice or basicPrice
o.price <- i.isPro ? i.proPrice : i.basicPrice
}
`;
// Should not change
assert.equal(formatBridge(input), input);
});

test("blank line between top-level blocks", () => {
const input = `version 1.5

tool geo from std.httpCall
tool weather from std.httpCall
bridge Query.a {
with input as i
}
bridge Query.b {
with input as i
}
define helper {
with input as i
}`;
const expected = `version 1.5

tool geo from std.httpCall

tool weather from std.httpCall

bridge Query.a {
with input as i
}

bridge Query.b {
with input as i
}

define helper {
with input as i
}
`;
assert.equal(formatBridge(input), expected);
});

test("not operator preserves space", () => {
const input = `o.requireMFA <- not i.verified
`;
// Should not change
assert.equal(formatBridge(input), input);
});

test("blank lines between comments are preserved", () => {
const input = `#asdasd

#sdasdsd
`;
// Should not change
assert.equal(formatBridge(input), input);
});
});
Loading
Loading