blob: 377f09d94e51b7a5881094b53b1ca1ada7b8fa63 [file] [log] [blame]
package compiler
import (
"bytes"
"go/ast"
"go/build"
"go/parser"
"go/token"
"go/types"
"testing"
"github.com/google/go-cmp/cmp"
"golang.org/x/tools/go/loader"
)
func TestOrder(t *testing.T) {
fileA := `
package foo
var Avar = "a"
type Atype struct{}
func Afunc() int {
var varA = 1
var varB = 2
return varA+varB
}
`
fileB := `
package foo
var Bvar = "b"
type Btype struct{}
func Bfunc() int {
var varA = 1
var varB = 2
return varA+varB
}
`
files := []source{{"fileA.go", []byte(fileA)}, {"fileB.go", []byte(fileB)}}
compare(t, "foo", files, false)
compare(t, "foo", files, true)
}
func compare(t *testing.T, path string, sourceFiles []source, minify bool) {
outputNormal, err := compile(path, sourceFiles, minify)
if err != nil {
t.Fatal(err)
}
// reverse the array
for i, j := 0, len(sourceFiles)-1; i < j; i, j = i+1, j-1 {
sourceFiles[i], sourceFiles[j] = sourceFiles[j], sourceFiles[i]
}
outputReversed, err := compile(path, sourceFiles, minify)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(string(outputNormal), string(outputReversed)); diff != "" {
t.Errorf("files in different order produce different JS:\n%s", diff)
}
}
type source struct {
name string
contents []byte
}
func compile(path string, sourceFiles []source, minify bool) ([]byte, error) {
conf := loader.Config{}
conf.Fset = token.NewFileSet()
conf.ParserMode = parser.ParseComments
context := build.Default // make a copy of build.Default
conf.Build = &context
conf.Build.BuildTags = []string{"js"}
var astFiles []*ast.File
for _, sourceFile := range sourceFiles {
astFile, err := parser.ParseFile(conf.Fset, sourceFile.name, sourceFile.contents, parser.ParseComments)
if err != nil {
return nil, err
}
astFiles = append(astFiles, astFile)
}
conf.CreateFromFiles(path, astFiles...)
prog, err := conf.Load()
if err != nil {
return nil, err
}
archiveCache := map[string]*Archive{}
var importContext *ImportContext
importContext = &ImportContext{
Packages: make(map[string]*types.Package),
Import: func(path string) (*Archive, error) {
// find in local cache
if a, ok := archiveCache[path]; ok {
return a, nil
}
pi := prog.Package(path)
importContext.Packages[path] = pi.Pkg
// compile package
a, err := Compile(path, pi.Files, prog.Fset, importContext, minify)
if err != nil {
return nil, err
}
archiveCache[path] = a
return a, nil
},
}
a, err := importContext.Import(path)
if err != nil {
return nil, err
}
b, err := renderPackage(a)
if err != nil {
return nil, err
}
return b, nil
}
func renderPackage(archive *Archive) ([]byte, error) {
selection := make(map[*Decl]struct{})
for _, d := range archive.Declarations {
selection[d] = struct{}{}
}
buf := &bytes.Buffer{}
if err := WritePkgCode(archive, selection, goLinknameSet{}, false, &SourceMapFilter{Writer: buf}); err != nil {
return nil, err
}
return buf.Bytes(), nil
}