Skip to content

totherme/nosj

Repository files navigation

NOSJ - Tiny Simple JSON Reflection in Go

This is to make testing JSON output of whatever-you're-doing a tiny bit easier.

GoDoc

Quick start

For full details of the below examples, see this file.

First: import nosj, ginkgo and gomega:

import (
	"github.com/totherme/nosj"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

Next, get yourself some nosj.JSON:

rawjson := `{...}`

myjson, err = nosj.ParseJSON(rawjson)
Expect(err).NotTo(HaveOccurred())

Test!

It("contains three employees", func() {
	employees, err := myjson.GetByPointer("/employees")
	Expect(err).NotTo(HaveOccurred())
	Expect(employees).To(BeAList())
	Expect(employees.ListValue()).To(HaveLen(3))
})

Describe("the first employee", func() {
	It("is great at cooking", func() {
		skill, err := myjson.GetByPointer("/employees/0/profile/special-skill")
		Expect(err).NotTo(HaveOccurred())
		Expect(skill).To(BeAString())
		Expect(skill.StringValue()).To(Equal("szechuan cookery"))
	})
})

In addition to nosj's JSON-wrangling, these tests make use of the ginkgo BDD DSL, which provides constructs like Describe and It; and the gomega matcher library, which gives us Expect.

Getting nosj.JSON Values

There are two approaches you can take to pulling values out of a nosj.JSON object. Firstly, if you like JSON pointers, you can use them:

morejson, err := myjson.GetByPointer("/path/to/property")

The other approach is to get by one key at a time. For this, you can use GetField or its alias F:

morejson := myjson.GetField("path").GetField("to").GetField("property")
// or equivalently:
morejson := myjson.F("path").F("to").F("property")

Note that all these methods will return another nosj.JSON object to the variable morejson. To do anything interesting, you'll probably want to get a golang value out of the nosj.JSON object, as documented in 'Getting Golang Values' below. Finally, notice that while GetByPointer's return type includes an error (e.g. when the pointer does not exist in myjson), the return type of GetField does not. This allows GetField to be chained (and thus makes up for single-field names being significantly less expressive than JSON pointers), but does mean that GetField will panic in those occasions where GetByPointer would return a helpful error message.

Testing nosj.JSON Values

nosj.JSON values may represent data of a variety of golang types. To discover these types, you can use methods such as:

isJSONBool := myjson.IsBool()
isJSONNum := myjson.IsNum()
isJSONString := myjson.IsString()
isJSONOb := myjson.IsOb()
isJSONList := myjson.IsList()
isJSONNull := myjson.IsNull()

If your nosj.JSON object represents a JSON object (as opposed to, for example, a JSON String), you may also want to check if that object has a field of a particular name:

hasField := myjson.HasKey("particular-name")

Getting Golang Values

If you are sure what JSON type is represented by your nosj.JSON object, you can get a value of the appropriate golang type like so:

myGolangBool := myjson.BoolValue()
myGolangNum := myjson.NumValue()
myGolangString := myjson.StringValue()
myGolangOb := myjson.ObValue()
myGolangList := myjson.ListValue()

Matchers

If you're using ginkgo and gomega, you might prefer to use a matcher rather than test your JSON directly:

import (
	"github.com/totherme/nosj"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/totherme/nosj/gnosj"
)

var _ = Describe("Gnosj matchers", func() {
  It("does the same thing as our test methods", func() {
    // Type matchers
    Expect(myjson.IsBool()).To(BeTrue())
    Expect(myjson).To(BeABool())

    Expect(myjson.IsNum()).To(BeTrue())
    Expect(myjson).To(BeANum())

    Expect(myjson.IsString()).To(BeTrue())
    Expect(myjson).To(BeAString())

    Expect(myjson.IsOb()).To(BeTrue())
    Expect(myjson).To(BeAnObject())

    Expect(myjson.IsList()).To(BeTrue())
    Expect(myjson).To(BeAList())

    Expect(myjson.IsNull()).To(BeTrue())
    Expect(myjson).To(BeANull())

    // Access matchers
    Expect(myjson.HasKey("my-key")).To(BeTrue())
    Expect(myjson).To(HaveJSONKey("my-key"))

    Expect(myjson.HasPointer("/my/pointer")).To(BeTrue())
    Expect(myjson).To(HaveJSONPointer("/my/pointer"))
  })
})

Each pair of expectations in the above block is composed of two equivalent statements.

About

A tiny simple json-testing helper

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages