Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

fix(status): fix Constraint & Version json output #976

Merged
merged 4 commits into from
Aug 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 50 additions & 18 deletions cmd/dep/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,10 @@ func (out *tableOutput) BasicFooter() {
}

func (out *tableOutput) BasicLine(bs *BasicStatus) {
var constraint string
if v, ok := bs.Constraint.(gps.Version); ok {
constraint = formatVersion(v)
} else {
constraint = bs.Constraint.String()
}
if bs.hasOverride {
constraint += " (override)"
}
fmt.Fprintf(out.w,
"%s\t%s\t%s\t%s\t%s\t%d\t\n",
bs.ProjectRoot,
constraint,
bs.getConsolidatedConstraint(),
formatVersion(bs.Version),
formatVersion(bs.Revision),
formatVersion(bs.Latest),
Expand All @@ -127,20 +118,20 @@ func (out *tableOutput) MissingFooter() {

type jsonOutput struct {
w io.Writer
basic []*BasicStatus
basic []*rawStatus
missing []*MissingStatus
}

func (out *jsonOutput) BasicHeader() {
out.basic = []*BasicStatus{}
out.basic = []*rawStatus{}
}

func (out *jsonOutput) BasicFooter() {
json.NewEncoder(out.w).Encode(out.basic)
}

func (out *jsonOutput) BasicLine(bs *BasicStatus) {
out.basic = append(out.basic, bs)
out.basic = append(out.basic, bs.marshalJSON())
}

func (out *jsonOutput) MissingHeader() {
Expand Down Expand Up @@ -177,11 +168,7 @@ func (out *dotOutput) BasicFooter() {
}

func (out *dotOutput) BasicLine(bs *BasicStatus) {
version := formatVersion(bs.Revision)
if bs.Version != nil {
version = formatVersion(bs.Version)
}
out.g.createNode(bs.ProjectRoot, version, bs.Children)
out.g.createNode(bs.ProjectRoot, bs.getConsolidatedVersion(), bs.Children)
}

func (out *dotOutput) MissingHeader() {}
Expand Down Expand Up @@ -243,6 +230,15 @@ func (cmd *statusCommand) Run(ctx *dep.Ctx, args []string) error {
return nil
}

type rawStatus struct {
ProjectRoot string
Constraint string
Version string
Revision gps.Revision
Latest gps.Version
PackageCount int
}

// BasicStatus contains all the information reported about a single dependency
// in the summary/list status output mode.
type BasicStatus struct {
Expand All @@ -256,6 +252,42 @@ type BasicStatus struct {
hasOverride bool
}

func (bs *BasicStatus) getConsolidatedConstraint() string {
var constraint string
if bs.Constraint != nil {
if v, ok := bs.Constraint.(gps.Version); ok {
constraint = formatVersion(v)
} else {
constraint = bs.Constraint.String()
}
}

if bs.hasOverride {
constraint += " (override)"
}

return constraint
}

func (bs *BasicStatus) getConsolidatedVersion() string {
version := formatVersion(bs.Revision)
if bs.Version != nil {
version = formatVersion(bs.Version)
}
return version
}

func (bs *BasicStatus) marshalJSON() *rawStatus {
return &rawStatus{
ProjectRoot: bs.ProjectRoot,
Constraint: bs.getConsolidatedConstraint(),
Version: formatVersion(bs.Version),
Revision: bs.Revision,
Latest: bs.Latest,
PackageCount: bs.PackageCount,
}
}

// MissingStatus contains information about all the missing packages in a project.
type MissingStatus struct {
ProjectRoot string
Expand Down
201 changes: 178 additions & 23 deletions cmd/dep/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package main
import (
"bytes"
"testing"
"text/tabwriter"

"strings"

Expand All @@ -32,36 +33,190 @@ func TestStatusFormatVersion(t *testing.T) {
}

func TestBasicLine(t *testing.T) {

project := dep.Project{}
aSemverConstraint, _ := gps.NewSemverConstraint("1.2.3")

var tests = []struct {
status BasicStatus
expected string
tests := []struct {
name string
status BasicStatus
wantDotStatus []string
wantJSONStatus []string
wantTableStatus []string
}{
{BasicStatus{
Version: nil,
Revision: gps.Revision("flooboofoobooo"),
}, `[label="\nflooboo"];`},
{BasicStatus{
Version: gps.NewVersion("1.0.0"),
Revision: gps.Revision("flooboofoobooo"),
}, `[label="\n1.0.0"];`},
{
name: "BasicStatus with ProjectRoot only",
status: BasicStatus{
ProjectRoot: "github.com/foo/bar",
},
wantDotStatus: []string{`[label="github.com/foo/bar"];`},
wantJSONStatus: []string{`"Version":""`, `"Revision":""`},
wantTableStatus: []string{`github.com/foo/bar 0`},
},
{
name: "BasicStatus with Revision",
status: BasicStatus{
ProjectRoot: "github.com/foo/bar",
Revision: gps.Revision("flooboofoobooo"),
},
wantDotStatus: []string{`[label="github.com/foo/bar\nflooboo"];`},
wantJSONStatus: []string{`"Version":""`, `"Revision":"flooboofoobooo"`, `"Constraint":""`},
wantTableStatus: []string{`github.com/foo/bar flooboo 0`},
},
{
name: "BasicStatus with Version and Revision",
status: BasicStatus{
ProjectRoot: "github.com/foo/bar",
Version: gps.NewVersion("1.0.0"),
Revision: gps.Revision("flooboofoobooo"),
},
wantDotStatus: []string{`[label="github.com/foo/bar\n1.0.0"];`},
wantJSONStatus: []string{`"Version":"1.0.0"`, `"Revision":"flooboofoobooo"`, `"Constraint":""`},
wantTableStatus: []string{`github.com/foo/bar 1.0.0 flooboo 0`},
},
{
name: "BasicStatus with Constraint, Version and Revision",
status: BasicStatus{
ProjectRoot: "github.com/foo/bar",
Constraint: aSemverConstraint,
Version: gps.NewVersion("1.0.0"),
Revision: gps.Revision("revxyz"),
},
wantDotStatus: []string{`[label="github.com/foo/bar\n1.0.0"];`},
wantJSONStatus: []string{`"Revision":"revxyz"`, `"Constraint":"1.2.3"`, `"Version":"1.0.0"`},
wantTableStatus: []string{`github.com/foo/bar 1.2.3 1.0.0 revxyz 0`},
},
}

for _, test := range tests {
var buf bytes.Buffer
t.Run(test.name, func(t *testing.T) {
var buf bytes.Buffer

out := &dotOutput{
p: &project,
w: &buf,
}
out.BasicHeader()
out.BasicLine(&test.status)
out.BasicFooter()
dotout := &dotOutput{
p: &project,
w: &buf,
}
dotout.BasicHeader()
dotout.BasicLine(&test.status)
dotout.BasicFooter()

if ok := strings.Contains(buf.String(), test.expected); !ok {
t.Fatalf("Did not find expected node label: \n\t(GOT) %v \n\t(WNT) %v", buf.String(), test.status)
}
for _, wantStatus := range test.wantDotStatus {
if ok := strings.Contains(buf.String(), wantStatus); !ok {
t.Errorf("Did not find expected node status: \n\t(GOT) %v \n\t(WNT) %v", buf.String(), wantStatus)
}
}

buf.Reset()

jsonout := &jsonOutput{w: &buf}

jsonout.BasicHeader()
jsonout.BasicLine(&test.status)
jsonout.BasicFooter()

for _, wantStatus := range test.wantJSONStatus {
if ok := strings.Contains(buf.String(), wantStatus); !ok {
t.Errorf("Did not find expected JSON status: \n\t(GOT) %v \n\t(WNT) %v", buf.String(), wantStatus)
}
}

buf.Reset()

tabw := tabwriter.NewWriter(&buf, 0, 4, 2, ' ', 0)

tableout := &tableOutput{w: tabw}

tableout.BasicHeader()
tableout.BasicLine(&test.status)
tableout.BasicFooter()

for _, wantStatus := range test.wantTableStatus {
if ok := strings.Contains(buf.String(), wantStatus); !ok {
t.Errorf("Did not find expected Table status: \n\t(GOT) %v \n\t(WNT) %v", buf.String(), wantStatus)
}
}
})
}
}

func TestBasicStatusGetConsolidatedConstraint(t *testing.T) {
aSemverConstraint, _ := gps.NewSemverConstraint("1.2.1")

testCases := []struct {
name string
basicStatus BasicStatus
wantConstraint string
}{
{
name: "empty BasicStatus",
basicStatus: BasicStatus{},
wantConstraint: "",
},
{
name: "BasicStatus with Any Constraint",
basicStatus: BasicStatus{
Constraint: gps.Any(),
},
wantConstraint: "*",
},
{
name: "BasicStatus with Semver Constraint",
basicStatus: BasicStatus{
Constraint: aSemverConstraint,
},
wantConstraint: "1.2.1",
},
{
name: "BasicStatus with Override",
basicStatus: BasicStatus{
Constraint: aSemverConstraint,
hasOverride: true,
},
wantConstraint: "1.2.1 (override)",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if tc.basicStatus.getConsolidatedConstraint() != tc.wantConstraint {
t.Errorf("unexpected consolidated constraint: \n\t(GOT) %v \n\t(WNT) %v", tc.basicStatus.getConsolidatedConstraint(), tc.wantConstraint)
}
})
}
}

func TestBasicStatusGetConsolidatedVersion(t *testing.T) {
testCases := []struct {
name string
basicStatus BasicStatus
wantVersion string
}{
{
name: "empty BasicStatus",
basicStatus: BasicStatus{},
wantVersion: "",
},
{
name: "BasicStatus with Version and Revision",
basicStatus: BasicStatus{
Version: gps.NewVersion("1.0.0"),
Revision: gps.Revision("revxyz"),
},
wantVersion: "1.0.0",
},
{
name: "BasicStatus with only Revision",
basicStatus: BasicStatus{
Revision: gps.Revision("revxyz"),
},
wantVersion: "revxyz",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if tc.basicStatus.getConsolidatedVersion() != tc.wantVersion {
t.Errorf("unexpected consolidated version: \n\t(GOT) %v \n\t(WNT) %v", tc.basicStatus.getConsolidatedVersion(), tc.wantVersion)
}
})
}
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"ProjectRoot":"github.com/sdboyer/deptest","Children":null,"Constraint":{},"Version":{},"Revision":"ff2948a2ac8f538c4ecd55962e919d1e13e74baf","Latest":"3f4c3bea144e112a69bbe5d8d01c1b09a544253f","PackageCount":1},{"ProjectRoot":"github.com/sdboyer/deptestdos","Children":null,"Constraint":{},"Version":{},"Revision":"5c607206be5decd28e6263ffffdcee067266015e","Latest":"5c607206be5decd28e6263ffffdcee067266015e","PackageCount":1}]
[{"ProjectRoot":"github.com/sdboyer/deptest","Constraint":"^0.8.0","Version":"v0.8.0","Revision":"ff2948a2ac8f538c4ecd55962e919d1e13e74baf","Latest":"3f4c3bea144e112a69bbe5d8d01c1b09a544253f","PackageCount":1},{"ProjectRoot":"github.com/sdboyer/deptestdos","Constraint":"*","Version":"v2.0.0","Revision":"5c607206be5decd28e6263ffffdcee067266015e","Latest":"5c607206be5decd28e6263ffffdcee067266015e","PackageCount":1}]