Skip to content

Commit df98288

Browse files
committed
Add internal/js_scanner/js_scanner_test.go#FuzzHoistImport
Runnable via `go test ./internal/js_scanner -fuzz=FuzzHoistImports`
1 parent bf5d9fd commit df98288

3 files changed

Lines changed: 63 additions & 29 deletions

File tree

.gitpod.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# This configuration file was automatically generated by Gitpod.
2+
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
3+
# and commit this file to your remote git repository to share the goodness with others.
4+
5+
tasks:
6+
- init: pnpm install && pnpm run build && go get && go build ./... && go test ./... && make
7+
command: go run .
8+
9+

internal/js_scanner/js_scanner_test.go

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"strings"
77
"testing"
8+
"unicode/utf8"
89

910
"github.com/withastro/compiler/internal/test_utils"
1011
)
@@ -16,8 +17,8 @@ type testcase struct {
1617
only bool
1718
}
1819

19-
func TestHoistImport(t *testing.T) {
20-
tests := []testcase{
20+
func fixturesHoistImport() []testcase {
21+
return []testcase{
2122
{
2223
name: "basic",
2324
source: `const value = "test"`,
@@ -40,18 +41,18 @@ const article2 = await import('../markdown/article2.md')
4041
{
4142
name: "big import",
4243
source: `import {
43-
a,
44-
b,
45-
c,
46-
d,
44+
a,
45+
b,
46+
c,
47+
d,
4748
} from "package"
4849
4950
const b = await fetch();`,
5051
want: `import {
51-
a,
52-
b,
53-
c,
54-
d,
52+
a,
53+
b,
54+
c,
55+
d,
5556
} from "package"
5657
`,
5758
},
@@ -73,18 +74,18 @@ const b = await fetch();`,
7374
name: "import assertion 2",
7475
source: `// comment
7576
import {
76-
fn
77+
fn
7778
} from
78-
"package" assert {
79-
it: 'works'
80-
};
79+
"package" assert {
80+
it: 'works'
81+
};
8182
const b = await fetch();`,
8283
want: `import {
83-
fn
84+
fn
8485
} from
85-
"package" assert {
86-
it: 'works'
87-
};
86+
"package" assert {
87+
it: 'works'
88+
};
8889
`,
8990
},
9091
{
@@ -96,10 +97,10 @@ import Test from "../components/Test.astro";`,
9697
{
9798
name: "import.meta.env II",
9899
source: `console.log(
99-
import
100-
.meta
101-
.env
102-
.FOO
100+
import
101+
.meta
102+
.env
103+
.FOO
103104
);
104105
import Test from "../components/Test.astro";`,
105106
want: `import Test from "../components/Test.astro";`,
@@ -115,7 +116,7 @@ const b = await fetch()`,
115116
name: "getStaticPaths",
116117
source: `import { fn } from "package";
117118
export async function getStaticPaths() {
118-
const content = Astro.fetchContent('**/*.md');
119+
const content = Astro.fetchContent('**/*.md');
119120
}
120121
const b = await fetch()`,
121122
want: `import { fn } from "package";`,
@@ -124,7 +125,7 @@ const b = await fetch()`,
124125
name: "getStaticPaths with comments",
125126
source: `import { fn } from "package";
126127
export async function getStaticPaths() {
127-
const content = Astro.fetchContent('**/*.md');
128+
const content = Astro.fetchContent('**/*.md');
128129
}
129130
const b = await fetch()`,
130131
want: `import { fn } from "package";`,
@@ -133,29 +134,29 @@ const b = await fetch()`,
133134
name: "getStaticPaths with semicolon",
134135
source: `import { fn } from "package";
135136
export async function getStaticPaths() {
136-
const content = Astro.fetchContent('**/*.md');
137+
const content = Astro.fetchContent('**/*.md');
137138
}; const b = await fetch()`,
138139
want: `import { fn } from "package";`,
139140
},
140141
{
141142
name: "getStaticPaths with RegExp escape",
142143
source: `export async function getStaticPaths() {
143-
const pattern = /\.md$/g.test('value');
144+
const pattern = /\.md$/g.test('value');
144145
}
145146
import a from "a";`,
146147
want: `import a from "a";`,
147148
},
148149
{
149150
name: "getStaticPaths with divider",
150151
source: `export async function getStaticPaths() {
151-
const pattern = a / b;
152+
const pattern = a / b;
152153
}`,
153154
want: ``,
154155
},
155156
{
156157
name: "getStaticPaths with divider and following content",
157158
source: `export async function getStaticPaths() {
158-
const value = 1 / 2;
159+
const value = 1 / 2;
159160
}
160161
// comment
161162
import { b } from "b";
@@ -165,7 +166,7 @@ const { a } = Astro.props;`,
165166
{
166167
name: "getStaticPaths with regex and following content",
167168
source: `export async function getStaticPaths() {
168-
const value = /2/g;
169+
const value = /2/g;
169170
}
170171
// comment
171172
import { b } from "b";
@@ -203,6 +204,10 @@ import { c } from "c";
203204
`,
204205
},
205206
}
207+
}
208+
209+
func TestHoistImport(t *testing.T) {
210+
tests := fixturesHoistImport()
206211
for _, tt := range tests {
207212
if tt.only {
208213
tests = make([]testcase, 0)
@@ -226,6 +231,24 @@ import { c } from "c";
226231
}
227232
}
228233

234+
func FuzzHoistImport(f *testing.F) {
235+
tests := fixturesHoistImport()
236+
for _, tt := range tests {
237+
f.Add(tt.source) // Use f.Add to provide a seed corpus
238+
}
239+
f.Fuzz(func(t *testing.T, source string) {
240+
result := HoistImports([]byte(source))
241+
got := []byte{}
242+
for _, imp := range result.Hoisted {
243+
got = append(got, bytes.TrimSpace(imp)...)
244+
got = append(got, '\n')
245+
}
246+
if utf8.ValidString(source) && !utf8.ValidString(string(got)) {
247+
t.Errorf("HTML scoping produced invalid html string: %q", got)
248+
}
249+
})
250+
}
251+
229252
func TestHoistExport(t *testing.T) {
230253
tests := []testcase{
231254
{
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
go test fuzz v1
2+
string("import\"\nimport \"\";")

0 commit comments

Comments
 (0)