Files
2026-07-13 12:32:25 +08:00

151 lines
4.7 KiB
Go

// Copyright 2024 Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"strings"
"time"
"github.com/cockroachdb/errors"
"github.com/jackc/pgx/v5/pgtype"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"github.com/dolthub/doltgresql/testing/generation/utils"
)
const TestHeader = `// Copyright %d Dolthub, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package output
import (
"testing"
"github.com/dolthub/go-mysql-server/sql"
)
func Test_%s(t *testing.T) {
RunScripts(t, []ScriptTest{
`
const TestFooter = ` })
}
`
// GenerateTests generates and writes a test file for the given function.
func GenerateTests(parentFolder utils.RootFolderLocation, functionName string, assertions []Assertion) error {
// We want to skip some functions since we know they'll always return a different result
switch functionName {
case "random":
return nil
}
// For now we'll skip some functions that will take a long time to calculate
switch functionName {
case "exp", "factorial", "lpad", "power", "rpad", "repeat", "round":
return nil
}
sb := strings.Builder{}
sb.WriteString(fmt.Sprintf(TestHeader, time.Now().Year(),
strings.ReplaceAll(cases.Title(language.English).String(strings.ReplaceAll(functionName, "_", " ")), " ", "")))
sb.WriteString("\t\t{\n")
sb.WriteString(fmt.Sprintf("\t\t\tName: \"%s\",\n", functionName))
sb.WriteString("\t\t\tAssertions: []ScriptTestAssertion{\n")
for _, assertion := range assertions {
sb.WriteString("\t\t\t\t{\n")
if !assertion.Error {
sb.WriteString(fmt.Sprintf("\t\t\t\t\tQuery: \"%s\",\n", assertion.Stmt))
sb.WriteString("\t\t\t\t\tExpected: []sql.Row{")
for i, results := range assertion.Rows {
if i > 0 {
sb.WriteRune(',')
}
sb.WriteRune('{')
for j, result := range results {
if j > 0 {
sb.WriteRune(',')
}
switch result := result.(type) {
case int:
sb.WriteString(fmt.Sprintf("int64(%d)", result))
case int8:
sb.WriteString(fmt.Sprintf("int8(%d)", result))
case int16:
sb.WriteString(fmt.Sprintf("int16(%d)", result))
case int32:
sb.WriteString(fmt.Sprintf("int32(%d)", result))
case int64:
sb.WriteString(fmt.Sprintf("int64(%d)", result))
case uint:
sb.WriteString(fmt.Sprintf("uint64(%d)", result))
case uint8:
sb.WriteString(fmt.Sprintf("uint8(%d)", result))
case uint16:
sb.WriteString(fmt.Sprintf("uint16(%d)", result))
case uint32:
sb.WriteString(fmt.Sprintf("uint32(%d)", result))
case uint64:
sb.WriteString(fmt.Sprintf("uint64(%d)", result))
case float32:
sb.WriteString(fmt.Sprintf("float32(%f)", result))
case float64:
sb.WriteString(fmt.Sprintf("float64(%f)", result))
case string:
sb.WriteString(fmt.Sprintf("%q", result))
case pgtype.Numeric:
sb.WriteString(fmt.Sprintf(`Numeric("%s")`, NumericToString(result)))
case nil:
sb.WriteString("nil")
default:
return errors.Errorf("%T does not have a switch case", result)
}
}
sb.WriteRune('}')
}
sb.WriteString("},\n")
} else {
sb.WriteString(fmt.Sprintf("\t\t\t\t\tQuery: \"%s\",\n", assertion.Stmt))
sb.WriteString("\t\t\t\t\tExpectedErr: true,\n")
}
sb.WriteString("\t\t\t\t},\n")
}
sb.WriteString("\t\t\t},\n")
sb.WriteString("\t\t},\n")
sb.WriteString(TestFooter)
outputFileName := strings.ToLower(strings.ReplaceAll(functionName, " ", "_"))
return parentFolder.WriteFileToDirectory("output", outputFileName+"_test.go", []byte(sb.String()), 0644)
}
// NumericToString converts a numeric to a string.
func NumericToString(numeric pgtype.Numeric) string {
str, err := numeric.Value()
if err != nil {
panic(err)
}
return str.(string)
}