mirror of
https://github.com/golang/go
synced 2024-11-20 05:14:41 -07:00
cmd/api: add more tests
Feature extraction was tested before, but not the final diffs. This CL breaks function main into a smaller main + testable compareAPI. No functional changes. R=golang-dev, adg CC=golang-dev https://golang.org/cl/6820057
This commit is contained in:
parent
1d61c9bb3e
commit
e53a2c40b1
@ -22,6 +22,7 @@ import (
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
@ -167,7 +168,6 @@ func main() {
|
||||
features = append(features, f2)
|
||||
}
|
||||
}
|
||||
sort.Strings(features)
|
||||
|
||||
fail := false
|
||||
defer func() {
|
||||
@ -186,26 +186,27 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
var required []string
|
||||
for _, filename := range []string{*checkFile} {
|
||||
required = append(required, fileFeatures(filename)...)
|
||||
required := fileFeatures(*checkFile)
|
||||
optional := fileFeatures(*nextFile)
|
||||
exception := fileFeatures(*exceptFile)
|
||||
fail = !compareAPI(bw, features, required, optional, exception)
|
||||
}
|
||||
|
||||
func compareAPI(w io.Writer, features, required, optional, exception []string) (ok bool) {
|
||||
ok = true
|
||||
|
||||
var optionalSet = make(map[string]bool) // feature => true
|
||||
var exceptionSet = make(map[string]bool) // exception => true
|
||||
for _, f := range optional {
|
||||
optionalSet[f] = true
|
||||
}
|
||||
for _, f := range exception {
|
||||
exceptionSet[f] = true
|
||||
}
|
||||
|
||||
sort.Strings(features)
|
||||
sort.Strings(required)
|
||||
|
||||
var optional = make(map[string]bool) // feature => true
|
||||
if *nextFile != "" {
|
||||
for _, feature := range fileFeatures(*nextFile) {
|
||||
optional[feature] = true
|
||||
}
|
||||
}
|
||||
|
||||
var exception = make(map[string]bool) // exception => true
|
||||
if *exceptFile != "" {
|
||||
for _, feature := range fileFeatures(*exceptFile) {
|
||||
exception[feature] = true
|
||||
}
|
||||
}
|
||||
|
||||
take := func(sl *[]string) string {
|
||||
s := (*sl)[0]
|
||||
*sl = (*sl)[1:]
|
||||
@ -216,23 +217,23 @@ func main() {
|
||||
switch {
|
||||
case len(features) == 0 || required[0] < features[0]:
|
||||
feature := take(&required)
|
||||
if exception[feature] {
|
||||
fmt.Fprintf(bw, "~%s\n", feature)
|
||||
if exceptionSet[feature] {
|
||||
fmt.Fprintf(w, "~%s\n", feature)
|
||||
} else {
|
||||
fmt.Fprintf(bw, "-%s\n", feature)
|
||||
fail = true // broke compatibility
|
||||
fmt.Fprintf(w, "-%s\n", feature)
|
||||
ok = false // broke compatibility
|
||||
}
|
||||
case len(required) == 0 || required[0] > features[0]:
|
||||
newFeature := take(&features)
|
||||
if optional[newFeature] {
|
||||
if optionalSet[newFeature] {
|
||||
// Known added feature to the upcoming release.
|
||||
// Delete it from the map so we can detect any upcoming features
|
||||
// which were never seen. (so we can clean up the nextFile)
|
||||
delete(optional, newFeature)
|
||||
delete(optionalSet, newFeature)
|
||||
} else {
|
||||
fmt.Fprintf(bw, "+%s\n", newFeature)
|
||||
fmt.Fprintf(w, "+%s\n", newFeature)
|
||||
if !*allowNew {
|
||||
fail = true // we're in lock-down mode for next release
|
||||
ok = false // we're in lock-down mode for next release
|
||||
}
|
||||
}
|
||||
default:
|
||||
@ -243,16 +244,20 @@ func main() {
|
||||
|
||||
// In next file, but not in API.
|
||||
var missing []string
|
||||
for feature := range optional {
|
||||
for feature := range optionalSet {
|
||||
missing = append(missing, feature)
|
||||
}
|
||||
sort.Strings(missing)
|
||||
for _, feature := range missing {
|
||||
fmt.Fprintf(bw, "±%s\n", feature)
|
||||
fmt.Fprintf(w, "±%s\n", feature)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func fileFeatures(filename string) []string {
|
||||
if filename == "" {
|
||||
return nil
|
||||
}
|
||||
bs, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading file %s: %v", filename, err)
|
||||
|
@ -5,6 +5,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -73,3 +74,53 @@ func TestGolden(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompareAPI(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
features, required, optional, exception []string
|
||||
ok bool // want
|
||||
out string // want
|
||||
}{
|
||||
{
|
||||
name: "feature added",
|
||||
features: []string{"C", "A", "B"},
|
||||
required: []string{"A", "C"},
|
||||
ok: true,
|
||||
out: "+B\n",
|
||||
},
|
||||
{
|
||||
name: "feature removed",
|
||||
features: []string{"C", "A"},
|
||||
required: []string{"A", "B", "C"},
|
||||
ok: false,
|
||||
out: "-B\n",
|
||||
},
|
||||
{
|
||||
name: "feature added then removed",
|
||||
features: []string{"A", "C"},
|
||||
optional: []string{"B"},
|
||||
required: []string{"A", "C"},
|
||||
ok: true,
|
||||
out: "±B\n",
|
||||
},
|
||||
{
|
||||
name: "exception removal",
|
||||
required: []string{"A", "B", "C"},
|
||||
features: []string{"A", "C"},
|
||||
exception: []string{"B"},
|
||||
ok: true,
|
||||
out: "~B\n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
buf := new(bytes.Buffer)
|
||||
gotok := compareAPI(buf, tt.features, tt.required, tt.optional, tt.exception)
|
||||
if gotok != tt.ok {
|
||||
t.Errorf("%s: ok = %v; want %v", tt.name, gotok, tt.ok)
|
||||
}
|
||||
if got := buf.String(); got != tt.out {
|
||||
t.Errorf("%s: output differs\nGOT:\n%s\nWANT:\n%s", tt.name, got, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user