//go:generate go install github.com/go-fed/activity/tools/vocab //go:generate vocab package vocab import ( "encoding/json" "github.com/go-test/deep" "net/url" "testing" ) func GetJSONDiff(str1, str2 []byte) ([]string, error) { var i1 interface{} var i2 interface{} err := json.Unmarshal(str1, &i1) if err != nil { return nil, err } err = json.Unmarshal(str2, &i2) if err != nil { return nil, err } return deep.Equal(i1, i2), nil } func MustParseURL(s string) *url.URL { u, err := url.Parse(s) if err != nil { panic(err) } return u } var ( tables = []struct { name string expectedJSON string expectedStruct Serializer deserializer func() Deserializer }{ { name: "Example 1", expectedJSON: example1, expectedStruct: example1Type, deserializer: func() Deserializer { return &Object{} }, }, { name: "Example 2", expectedJSON: example2, expectedStruct: example2Type, deserializer: func() Deserializer { return &Link{} }, }, { name: "Example 3", expectedJSON: example3, expectedStruct: example3Type, deserializer: func() Deserializer { return &Activity{} }, }, { name: "Example 4", expectedJSON: example4, expectedStruct: example4Type, deserializer: func() Deserializer { return &Travel{} }, }, { name: "Example 5", expectedJSON: example5, expectedStruct: example5Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 6", expectedJSON: example6, expectedStruct: example6Type, deserializer: func() Deserializer { return &OrderedCollection{} }, }, { name: "Example 7", expectedJSON: example7, expectedStruct: example7Type, deserializer: func() Deserializer { return &CollectionPage{} }, }, { name: "Example 8", expectedJSON: example8, expectedStruct: example8Type, deserializer: func() Deserializer { return &OrderedCollectionPage{} }, }, { name: "Example 9", expectedJSON: example9, expectedStruct: example9Type, deserializer: func() Deserializer { return &Accept{} }, }, { name: "Example 10", expectedJSON: example10, expectedStruct: example10Type, deserializer: func() Deserializer { return &Accept{} }, }, { name: "Example 11", expectedJSON: example11, expectedStruct: example11Type, deserializer: func() Deserializer { return &TentativeAccept{} }, }, { name: "Example 12", expectedJSON: example12, expectedStruct: example12Type, deserializer: func() Deserializer { return &Add{} }, }, { name: "Example 13", expectedJSON: example13, expectedStruct: example13Type, deserializer: func() Deserializer { return &Add{} }, }, { name: "Example 14", expectedJSON: example14, expectedStruct: example14Type, deserializer: func() Deserializer { return &Arrive{} }, }, { name: "Example 15", expectedJSON: example15, expectedStruct: example15Type, deserializer: func() Deserializer { return &Create{} }, }, { name: "Example 16", expectedJSON: example16, expectedStruct: example16Type, deserializer: func() Deserializer { return &Delete{} }, }, { name: "Example 17", expectedJSON: example17, expectedStruct: example17Type, deserializer: func() Deserializer { return &Follow{} }, }, { name: "Example 18", expectedJSON: example18, expectedStruct: example18Type, deserializer: func() Deserializer { return &Ignore{} }, }, { name: "Example 19", expectedJSON: example19, expectedStruct: example19Type, deserializer: func() Deserializer { return &Join{} }, }, { name: "Example 20", expectedJSON: example20, expectedStruct: example20Type, deserializer: func() Deserializer { return &Leave{} }, }, { name: "Example 21", expectedJSON: example21, expectedStruct: example21Type, deserializer: func() Deserializer { return &Leave{} }, }, { name: "Example 22", expectedJSON: example22, expectedStruct: example22Type, deserializer: func() Deserializer { return &Like{} }, }, { name: "Example 23", expectedJSON: example23, expectedStruct: example23Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 24", expectedJSON: example24, expectedStruct: example24Type, deserializer: func() Deserializer { return &Invite{} }, }, { name: "Example 25", expectedJSON: example25, expectedStruct: example25Type, deserializer: func() Deserializer { return &Reject{} }, }, { name: "Example 26", expectedJSON: example26, expectedStruct: example26Type, deserializer: func() Deserializer { return &TentativeReject{} }, }, { name: "Example 27", expectedJSON: example27, expectedStruct: example27Type, deserializer: func() Deserializer { return &Remove{} }, }, { name: "Example 28", expectedJSON: example28, expectedStruct: example28Type, deserializer: func() Deserializer { return &Remove{} }, }, { name: "Example 29", expectedJSON: example29, expectedStruct: example29Type, deserializer: func() Deserializer { return &Undo{} }, }, { name: "Example 30", expectedJSON: example30, expectedStruct: example30Type, deserializer: func() Deserializer { return &Update{} }, }, { name: "Example 31", expectedJSON: example31, expectedStruct: example31Type, deserializer: func() Deserializer { return &View{} }, }, { name: "Example 32", expectedJSON: example32, expectedStruct: example32Type, deserializer: func() Deserializer { return &Listen{} }, }, { name: "Example 33", expectedJSON: example33, expectedStruct: example33Type, deserializer: func() Deserializer { return &Read{} }, }, { name: "Example 34", expectedJSON: example34, expectedStruct: example34Type, deserializer: func() Deserializer { return &Move{} }, }, { name: "Example 35", expectedJSON: example35, expectedStruct: example35Type, deserializer: func() Deserializer { return &Travel{} }, }, { name: "Example 36", expectedJSON: example36, expectedStruct: example36Type, deserializer: func() Deserializer { return &Announce{} }, }, { name: "Example 37", expectedJSON: example37, expectedStruct: example37Type, deserializer: func() Deserializer { return &Block{} }, }, { name: "Example 38", expectedJSON: example38, expectedStruct: example38Type, deserializer: func() Deserializer { return &Flag{} }, }, { name: "Example 39", expectedJSON: example39, expectedStruct: example39Type, deserializer: func() Deserializer { return &Dislike{} }, }, { name: "Example 40", expectedJSON: example40, expectedStruct: example40Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 41", expectedJSON: example41, expectedStruct: example41Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 42", expectedJSON: example42, expectedStruct: example42Type, deserializer: func() Deserializer { return &Application{} }, }, { name: "Example 43", expectedJSON: example43, expectedStruct: example43Type, deserializer: func() Deserializer { return &Group{} }, }, { name: "Example 44", expectedJSON: example44, expectedStruct: example44Type, deserializer: func() Deserializer { return &Organization{} }, }, { name: "Example 45", expectedJSON: example45, expectedStruct: example45Type, deserializer: func() Deserializer { return &Person{} }, }, { name: "Example 46", expectedJSON: example46, expectedStruct: example46Type, deserializer: func() Deserializer { return &Service{} }, }, { name: "Example 47", expectedJSON: example47, expectedStruct: example47Type, deserializer: func() Deserializer { return &Relationship{} }, }, { name: "Example 48", expectedJSON: example48, expectedStruct: example48Type, deserializer: func() Deserializer { return &Article{} }, }, { name: "Example 49", expectedJSON: example49, expectedStruct: example49Type, deserializer: func() Deserializer { return &Document{} }, }, { name: "Example 50", expectedJSON: example50, expectedStruct: example50Type, deserializer: func() Deserializer { return &Audio{} }, }, { name: "Example 51", expectedJSON: example51, expectedStruct: example51Type, deserializer: func() Deserializer { return &Image{} }, }, { name: "Example 52", expectedJSON: example52, expectedStruct: example52Type, deserializer: func() Deserializer { return &Video{} }, }, { name: "Example 53", expectedJSON: example53, expectedStruct: example53Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 54", expectedJSON: example54, expectedStruct: example54Type, deserializer: func() Deserializer { return &Page{} }, }, { name: "Example 55", expectedJSON: example55, expectedStruct: example55Type, deserializer: func() Deserializer { return &Event{} }, }, { name: "Example 56", expectedJSON: example56, expectedStruct: example56Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 57", expectedJSON: example57, expectedStruct: example57Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 58", expectedJSON: example58, expectedStruct: example58Type, deserializer: func() Deserializer { return &Mention{} }, }, { name: "Example 59", expectedJSON: example59, expectedStruct: example59Type, deserializer: func() Deserializer { return &Profile{} }, }, { name: "Example 60", expectedJSON: example60, expectedStruct: example60Type, deserializer: func() Deserializer { return &OrderedCollection{} }, }, { name: "Example 61", expectedJSON: example61, expectedStruct: example61Type, deserializer: func() Deserializer { return &Unknown{} }, }, { name: "Example 62", expectedJSON: example62, expectedStruct: example62Type, deserializer: func() Deserializer { return &Unknown{} }, }, { name: "Example 63", expectedJSON: example63, expectedStruct: example63Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 64", expectedJSON: example64, expectedStruct: example64Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 65", expectedJSON: example65, expectedStruct: example65Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 66", expectedJSON: example66, expectedStruct: example66Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 67", expectedJSON: example67, expectedStruct: example67Type, deserializer: func() Deserializer { return &Image{} }, }, { name: "Example 68", expectedJSON: example68, expectedStruct: example68Type, deserializer: func() Deserializer { return &Image{} }, }, { name: "Example 69", expectedJSON: example69, expectedStruct: example69Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 70", expectedJSON: example70, expectedStruct: example70Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 71", expectedJSON: example71, expectedStruct: example71Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 72", expectedJSON: example72, expectedStruct: example72Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 73", expectedJSON: example73, expectedStruct: example73Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 74", expectedJSON: example74, expectedStruct: example74Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 75", expectedJSON: example75, expectedStruct: example75Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 76", expectedJSON: example76, expectedStruct: example76Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 77", expectedJSON: example77, expectedStruct: example77Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 78", expectedJSON: example78, expectedStruct: example78Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 79", expectedJSON: example79, expectedStruct: example79Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 80", expectedJSON: example80, expectedStruct: example80Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 81", expectedJSON: example81, expectedStruct: example81Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 82", expectedJSON: example82, expectedStruct: example82Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 83", expectedJSON: example83, expectedStruct: example83Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 84", expectedJSON: example84, expectedStruct: example84Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 85", expectedJSON: example85, expectedStruct: example85Type, deserializer: func() Deserializer { return &Listen{} }, }, { name: "Example 86", expectedJSON: example86, expectedStruct: example86Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 87", expectedJSON: example87, expectedStruct: example87Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 88", expectedJSON: example88, expectedStruct: example88Type, deserializer: func() Deserializer { return &Person{} }, }, { name: "Example 89", expectedJSON: example89, expectedStruct: example89Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 90", expectedJSON: example90, expectedStruct: example90Type, deserializer: func() Deserializer { return &OrderedCollection{} }, }, { name: "Example 91", expectedJSON: example91, expectedStruct: example91Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 92", expectedJSON: example92, expectedStruct: example92Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 93", expectedJSON: example93, expectedStruct: example93Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 94", expectedJSON: example94, expectedStruct: example94Type, deserializer: func() Deserializer { return &Move{} }, }, { name: "Example 95", expectedJSON: example95, expectedStruct: example95Type, deserializer: func() Deserializer { return &CollectionPage{} }, }, { name: "Example 96", expectedJSON: example96, expectedStruct: example96Type, deserializer: func() Deserializer { return &CollectionPage{} }, }, { name: "Example 97", expectedJSON: example97, expectedStruct: example97Type, deserializer: func() Deserializer { return &Like{} }, }, { name: "Example 98", expectedJSON: example98, expectedStruct: example98Type, deserializer: func() Deserializer { return &Like{} }, }, { name: "Example 99", expectedJSON: example99, expectedStruct: example99Type, deserializer: func() Deserializer { return &Like{} }, }, { name: "Example 100", expectedJSON: example100, expectedStruct: example100Type, deserializer: func() Deserializer { return &CollectionPage{} }, }, { name: "Example 101", expectedJSON: example101, expectedStruct: example101Type, deserializer: func() Deserializer { return &CollectionPage{} }, }, { name: "Example 102", expectedJSON: example102, expectedStruct: example102Type, deserializer: func() Deserializer { return &Video{} }, }, { name: "Example 103", expectedJSON: example103, expectedStruct: example103Type, deserializer: func() Deserializer { return &Activity{} }, }, { name: "Example 104", expectedJSON: example104, expectedStruct: example104Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 105", expectedJSON: example105, expectedStruct: example105Type, deserializer: func() Deserializer { return &Image{} }, }, { name: "Example 106", expectedJSON: example106, expectedStruct: example106Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 107", expectedJSON: example107, expectedStruct: example107Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 108", expectedJSON: example108, expectedStruct: example108Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 109", expectedJSON: example109, expectedStruct: example109Type, deserializer: func() Deserializer { return &Document{} }, }, { name: "Example 110", expectedJSON: example110, expectedStruct: example110Type, deserializer: func() Deserializer { return &Document{} }, }, { name: "Example 111", expectedJSON: example111, expectedStruct: example111Type, deserializer: func() Deserializer { return &Document{} }, }, { name: "Example 112", expectedJSON: example112, expectedStruct: example112Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 113", expectedJSON: example113, expectedStruct: example113Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 114", expectedJSON: example114, expectedStruct: example114Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 115", expectedJSON: example115, expectedStruct: example115Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 116", expectedJSON: example116, expectedStruct: example116Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 117", expectedJSON: example117, expectedStruct: example117Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 118", expectedJSON: example118, expectedStruct: example118Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 119", expectedJSON: example119, expectedStruct: example119Type, deserializer: func() Deserializer { return &Video{} }, }, { name: "Example 120", expectedJSON: example120, expectedStruct: example120Type, deserializer: func() Deserializer { return &Link{} }, }, { name: "Example 121", expectedJSON: example121, expectedStruct: example121Type, deserializer: func() Deserializer { return &Link{} }, }, { name: "Example 122", expectedJSON: example122, expectedStruct: example122Type, deserializer: func() Deserializer { return &Link{} }, }, { name: "Example 123", expectedJSON: example123, expectedStruct: example123Type, deserializer: func() Deserializer { return &CollectionPage{} }, }, { name: "Example 124", expectedJSON: example124, expectedStruct: example124Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 125", expectedJSON: example125, expectedStruct: example125Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 126", expectedJSON: example126, expectedStruct: example126Type, deserializer: func() Deserializer { return &Link{} }, }, { name: "Example 127", expectedJSON: example127, expectedStruct: example127Type, deserializer: func() Deserializer { return &Event{} }, }, { name: "Example 128", expectedJSON: example128, expectedStruct: example128Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 129", expectedJSON: example129, expectedStruct: example129Type, deserializer: func() Deserializer { return &Event{} }, }, { name: "Example 130", expectedJSON: example130, expectedStruct: example130Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 131", expectedJSON: example131, expectedStruct: example131Type, deserializer: func() Deserializer { return &Link{} }, }, { name: "Example 132", expectedJSON: example132, expectedStruct: example132Type, deserializer: func() Deserializer { return &OrderedCollectionPage{} }, }, { name: "Example 133", expectedJSON: example133, expectedStruct: example133Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 134", expectedJSON: example134, expectedStruct: example134Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 135", expectedJSON: example135, expectedStruct: example135Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 136", expectedJSON: example136, expectedStruct: example136Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 137", expectedJSON: example137, expectedStruct: example137Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 138", expectedJSON: example138, expectedStruct: example138Type, deserializer: func() Deserializer { return &Link{} }, }, { name: "Example 139", expectedJSON: example139, expectedStruct: example139Type, deserializer: func() Deserializer { return &Relationship{} }, }, { name: "Example 140", expectedJSON: example140, expectedStruct: example140Type, deserializer: func() Deserializer { return &Relationship{} }, }, { name: "Example 141", expectedJSON: example141, expectedStruct: example141Type, deserializer: func() Deserializer { return &Profile{} }, }, { name: "Example 142", expectedJSON: example142, expectedStruct: example142Type, deserializer: func() Deserializer { return &Tombstone{} }, }, { name: "Example 143", expectedJSON: example143, expectedStruct: example143Type, deserializer: func() Deserializer { return &Tombstone{} }, }, { name: "Example 144", expectedJSON: example144, expectedStruct: example144Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 145", expectedJSON: example145, expectedStruct: example145Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 146", expectedJSON: example146, expectedStruct: example146Type, deserializer: func() Deserializer { return &Create{} }, }, { name: "Example 147", expectedJSON: example147, expectedStruct: example147Type, deserializer: func() Deserializer { return &Offer{} }, }, { name: "Example 148", expectedJSON: example148, expectedStruct: example148Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 149", expectedJSON: example149, expectedStruct: example149Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 150", expectedJSON: example150, expectedStruct: example150Type, deserializer: func() Deserializer { return &Place{} }, }, { name: "Example 151", expectedJSON: example151, expectedStruct: example151Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 152", expectedJSON: example152, expectedStruct: example152Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 153", expectedJSON: example153, expectedStruct: example153Type, deserializer: func() Deserializer { return &Unknown{} }, }, { name: "Example 154", expectedJSON: example154, expectedStruct: example154Type, deserializer: func() Deserializer { return &Question{} }, }, { name: "Example 155", expectedJSON: example155, expectedStruct: example155Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 156", expectedJSON: example156, expectedStruct: example156Type, deserializer: func() Deserializer { return &Collection{} }, }, { name: "Example 157", expectedJSON: example157, expectedStruct: example157Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 158", expectedJSON: example158, expectedStruct: example158Type, deserializer: func() Deserializer { return &Note{} }, }, { name: "Example 159", expectedJSON: example159, expectedStruct: example159Type, deserializer: func() Deserializer { return &Move{} }, }, } ) func TestDeserialization(t *testing.T) { for _, r := range tables { // Test Deserialize m := make(map[string]interface{}) err := json.Unmarshal([]byte(r.expectedJSON), &m) if err != nil { t.Errorf("%s: Cannot json.Unmarshal: %s", r.name, err) continue } actual := r.deserializer() err = actual.Deserialize(m) if err != nil { t.Errorf("%s: Cannot Deserialize: %s", r.name, err) continue } if diff := deep.Equal(actual, r.expectedStruct); diff != nil { t.Errorf("%s: Deserialize deep equal is false: %s", r.name, diff) } } } func TestSerialization(t *testing.T) { for _, r := range tables { m, err := r.expectedStruct.Serialize() if err != nil { t.Errorf("%s: Cannot Serialize: %s", r.name, err) continue } m["@context"] = "https://www.w3.org/ns/activitystreams" b, err := json.Marshal(m) if err != nil { t.Errorf("%s: Cannot json.Marshal: %s", r.name, err) continue } if diff, err := GetJSONDiff(b, []byte(r.expectedJSON)); err == nil && diff != nil { t.Errorf("%s: Serialize JSON equality is false:\n%s", r.name, diff) } else if err != nil { t.Errorf("%s: GetJSONDiff returned error: %s", r.name, err) } } } func TestSerializationWithoutTypeSet(t *testing.T) { obj := &Object{} obj.SetId(MustParseURL("http://www.test.example/object/1")) obj.AppendNameString("A Simple, non-specific object") person := &Person{} person.AppendNameString("Sally") place := &Place{} place.AppendNameString("Work") obj4 := &Travel{} obj4.AppendSummaryString("Sally went to work") obj4.AppendActorObject(person) obj4.AppendTargetObject(place) tables := []struct { name string expectedJSON string input Serializer }{ { name: "Example 1", expectedJSON: example1, input: obj, }, { name: "Example 4", expectedJSON: example4, input: obj4, }, } for _, r := range tables { m, err := r.input.Serialize() if err != nil { t.Errorf("%s: Cannot Serialize: %s", r.name, err) continue } m["@context"] = "https://www.w3.org/ns/activitystreams" b, err := json.Marshal(m) if err != nil { t.Errorf("%s: Cannot json.Marshal: %s", r.name, err) continue } if diff, err := GetJSONDiff(b, []byte(r.expectedJSON)); err == nil && diff != nil { t.Errorf("%s: Serialize JSON equality is false:\n%s", r.name, diff) } else if err != nil { t.Errorf("%s: GetJSON Diff returned error: %s", r.name, err) } } } func TestReserializationAbility(t *testing.T) { const ( samIRIInboxString = "https://example.com/sam/inbox" samIRIString = "https://example.com/sam" noteURIString = "https://example.com/note/123" sallyIRIString = "https://example.com/sally" activityIRIString = "https://example.com/test/new/iri" ) samIRIInbox, err := url.Parse(samIRIInboxString) if err != nil { t.Fatal(err) } samIRI, err := url.Parse(samIRIString) if err != nil { t.Fatal(err) } noteIRI, err := url.Parse(noteURIString) if err != nil { t.Fatal(err) } sallyIRI, err := url.Parse(sallyIRIString) if err != nil { t.Fatal(err) } activityIRI, err := url.Parse(activityIRIString) if err != nil { t.Fatal(err) } expectedSamActor := &Person{} expectedSamActor.SetInboxAnyURI(samIRIInbox) expectedSamActor.SetId(samIRI) expectedNote := &Note{} expectedNote.SetId(noteIRI) expectedNote.AppendNameString("A Note") expectedNote.AppendContentString("This is a simple note") expectedNote.AppendToObject(expectedSamActor) expectedUpdate := &Update{} expectedUpdate.AppendActorIRI(sallyIRI) expectedUpdate.AppendSummaryString("Sally updated her note") expectedUpdate.SetId(activityIRI) expectedUpdate.AppendObject(expectedNote) tables := []struct { name string expected Serializer deserializer func() Deserializer input string }{ { name: "JSON with null", expected: expectedUpdate, deserializer: func() Deserializer { return &Update{} }, input: ` { "@context": "https://www.w3.org/ns/activitystreams", "summary": "Sally updated her note", "type": "Update", "actor": "https://example.com/sally", "id": "https://example.com/test/new/iri", "object": { "id": "https://example.com/note/123", "type": "Note", "to": { "id": "https://example.com/sam", "inbox": "https://example.com/sam/inbox", "type": "Person", "name": null } } } `, }, } for _, r := range tables { m := make(map[string]interface{}) err := json.Unmarshal([]byte(r.input), &m) if err != nil { t.Errorf("%s: Cannot json.Unmarshal: %s", r.name, err) continue } actual := r.deserializer() err = actual.Deserialize(m) if err != nil { t.Errorf("%s: Cannot Deserialize: %s", r.name, err) continue } if diff := deep.Equal(actual, r.expected); diff != nil { t.Errorf("%s: Deserialize deep equal is false: %s", r.name, diff) } // Only test ability to reserialize serializer, ok := actual.(Serializer) if !ok { t.Errorf("Deserializer is not also Serializer") } m, err = serializer.Serialize() if err != nil { t.Errorf("%s: Cannot Serialize: %s", r.name, err) continue } m["@context"] = "https://www.w3.org/ns/activitystreams" _, err = json.Marshal(m) if err != nil { t.Errorf("%s: Cannot json.Marshal: %s", r.name, err) continue } } } func TestBooleanOperationsOnEmptyTypes(t *testing.T) { o := &Object{} // Functional multi-type property if o.IsAltitude() { t.Errorf("IsAltitude returned true; expected false") } if o.IsAltitudeIRI() { t.Errorf("IsAltitudeIRI returned true; expected false") } if o.HasUnknownAltitude() { t.Errorf("HasUnknownAltitude returned true; expected false") } // Non-functional multi-type property if o.AttachmentLen() > 0 { t.Errorf("AttachentLen returned >0; expected ==0") } if o.HasUnknownAttachment() { t.Errorf("HasUnknownAttachment returned true; expected false") } // Functional any property // None exist // Non-functional any property if o.TypeLen() > 0 { t.Errorf("TypeLen returned >0; expected ==0") } l := &Link{} // Functional single-type property if l.HasHref() { t.Errorf("HasHref returned true; expected false") } if l.HasUnknownHref() { t.Errorf("HasUnknownHref returned true; expected false") } }