Skip to content

Commit

Permalink
Refactor specs
Browse files Browse the repository at this point in the history
  • Loading branch information
emilos committed Mar 27, 2024
1 parent a112582 commit af778a0
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 36 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,9 @@ console.log(match({ type: "Literal", value: 41 }, "Literal[value=42]")) // false

#### template

The function converts the input to an equivalent abstract syntax tree representation.
The function converts the input to an equivalent abstract syntax tree representation. The function uses a `<%= %>` syntax to insert nodes.

You can also use standard javascript types and they're going to be transformed automatically.

```js
const { template } = require("abstract-syntax-tree")
Expand All @@ -382,14 +384,22 @@ const nodes = template("const foo = <%= bar %>;", {

```js
const { template } = require("abstract-syntax-tree")
const nodes = template("function foo(%= bar %) {}", {
const nodes = template("function foo(<%= bar %>) {}", {
bar: [
{ type: "Identifier", name: "baz" },
{ type: "Identifier", name: "qux" },
],
})
```

```js
const { template } = require("abstract-syntax-tree")
const literal = template(42)
const nodes = template("const foo = <%= bar %>;", {
bar: 1,
})
```

#### program

Creates an abstract syntax tree with a blank program.
Expand Down
15 changes: 9 additions & 6 deletions src/template/transform.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
"use strict"

const parse = require("../parse")
// const traverse = require("../traverse")
// const replace = require("../replace")
const tokenize = require("./tokenize")
const generate = require("../generate")

Expand All @@ -11,9 +7,16 @@ function transform(string, data) {

tokens.forEach((token) => {
if (token.type === "expression") {
if (data[token.value]) {
const value = data[token.value]
if (value) {
token.type = "code"
token.value = generate(data[token.value])
if (Array.isArray(value)) {
token.value = value.map((node) => generate(node)).join(", ")
} else if (typeof value === "object") {
token.value = generate(value)
} else {
token.value = value
}
}
}
})
Expand Down
72 changes: 46 additions & 26 deletions test/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,31 @@ test("template: from string", () => {
])
})

test("template: from string literal with params", () => {
assert.deepEqual(
template("const foo = <%= value %>;", {
value: { type: "Literal", value: 42 },
}),
[
{
type: "VariableDeclaration",
declarations: [
{
type: "VariableDeclarator",
id: { type: "Identifier", name: "foo" },
init: { type: "Literal", value: 42 },
},
],
kind: "const",
},
]
)
})

test("template: from string with params", () => {
assert.deepEqual(
template("const foo = <%= value %>;", {
value: { type: "Literal", value: "bar" },
value: 42,
}),
[
{
Expand All @@ -31,7 +52,7 @@ test("template: from string with params", () => {
{
type: "VariableDeclarator",
id: { type: "Identifier", name: "foo" },
init: { type: "Literal", value: "bar" },
init: { type: "Literal", value: 42 },
},
],
kind: "const",
Expand Down Expand Up @@ -70,9 +91,9 @@ test("template: simple substitution", () => {
)
})

test.skip("template: spread array elements", () => {
test("template: spread array elements", () => {
assert.deepEqual(
convert("var a = [%= items %];", {
convert("var a = [<%= items %>];", {
items: [
{ type: "Literal", value: 123 },
{ type: "Literal", value: 456 },
Expand All @@ -82,9 +103,9 @@ test.skip("template: spread array elements", () => {
)
})

test.skip("template: spread call arguments", () => {
test("template: spread call arguments", () => {
assert.deepEqual(
convert("var x = f(%= items %);", {
convert("var x = f(<%= items %>);", {
items: [
{ type: "Literal", value: 123 },
{ type: "Literal", value: 456 },
Expand All @@ -94,9 +115,9 @@ test.skip("template: spread call arguments", () => {
)
})

test.skip("template: spread function params", () => {
test("template: spread function params", () => {
assert.deepEqual(
convert("function f(%= params %) {}", {
convert("function f(<%= params %>) {}", {
params: [
{ type: "Identifier", name: "a" },
{ type: "Identifier", name: "b" },
Expand All @@ -106,9 +127,9 @@ test.skip("template: spread function params", () => {
)
})

test.skip("template: spread block elements", () => {
test("template: spread block elements", () => {
assert.deepEqual(
convert("define(function () {%= body %});", {
convert("define(function () {<%= body %>});", {
body: parse('module.exports = require("./module").property;').body,
}),
`define(function () {
Expand All @@ -117,19 +138,19 @@ test.skip("template: spread block elements", () => {
)
})

test.skip("template: spread program root", () => {
test("template: spread program root", () => {
assert.deepEqual(
convert("var x = 42; %= body %", {
convert("var x = 42; <%= body %>", {
body: parse("var y = 42;").body,
}),
`var x = 42;
var y = 42;`
)
})

test.skip("template: spread literals", () => {
test("template: spread literals", () => {
assert.deepEqual(
convert('var a = "%= x %"; var b = "%= y %";', {
convert('var a = "<%= x %>"; var b = "<%= y %>";', {
x: "alpha",
y: "beta",
}),
Expand All @@ -138,9 +159,9 @@ var b = "beta";`
)
})

test.skip("template: spread concatenation with inline elements", () => {
test("template: spread concatenation with inline elements", () => {
assert.deepEqual(
convert("var a = [123, %= items %];", {
convert("var a = [123, <%= items %>];", {
items: [
{ type: "Literal", value: 456 },
{ type: "Literal", value: 789 },
Expand All @@ -150,9 +171,9 @@ test.skip("template: spread concatenation with inline elements", () => {
)
})

test.skip("template: spread concatenation with function params", () => {
test("template: spread concatenation with function params", () => {
assert.deepEqual(
convert("function f(%= params %, callback) {}", {
convert("function f(<%= params %>, callback) {}", {
params: [
{ type: "Identifier", name: "a" },
{ type: "Identifier", name: "b" },
Expand All @@ -162,12 +183,12 @@ test.skip("template: spread concatenation with function params", () => {
)
})

test.skip("template: spread concatenation around elements", () => {
test("template: spread concatenation around elements", () => {
assert.deepEqual(
convert(
'function f() { console.time("module"); %= body %; console.timeEnd("module"); }',
'function f() { console.time("module"); <%= body %> console.timeEnd("module"); }',
{
body: parse("init(); doSmth(); finalize();").body,
body: parse("init(); doSmth(); finalize();"),
}
),
`function f() {
Expand All @@ -180,11 +201,11 @@ test.skip("template: spread concatenation around elements", () => {
)
})

test.skip("template: spread concatenation between elements", () => {
test("template: spread concatenation between elements", () => {
assert.deepEqual(
convert("function f() { %= init %; doSmth(); %= finalize %; }", {
init: parse('console.time("module"); init();').body,
finalize: parse('finalize(); console.timeEnd("module");').body,
convert("function f() { <%= init %> doSmth(); <%= finalize %> }", {
init: parse('console.time("module"); init();'),
finalize: parse('finalize(); console.timeEnd("module");'),
}),
`function f() {
console.time("module");
Expand Down Expand Up @@ -220,7 +241,6 @@ test("template: from functions", () => {
})

test("template: from arrays", () => {
// assert.deepEqual(convert([], '[]'))
assert.deepEqual(convert([1, 2, 3]), "[1, 2, 3]")
assert.deepEqual(convert(["foo", "bar"]), '["foo", "bar"]')
assert.deepEqual(
Expand Down
4 changes: 2 additions & 2 deletions test/template/tokenize.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ const test = require("node:test")
const assert = require("node:assert")
const tokenize = require("../../src/template/tokenize")

test("template: tokenizes code", () => {
test("tokenizes code", () => {
assert.deepEqual(tokenize('const foo = "bar";'), [
{ type: "code", value: 'const foo = "bar";' },
])
})

test("template: tokenizes expressions", () => {
test("tokenizes expressions", () => {
assert.deepEqual(tokenize("const foo = <%= bar %>"), [
{ type: "code", value: "const foo = " },
{ type: "expression", value: "bar" },
Expand Down

0 comments on commit af778a0

Please sign in to comment.