Skip to content

Commit

Permalink
more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-richards committed Aug 22, 2024
1 parent 6f18002 commit a253445
Show file tree
Hide file tree
Showing 29 changed files with 748 additions and 341 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.out
.idea/
94 changes: 38 additions & 56 deletions cbor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,37 @@ import (
"github.com/fxamacker/cbor/v2"
)

const tagEncodedCBOR = 24
const (
cborMajorTypeFloatNoContent = 7 << 5
)

type bstr []byte
type TaggedEncodedCBOR struct {
taggedValue bstr
untaggedValue bstr
}
const (
cborNull = cborMajorTypeFloatNoContent | 22
)

const (
cborTagEncodedCBOR = 24
)

var (
encodeModeTaggedEncodedCBOR cbor.EncMode
decodeModeTaggedEncodedCBOR cbor.DecMode
ErrEmptyTaggedValue = errors.New("empty tagged value")
)

var (
ErrorEmptyTaggedValue = errors.New("empty tagged value")
ErrorEmptyUntaggedValue = errors.New("empty untagged value")
encodeModeTaggedEncodedCBOR cbor.EncMode
decodeModeTaggedEncodedCBOR cbor.DecMode
)

func init() {
ts := cbor.NewTagSet()
ts.Add(
err := ts.Add(
cbor.TagOptions{DecTag: cbor.DecTagRequired, EncTag: cbor.EncTagRequired},
reflect.TypeOf(bstr(nil)),
tagEncodedCBOR,
cborTagEncodedCBOR,
)

var err error
if err != nil {
panic(err)
}

encodeModeTaggedEncodedCBOR, err = cbor.EncOptions{}.EncModeWithTags(ts)
if err != nil {
Expand All @@ -46,61 +50,39 @@ func init() {
}
}

func (tec *TaggedEncodedCBOR) TaggedValue() ([]byte, error) {
if tec.taggedValue != nil {
return tec.taggedValue, nil
}

if tec.untaggedValue != nil {
return encodeModeTaggedEncodedCBOR.Marshal(tec.untaggedValue)
}
type bstr []byte

return nil, ErrorEmptyTaggedValue
type TaggedEncodedCBOR struct {
TaggedValue bstr
UntaggedValue bstr
}

func (tec *TaggedEncodedCBOR) UntaggedValue() ([]byte, error) {
if tec.untaggedValue != nil {
return tec.untaggedValue, nil
}

if tec.taggedValue != nil {
var untaggedValue []byte
if err := decodeModeTaggedEncodedCBOR.Unmarshal(tec.taggedValue, untaggedValue); err != nil {
return nil, err
}

return untaggedValue, nil
func NewTaggedEncodedCBOR(untaggedValue []byte) (*TaggedEncodedCBOR, error) {
taggedValue, err := encodeModeTaggedEncodedCBOR.Marshal((bstr)(untaggedValue))
if err != nil {
return nil, err
}

return nil, ErrorEmptyUntaggedValue
return &TaggedEncodedCBOR{
TaggedValue: taggedValue,
UntaggedValue: untaggedValue,
}, nil
}

func (tec *TaggedEncodedCBOR) MarshalCBOR() ([]byte, error) {
return tec.TaggedValue()
if tec.TaggedValue == nil {
return nil, ErrEmptyTaggedValue
}
return tec.TaggedValue, nil
}

func (tec *TaggedEncodedCBOR) UnmarshalCBOR(taggedValue []byte) error {
var untaggedValue []byte
err := decodeModeTaggedEncodedCBOR.Unmarshal(taggedValue, &untaggedValue)
if err != nil {
var untaggedValue bstr
if err := decodeModeTaggedEncodedCBOR.Unmarshal(taggedValue, &untaggedValue); err != nil {
return err
}

tec.taggedValue = taggedValue
tec.untaggedValue = untaggedValue
tec.TaggedValue = taggedValue
tec.UntaggedValue = untaggedValue
return nil
}

func NewTaggedEncodedCBOR(untaggedValue []byte) (*TaggedEncodedCBOR, error) {
taggedEncodedCBOR := TaggedEncodedCBOR{
untaggedValue: untaggedValue,
}

var err error
taggedEncodedCBOR.taggedValue, err = taggedEncodedCBOR.TaggedValue()
if err != nil {
return nil, err
}

return &taggedEncodedCBOR, nil
}
218 changes: 188 additions & 30 deletions cbor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,209 @@ package mdoc
import (
"bytes"
"encoding/hex"
"testing"

"errors"
"github.com/fxamacker/cbor/v2"
"github.com/google/go-cmp/cmp"
"testing"
)

type TestStruct struct {
One int
Two string
}
const (
cborMajorTypeBstr = 2 << 5
cborMajorTypeMap = 5 << 5
cborMajorTypeTaggedValue = 6 << 5
)

func TestEncodedCBORTagged(t *testing.T) {
testStruct := TestStruct{
One: 1,
Two: "2",
}
const (
cborArgumentLength1 = 24
//cborArgumentLength2 = 25
//cborArgumentLength3 = 26
//cborArgumentLength4 = 27
)

testStructBytes, err := cbor.Marshal(testStruct)
if err != nil {
t.Fatal(err)
}
const (
cborEmptyMap = cborMajorTypeMap | 0
)

if errUntagged := cbor.Unmarshal(testStructBytes, &TaggedEncodedCBOR{}); errUntagged == nil {
t.Fatal("expected error")
func TestNewTaggedEncodedCBOR(t *testing.T) {
tests := []struct {
name string
untaggedValue []byte
want *TaggedEncodedCBOR
}{
{
name: "value",
untaggedValue: []byte{1, 2, 3, 4},
want: &TaggedEncodedCBOR{
TaggedValue: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 4, 1, 2, 3, 4,
},
UntaggedValue: []byte{1, 2, 3, 4},
},
},
{
name: "nil",
untaggedValue: nil,
want: &TaggedEncodedCBOR{
TaggedValue: []byte{
cborNull,
},
UntaggedValue: nil,
},
},
{
name: "empty",
untaggedValue: []byte{},
want: &TaggedEncodedCBOR{
TaggedValue: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 0,
},
UntaggedValue: []byte{},
},
},
}

taggedEncodedCBOR, err := NewTaggedEncodedCBOR(testStructBytes)
if err != nil {
t.Fatal(err)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewTaggedEncodedCBOR(tt.untaggedValue)
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Fatal(diff)
}
})
}
}

testStructBytesTagged, err := cbor.Marshal(taggedEncodedCBOR)
if err != nil {
t.Fatal(err)
func TestTaggedEncodedCBOR_MarshalCBOR(t *testing.T) {
tests := []struct {
name string
taggedEncodedCBOR TaggedEncodedCBOR
want []byte
wantErr error
}{
{
name: "marshal complete",
taggedEncodedCBOR: TaggedEncodedCBOR{
TaggedValue: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 1, cborEmptyMap,
},
UntaggedValue: []byte{
cborEmptyMap,
},
},
want: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 1, cborEmptyMap,
},
},
{
name: "marshal tagged only",
taggedEncodedCBOR: TaggedEncodedCBOR{
TaggedValue: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 1, cborEmptyMap,
},
},
want: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 1, cborEmptyMap,
},
},
{
name: "marshal untagged only",
taggedEncodedCBOR: TaggedEncodedCBOR{
UntaggedValue: []byte{
cborEmptyMap,
},
},
wantErr: ErrEmptyTaggedValue,
},
{
name: "marshal empty",
taggedEncodedCBOR: TaggedEncodedCBOR{},
wantErr: ErrEmptyTaggedValue,
},
{
name: "marshal nil",
wantErr: ErrEmptyTaggedValue,
},
}
if !bytes.Equal(testStructBytesTagged[0:2], []byte{0xd8, tagEncodedCBOR}) {
t.Fatal(hex.EncodeToString(testStructBytesTagged))

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := cbor.Marshal(tt.taggedEncodedCBOR)
if err != nil && !errors.Is(err, tt.wantErr) {
t.Fatalf("err = %v, wantErr %v", err, tt.wantErr)
}
if err == nil && (tt.wantErr != nil) {
t.Fatalf("err = %v, wantErr %v", err, tt.wantErr)
}
if !bytes.Equal(tt.want, got) {
t.Errorf("got = %v, want %v", hex.EncodeToString(got), hex.EncodeToString(tt.want))
}
})
}
}

var taggedEncodedCBORUnmarshalled TaggedEncodedCBOR
if err = cbor.Unmarshal(testStructBytesTagged, &taggedEncodedCBORUnmarshalled); err != nil {
t.Fatal(err)
func TestTaggedEncodedCBOR_UnmarshalCBOR(t *testing.T) {
tests := []struct {
name string
data []byte
want TaggedEncodedCBOR
wantErr string
}{
{
name: "unmarshal tagged",
data: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 1, cborEmptyMap,
},
want: TaggedEncodedCBOR{
TaggedValue: []byte{
cborMajorTypeTaggedValue | cborArgumentLength1, cborTagEncodedCBOR,
cborMajorTypeBstr | 1, cborEmptyMap,
},
UntaggedValue: []byte{
cborEmptyMap,
},
},
},
{
name: "unmarshal untagged",
data: []byte{
cborEmptyMap,
},
wantErr: "cbor: cannot unmarshal map into Go value of type mdoc.bstr (expect CBOR tag value)",
},
{
name: "unmarshal empty",
data: []byte{},
wantErr: "EOF",
},
{
name: "unmarshal nil",
data: nil,
wantErr: "EOF",
},
}

if diff := cmp.Diff(testStructBytes, []byte(taggedEncodedCBORUnmarshalled.untaggedValue)); diff != "" {
t.Fatal(diff)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var got TaggedEncodedCBOR
err := cbor.Unmarshal(tt.data, &got)
if err != nil && (err.Error() != tt.wantErr) {
t.Fatalf("err = %v, wantErr %v", err, tt.wantErr)
}
if err == nil && (tt.wantErr != "") {
t.Fatalf("err = %v, wantErr %v", err, tt.wantErr)
}
if diff := cmp.Diff(&tt.want, &got, cmp.AllowUnexported(TaggedEncodedCBOR{})); diff != "" {
t.Fatal(diff)
}
})
}
}
Loading

0 comments on commit a253445

Please sign in to comment.