-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
276 additions
and
72 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package context | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
) | ||
|
||
type sort uint | ||
|
||
const ( | ||
field sort = iota | ||
index | ||
key | ||
) | ||
|
||
type segment struct { | ||
sort sort | ||
name string | ||
index int | ||
typ reflect.Type | ||
} | ||
|
||
func (s segment) String() string { | ||
switch s.sort { | ||
case field: | ||
return fmt.Sprintf(`field "%s" (type "%s")`, s.name, s.typ) | ||
case index: | ||
return fmt.Sprintf(`index %d (type "%s")`, s.index, s.typ) | ||
default: | ||
return fmt.Sprintf(`key "%s" (type "%s")`, s.name, s.typ) | ||
} | ||
} | ||
|
||
type Context []segment | ||
|
||
func (ctx Context) String() string { | ||
switch len(ctx) { | ||
case 0: | ||
return "at the root" | ||
case 1: | ||
return fmt.Sprintf("at %s", ctx.leaf()) | ||
default: | ||
return fmt.Sprintf("at %s path %s", ctx.leaf(), ctx.path()) | ||
} | ||
} | ||
|
||
func (ctx Context) leaf() segment { | ||
return ctx[len(ctx)-1] | ||
} | ||
|
||
func (ctx Context) path() string { | ||
var path string | ||
for _, s := range ctx { | ||
switch s.sort { | ||
case index: | ||
path = fmt.Sprintf("%s[%d]", path, s.index) | ||
case field: | ||
if len(path) > 0 { | ||
path = path + "." | ||
} | ||
path = path + s.name | ||
case key: | ||
path = fmt.Sprintf(`%s["%s"]`, path, s.name) | ||
} | ||
} | ||
|
||
return path | ||
} | ||
|
||
func (ctx Context) WithField(f reflect.StructField) Context { | ||
return append(ctx, segment{sort: field, name: f.Name, typ: f.Type}) | ||
} | ||
|
||
func (ctx Context) WithIndex(i int, t reflect.Type) Context { | ||
return append(ctx, segment{sort: index, index: i, typ: t}) | ||
} | ||
|
||
func (ctx Context) WithKey(k string, t reflect.Type) Context { | ||
return append(ctx, segment{sort: key, name: k, typ: t}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package context_test | ||
|
||
import ( | ||
"testing" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
func TestContext(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Context Suite") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package context_test | ||
|
||
import ( | ||
"reflect" | ||
|
||
"code.cloudfoundry.org/jsonry/internal/context" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("Context", func() { | ||
When("it is the zero value", func() { | ||
It("reports being at the root", func() { | ||
ctx := context.Context{} | ||
Expect(ctx.String()).To(Equal("at the root")) | ||
}) | ||
}) | ||
|
||
When("it has a field", func() { | ||
It("reports the field detail", func() { | ||
ctx := context.Context{}.WithField(reflect.StructField{Name: "Foo", Type: reflect.TypeOf("")}) | ||
Expect(ctx.String()).To(Equal(`at field "Foo" (type "string")`)) | ||
}) | ||
}) | ||
|
||
When("it has an index", func() { | ||
It("reports the index detail", func() { | ||
ctx := context.Context{}.WithIndex(4, reflect.TypeOf(true)) | ||
Expect(ctx.String()).To(Equal(`at index 4 (type "bool")`)) | ||
|
||
}) | ||
}) | ||
|
||
When("it has an key", func() { | ||
It("reports the key detail", func() { | ||
ctx := context.Context{}.WithKey("foo", reflect.TypeOf(true)) | ||
Expect(ctx.String()).To(Equal(`at key "foo" (type "bool")`)) | ||
|
||
}) | ||
}) | ||
|
||
When("it has multiple fields", func() { | ||
It("reports the path details", func() { | ||
ctx := context.Context{}. | ||
WithField(reflect.StructField{Name: "Foo", Type: reflect.TypeOf("")}). | ||
WithField(reflect.StructField{Name: "Bar", Type: reflect.TypeOf(true)}). | ||
WithField(reflect.StructField{Name: "Baz", Type: reflect.TypeOf(42)}) | ||
|
||
Expect(ctx.String()).To(Equal(`at field "Baz" (type "int") path Foo.Bar.Baz`)) | ||
}) | ||
}) | ||
|
||
When("it has multiple indices", func() { | ||
It("reports the path details", func() { | ||
ctx := context.Context{}. | ||
WithIndex(3, reflect.TypeOf("")). | ||
WithIndex(5, reflect.TypeOf(true)). | ||
WithIndex(4, reflect.TypeOf(42)) | ||
Expect(ctx.String()).To(Equal(`at index 4 (type "int") path [3][5][4]`)) | ||
}) | ||
}) | ||
|
||
When("it has multiple key", func() { | ||
It("reports the path details", func() { | ||
ctx := context.Context{}. | ||
WithKey("foo", reflect.TypeOf(true)). | ||
WithKey("bar", reflect.TypeOf(42)). | ||
WithKey("baz", reflect.TypeOf("")) | ||
Expect(ctx.String()).To(Equal(`at key "baz" (type "string") path ["foo"]["bar"]["baz"]`)) | ||
|
||
}) | ||
}) | ||
|
||
When("it there is a mixture of fields, indices, and keys", func() { | ||
It("reports the details", func() { | ||
ctx := context.Context{}. | ||
WithIndex(3, reflect.TypeOf("")). | ||
WithField(reflect.StructField{Name: "Foo", Type: reflect.TypeOf("")}). | ||
WithKey("foo", reflect.TypeOf(true)). | ||
WithIndex(5, reflect.TypeOf(true)). | ||
WithField(reflect.StructField{Name: "Bar", Type: reflect.TypeOf(true)}). | ||
WithField(reflect.StructField{Name: "Baz", Type: reflect.TypeOf(42)}). | ||
WithKey("bar", reflect.TypeOf(42)). | ||
WithIndex(4, reflect.TypeOf(42)) | ||
Expect(ctx.String()).To(Equal(`at index 4 (type "int") path [3].Foo["foo"][5].Bar.Baz["bar"][4]`)) | ||
|
||
ctx = context.Context{}. | ||
WithField(reflect.StructField{Name: "Foo", Type: reflect.TypeOf("")}). | ||
WithIndex(5, reflect.TypeOf(true)). | ||
WithIndex(3, reflect.TypeOf("")). | ||
WithKey("foo", reflect.TypeOf(true)). | ||
WithField(reflect.StructField{Name: "Bar", Type: reflect.TypeOf(true)}). | ||
WithKey("bar", reflect.TypeOf(42)). | ||
WithIndex(4, reflect.TypeOf(42)). | ||
WithField(reflect.StructField{Name: "Baz", Type: reflect.TypeOf(42)}) | ||
Expect(ctx.String()).To(Equal(`at field "Baz" (type "int") path Foo[5][3]["foo"].Bar["bar"][4].Baz`)) | ||
}) | ||
}) | ||
|
||
}) |
Oops, something went wrong.