2025-10-15 10:12:44 +03:00

125 lines
3.9 KiB
Go

package tsbaseline
import (
"encoding/base64"
"net/url"
"slices"
"strings"
"testing"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/sourcemap"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/testutil/baseline"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/testutil/harnessutil"
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
"github.com/go-json-experiment/json"
)
func DoSourcemapBaseline(
t *testing.T,
baselinePath string,
header string,
options *core.CompilerOptions,
result *harnessutil.CompilationResult,
harnessSettings *harnessutil.HarnessOptions,
opts baseline.Options,
) {
declMaps := options.GetAreDeclarationMapsEnabled()
if options.InlineSourceMap.IsTrue() {
if result.Maps.Size() > 0 && !declMaps {
t.Fatal("No sourcemap files should be generated if inlineSourceMaps was set.")
}
return
} else if options.SourceMap.IsTrue() || declMaps {
expectedMapCount := 0
if options.SourceMap.IsTrue() {
expectedMapCount += result.GetNumberOfJSFiles( /*includeJSON*/ false)
}
if declMaps {
expectedMapCount += result.GetNumberOfJSFiles( /*includeJSON*/ true)
}
if result.Maps.Size() != expectedMapCount {
t.Fatal("Number of sourcemap files should be same as js files.")
}
var sourceMapCode string
if options.NoEmitOnError.IsTrue() && len(result.Diagnostics) != 0 || result.Maps.Size() == 0 {
sourceMapCode = baseline.NoContent
} else {
var sourceMapCodeBuilder strings.Builder
for sourceMap := range result.Maps.Values() {
if sourceMapCodeBuilder.Len() > 0 {
sourceMapCodeBuilder.WriteString("\r\n")
}
sourceMapCodeBuilder.WriteString(fileOutput(sourceMap, harnessSettings))
if !options.InlineSourceMap.IsTrue() {
sourceMapCodeBuilder.WriteString(createSourceMapPreviewLink(sourceMap, result))
}
}
sourceMapCode = sourceMapCodeBuilder.String()
}
if tspath.FileExtensionIsOneOf(baselinePath, []string{tspath.ExtensionTs, tspath.ExtensionTsx}) {
baselinePath = tspath.ChangeExtension(baselinePath, tspath.ExtensionJs+".map")
}
baseline.Run(t, baselinePath, sourceMapCode, opts)
}
}
func createSourceMapPreviewLink(sourceMap *harnessutil.TestFile, result *harnessutil.CompilationResult) string {
var sourcemapJSON sourcemap.RawSourceMap
if err := json.Unmarshal([]byte(sourceMap.Content), &sourcemapJSON); err != nil {
panic(err)
}
outputJSFile := core.Find(result.Outputs(), func(td *harnessutil.TestFile) bool {
return strings.HasSuffix(td.UnitName, sourcemapJSON.File)
})
// !!! Strada uses a fallible approach to associating inputs and outputs derived from a source map output. The
// !!! commented logic below should be used after the Strada migration is complete:
////inputsAndOutputs := result.GetInputsAndOutputsForFile(sourceMap.UnitName)
////outputJSFile := inputsAndOutputs.Js
if outputJSFile == nil {
return ""
}
var sourceTDs []*harnessutil.TestFile
////if len(sourcemapJSON.Sources) == len(inputsAndOutputs.Inputs) {
//// sourceTDs = inputsAndOutputs.Inputs
////} else {
sourceTDs = core.Map(sourcemapJSON.Sources, func(s string) *harnessutil.TestFile {
return core.Find(result.Inputs(), func(td *harnessutil.TestFile) bool {
return strings.HasSuffix(td.UnitName, s)
})
})
if slices.Contains(sourceTDs, nil) {
return ""
}
////}
var hash strings.Builder
hash.WriteString("\n//// https://sokra.github.io/source-map-visualization#base64,")
hash.WriteString(base64EncodeChunk(outputJSFile.Content))
hash.WriteString(",")
hash.WriteString(base64EncodeChunk(sourceMap.Content))
for _, td := range sourceTDs {
hash.WriteString(",")
hash.WriteString(base64EncodeChunk(td.Content))
}
hash.WriteRune('\n')
return hash.String()
}
func base64EncodeChunk(s string) string {
s = url.QueryEscape(s)
s, err := url.QueryUnescape(s)
if err != nil {
panic(err)
}
return base64.StdEncoding.EncodeToString([]byte(s))
}