Changes
4 changed files (+741/-722)
-
-
@@ -0,0 +1,264 @@package activitypub import ( "bytes" "fmt" "github.com/buger/jsonparser" json "github.com/go-ap/jsonld" "strconv" "strings" ) type ( // LangRef is the type for a language reference code, should be an ISO639-1 language specifier. LangRef string // LangRefValue is a type for storing per language values LangRefValue struct { Ref LangRef Value string } // NaturalLanguageValues is a mapping for multiple language values NaturalLanguageValues []LangRefValue ) func NaturalLanguageValuesNew() NaturalLanguageValues { return make(NaturalLanguageValues, 0) } func (n NaturalLanguageValues) String() string { cnt := len(n) if cnt == 1 { return n[0].String() } s := strings.Builder{} s.Write([]byte{'['}) for k, v := range n { s.WriteString(v.String()) if k != cnt-1 { s.Write([]byte{','}) } } s.Write([]byte{']'}) return s.String() } func (n NaturalLanguageValues) Get(ref LangRef) string { for _, val := range n { if val.Ref == ref { return val.Value } } return "" } // Set sets a language, value pair in a NaturalLanguageValues array func (n *NaturalLanguageValues) Set(ref LangRef, v string) error { found := false for k, vv := range *n { if vv.Ref == ref { (*n)[k] = LangRefValue{ref, v} found = true } } if !found { n.Append(ref, v) } return nil } // MarshalJSON serializes the NaturalLanguageValues into JSON func (n NaturalLanguageValues) MarshalJSON() ([]byte, error) { if len(n) == 0 { return json.Marshal(nil) } if len(n) == 1 { v := n[0] if v.Ref == NilLangRef { return v.MarshalJSON() } } mm := make(map[LangRef]string) for _, val := range n { mm[val.Ref] = val.Value } return json.Marshal(mm) } // First returns the first element in the array func (n NaturalLanguageValues) First() LangRefValue { for _, v := range n { return v } return LangRefValue{} } // MarshalText serializes the NaturalLanguageValues into Text func (n NaturalLanguageValues) MarshalText() ([]byte, error) { for _, v := range n { return []byte(fmt.Sprintf("%q", v)), nil } return nil, nil } // Append is syntactic sugar for resizing the NaturalLanguageValues map // and appending an element func (n *NaturalLanguageValues) Append(lang LangRef, value string) error { var t NaturalLanguageValues if len(*n) == 0 { t = make(NaturalLanguageValues, 0) } else { t = *n } t = append(*n, LangRefValue{lang, value}) *n = t return nil } // Count returns the length of Items in the item collection func (n *NaturalLanguageValues) Count() uint { return uint(len(*n)) } // String adds support for Stringer interface. It returns the Value[LangRef] text or just Value if LangRef is NIL func (l LangRefValue) String() string { if l.Ref == NilLangRef { return l.Value } return fmt.Sprintf("%s[%s]", l.Value, l.Ref) } // UnmarshalJSON implements the JsonEncoder interface func (l *LangRefValue) UnmarshalJSON(data []byte) error { _, typ, _, err := jsonparser.Get(data) if err != nil { l.Ref = NilLangRef l.Value = string(unescape(data)) return nil } switch typ { case jsonparser.Object: jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error { l.Ref = LangRef(key) l.Value = string(unescape(value)) return err }) case jsonparser.String: l.Ref = NilLangRef l.Value = string(unescape(data)) } return nil } // UnmarshalText implements the TextEncoder interface func (l *LangRefValue) UnmarshalText(data []byte) error { return nil } // MarshalJSON serializes the LangRefValue into JSON func (l LangRefValue) MarshalJSON() ([]byte, error) { buf := bytes.Buffer{} if l.Ref != NilLangRef { if l.Value == "" { return nil, nil } buf.WriteByte('"') buf.WriteString(string(l.Ref)) buf.Write([]byte{'"', ':'}) } l.Value = string(unescape([]byte(l.Value))) buf.WriteString(strconv.Quote(l.Value)) return buf.Bytes(), nil } // MarshalText serializes the LangRefValue into JSON func (l LangRefValue) MarshalText() ([]byte, error) { if l.Ref != NilLangRef && l.Value == "" { return nil, nil } buf := bytes.Buffer{} buf.WriteString(l.Value) if l.Ref != NilLangRef { buf.WriteByte('[') buf.WriteString(string(l.Ref)) buf.WriteByte(']') } return buf.Bytes(), nil } // UnmarshalJSON implements the JsonEncoder interface func (l *LangRef) UnmarshalJSON(data []byte) error { return l.UnmarshalText(data) } // UnmarshalText implements the TextEncoder interface func (l *LangRef) UnmarshalText(data []byte) error { *l = LangRef("") if len(data) == 0 { return nil } if len(data) > 2 { if data[0] == '"' && data[len(data)-1] == '"' { *l = LangRef(data[1 : len(data)-1]) } } else { *l = LangRef(data) } return nil } func unescape(b []byte) []byte { // FIMXE(marius): I feel like I'm missing something really obvious about encoding/decoding from Json regarding // escape characters, and that this function is just a hack. Be better future Marius, find the real problem! b = bytes.ReplaceAll(b, []byte{'\\', 'a'}, []byte{'\a'}) b = bytes.ReplaceAll(b, []byte{'\\', 'f'}, []byte{'\f'}) b = bytes.ReplaceAll(b, []byte{'\\', 'n'}, []byte{'\n'}) b = bytes.ReplaceAll(b, []byte{'\\', 'r'}, []byte{'\r'}) b = bytes.ReplaceAll(b, []byte{'\\', 't'}, []byte{'\t'}) b = bytes.ReplaceAll(b, []byte{'\\', 'v'}, []byte{'\v'}) b = bytes.ReplaceAll(b, []byte{'\\', '"'}, []byte{'"'}) b = bytes.ReplaceAll(b, []byte{'\\', '\\'}, []byte{'\\'}) // this should cover the case of \\u -> \u return b } // UnmarshalJSON tries to load the NaturalLanguage array from the incoming json value func (n *NaturalLanguageValues) UnmarshalJSON(data []byte) error { val, typ, _, err := jsonparser.Get(data) if err != nil { // try our luck if data contains an unquoted string n.Append(NilLangRef, string(unescape(data))) return nil } switch typ { case jsonparser.Object: jsonparser.ObjectEach(data, func(key []byte, val []byte, dataType jsonparser.ValueType, offset int) error { n.Append(LangRef(key), string(unescape(val))) return err }) case jsonparser.String: n.Append(NilLangRef, string(unescape(val))) case jsonparser.Array: jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { l := LangRefValue{} l.UnmarshalJSON(value) n.Append(l.Ref, l.Value) }) } return nil } // UnmarshalText tries to load the NaturalLanguage array from the incoming Text value func (n *NaturalLanguageValues) UnmarshalText(data []byte) error { if data[0] == '"' { // a quoted string - loading it to c.URL if data[len(data)-1] != '"' { return fmt.Errorf("invalid string value when unmarshaling %T value", n) } n.Append(LangRef(NilLangRef), string(data[1:len(data)-1])) } return nil }
-
-
-
@@ -0,0 +1,467 @@package activitypub import ( "fmt" json "github.com/go-ap/jsonld" "strconv" "testing" ) func TestNaturalLanguageValue_MarshalJSON(t *testing.T) { p := NaturalLanguageValues{ { "en", "the test", }, { "fr", "le test", }, } js := "{\"en\":\"the test\",\"fr\":\"le test\"}" out, err := p.MarshalJSON() if err != nil { t.Errorf("Error: '%s'", err) } if js != string(out) { t.Errorf("Different marshal result '%s', instead of '%s'", out, js) } p1 := NaturalLanguageValues{ { "en", "the test", }, } out1, err1 := p1.MarshalJSON() if err1 != nil { t.Errorf("Error: '%s'", err1) } txt := `{"en":"the test"}` if txt != string(out1) { t.Errorf("Different marshal result '%s', instead of '%s'", out1, txt) } } func TestLangRefValue_MarshalJSON(t *testing.T) { { tst := LangRefValue{ Ref: NilLangRef, Value: "test", } j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error: %s", err) } expected := `"test"` if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } { tst := LangRefValue{ Ref: "en", Value: "test", } j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error: %s", err) } expected := `"en":"test"` if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } { tst := LangRefValue{ Ref: "en", Value: "test\nwith characters\tneeding escaping\r\n", } j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error: %s", err) } expected := `"en":"test\nwith characters\tneeding escaping\r\n"` if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } } func TestLangRefValue_MarshalText(t *testing.T) { { tst := LangRefValue{ Ref: NilLangRef, Value: "test", } j, err := tst.MarshalText() if err != nil { t.Errorf("Error: %s", err) } expected := "test" if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } { tst := LangRefValue{ Ref: "en", Value: "test", } j, err := tst.MarshalText() if err != nil { t.Errorf("Error: %s", err) } expected := "test[en]" if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } } func TestNaturalLanguageValue_Get(t *testing.T) { testVal := "test" a := NaturalLanguageValues{{NilLangRef, testVal}} if a.Get(NilLangRef) != testVal { t.Errorf("Invalid Get result. Expected %s received %s", testVal, a.Get(NilLangRef)) } } func TestNaturalLanguageValue_Set(t *testing.T) { testVal := "test" a := NaturalLanguageValues{{NilLangRef, "ana are mere"}} err := a.Set(LangRef("en"), testVal) if err != nil { t.Errorf("Received error when doing Set %s", err) } } func TestNaturalLanguageValue_Append(t *testing.T) { var a NaturalLanguageValues if len(a) != 0 { t.Errorf("Invalid initialization of %T. Size %d > 0 ", a, len(a)) } langEn := LangRef("en") valEn := "random value" a.Append(langEn, valEn) if len(a) != 1 { t.Errorf("Invalid append of one element to %T. Size %d != 1", a, len(a)) } if a.Get(langEn) != valEn { t.Errorf("Invalid append of one element to %T. Value of %q not equal to %q, but %q", a, langEn, valEn, a.Get(langEn)) } langDe := LangRef("de") valDe := "randomisch" a.Append(langDe, valDe) if len(a) != 2 { t.Errorf("Invalid append of one element to %T. Size %d != 2", a, len(a)) } if a.Get(langEn) != valEn { t.Errorf("Invalid append of one element to %T. Value of %q not equal to %q, but %q", a, langEn, valEn, a.Get(langEn)) } if a.Get(langDe) != valDe { t.Errorf("Invalid append of one element to %T. Value of %q not equal to %q, but %q", a, langDe, valDe, a.Get(langDe)) } } func TestLangRef_UnmarshalJSON(t *testing.T) { lang := "en-US" json := `"` + lang + `"` var a LangRef a.UnmarshalJSON([]byte(json)) if string(a) != lang { t.Errorf("Invalid json unmarshal for %T. Expected %q, found %q", lang, lang, string(a)) } } func TestNaturalLanguageValue_UnmarshalFullObjectJSON(t *testing.T) { langEn := "en-US" valEn := "random" langDe := "de-DE" valDe := "zufällig\n" //m := make(map[string]string) //m[langEn] = valEn //m[langDe] = valDe json := `{ "` + langEn + `": "` + valEn + `", "` + langDe + `": "` + valDe + `" }` a := make(NaturalLanguageValues, 0) _ = a.Append(LangRef(langEn), valEn) _ = a.Append(LangRef(langDe), valDe) err := a.UnmarshalJSON([]byte(json)) if err != nil { t.Error(err) } for lang, val := range a { if val.Ref != LangRef(langEn) && val.Ref != LangRef(langDe) { t.Errorf("Invalid json unmarshal for %T. Expected lang %q or %q, found %q", a, langEn, langDe, lang) } if val.Ref == LangRef(langEn) && val.Value != valEn { t.Errorf("Invalid json unmarshal for %T. Expected value %q, found %q", a, valEn, val) } if val.Ref == LangRef(langDe) && val.Value != valDe { t.Errorf("Invalid json unmarshal for %T. Expected value %q, found %q", a, valDe, val) } } } func TestNaturalLanguageValue_UnmarshalJSON(t *testing.T) { l := LangRef("") dataEmpty := []byte("") l.UnmarshalJSON(dataEmpty) if l != "" { t.Errorf("Unmarshaled object %T should be an empty string, received %q", l, l) } } func TestNaturalLanguageValue_UnmarshalText(t *testing.T) { l := LangRef("") dataEmpty := []byte("") l.UnmarshalText(dataEmpty) if l != "" { t.Errorf("Unmarshaled object %T should be an empty string, received %q", l, l) } } func TestNaturalLanguageValue_First(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValueNew(t *testing.T) { n := NaturalLanguageValuesNew() if len(n) != 0 { t.Errorf("Initial %T should have length 0, received %d", n, len(n)) } } func TestNaturalLanguageValue_MarshalText(t *testing.T) { nlv := LangRefValue{ Ref: "en", Value: "test", } tst := NaturalLanguageValues{nlv} j, err := tst.MarshalText() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("\"%s[%s]\"", nlv.Value, nlv.Ref) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } func TestNaturalLanguageValues_Append(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_First(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_Get(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_MarshalJSON(t *testing.T) { { m := NaturalLanguageValues{ { "en", "test", }, { "de", "test", }, } result, err := m.MarshalJSON() if err != nil { t.Errorf("Failed marshaling '%v'", err) } mRes := "{\"de\":\"test\",\"en\":\"test\"}" if string(result) != mRes { t.Errorf("Different results '%v' vs. '%v'", string(result), mRes) } //n := NaturalLanguageValuesNew() //result, err := n.MarshalJSON() s := make(map[LangRef]string) s["en"] = "test" n1 := NaturalLanguageValues{{ "en", "test", }} result1, err1 := n1.MarshalJSON() if err1 != nil { t.Errorf("Failed marshaling '%v'", err1) } mRes1 := `{"en":"test"}` if string(result1) != mRes1 { t.Errorf("Different results '%v' vs. '%v'", string(result1), mRes1) } } { nlv := LangRefValue{ Ref: NilLangRef, Value: "test", } tst := NaturalLanguageValues{nlv} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("\"%s\"", nlv.Value) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } { nlv := LangRefValue{ Ref: "en", Value: "test", } tst := NaturalLanguageValues{nlv} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("{\"%s\":\"%s\"}", nlv.Ref, nlv.Value) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } { nlvEn := LangRefValue{ Ref: "en", Value: "test", } nlvFr := LangRefValue{ Ref: "fr", Value: "teste", } tst := NaturalLanguageValues{nlvEn, nlvFr} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("{\"%s\":\"%s\",\"%s\":\"%s\"}", nlvEn.Ref, nlvEn.Value, nlvFr.Ref, nlvFr.Value) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } { nlvEn := LangRefValue{ Ref: "en", Value: "test\nwith new line", } nlvFr := LangRefValue{ Ref: "fr", Value: "teste\navec une ligne nouvelle", } tst := NaturalLanguageValues{nlvEn, nlvFr} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("{\"%s\":%s,\"%s\":%s}", nlvEn.Ref, strconv.Quote(nlvEn.Value), nlvFr.Ref, strconv.Quote(nlvFr.Value)) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } } func TestNaturalLanguageValues_MarshalText(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_Set(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_UnmarshalJSON(t *testing.T) { { lang := []byte{'e', 'n'} val := []byte{'a', 'n', 'a', ' ', 'a', 'r', 'e', ' ', 'm', 'e', 'r', 'e', '\n'} js := fmt.Sprintf(`[{"%s": "%s"}]`, lang, val) n := NaturalLanguageValues{} err := n.UnmarshalJSON([]byte(js)) if err != nil { t.Errorf("Unexpected error when unmarshaling %T: %s", n, err) } if n.Count() != 1 { t.Errorf("Invalid number of elements %d, expected %d", n.Count(), 1) } l := n.First() if l.Value != "ana are mere\n" { t.Errorf("Invalid %T value %q, expected %q", l, l.Value, "ana are mere\n") } if l.Ref != "en" { t.Errorf("Invalid %T ref %q, expected %q", l, l.Ref, "en") } } { ob := make(map[string]string) ob["en"] = "ana are mere\n" js, err := json.Marshal(ob) if err != nil { t.Errorf("Unexpected error when marshaling %T: %s", ob, err) } n := NaturalLanguageValues{} err = n.UnmarshalJSON(js) if err != nil { t.Errorf("Unexpected error when unmarshaling %T: %s", n, err) } if n.Count() != 1 { t.Errorf("Invalid number of elements %d, expected %d", n.Count(), 1) } l := n.First() if l.Value != "ana are mere\n" { t.Errorf("Invalid %T value %q, expected %q", l, l.Value, "ana are mere\n") } if l.Ref != "en" { t.Errorf("Invalid %T ref %q, expected %q", l, l.Ref, "en") } } } func TestNaturalLanguageValues_UnmarshalText(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValuesNew(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_String(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_Count(t *testing.T) { t.Skipf("TODO") }
-
-
-
@@ -1,12 +1,9 @@package activitypub import ( "bytes" "fmt" "github.com/buger/jsonparser" json "github.com/go-ap/jsonld" "sort" "strconv" "strings" "time" "unsafe"
-
@@ -27,8 +24,13 @@ import (type ObjectID IRI const ( // ActivityBaseURI the basic URI for the activity streams namespaces ActivityBaseURI = IRI("https://www.w3.org/ns/activitystreams") // ActivityBaseURI the URI for the activity streams namespace ActivityBaseURI = IRI("https://www.w3.org/ns/activitystreams") // SecurityContextURI the URI for the secruity namespace (for an Actor's PublicKey) SecurityContextURI = IRI("https://w3id.org/security/v1") ) const ( ObjectType ActivityVocabularyType = "Object" LinkType ActivityVocabularyType = "Link" ActivityType ActivityVocabularyType = "Activity"
-
@@ -108,7 +110,7 @@ type (// GetLink returns the object id in IRI type GetLink() IRI } // Item describes the requirements of an ActivityStreams object // ObjectOrLink describes the requirements of an ActivityStreams object ObjectOrLink interface { ActivityObject LinkOrIRI
-
@@ -128,261 +130,10 @@ type (// MimeType is the type for representing MIME types in certain ActivityStreams properties MimeType string // LangRef is the type for a language reference code, should be an ISO639-1 language specifier. LangRef string // LangRefValue is a type for storing per language values LangRefValue struct { Ref LangRef Value string } // NaturalLanguageValues is a mapping for multiple language values NaturalLanguageValues []LangRefValue ) func NaturalLanguageValuesNew() NaturalLanguageValues { return make(NaturalLanguageValues, 0) } func (n NaturalLanguageValues) String() string { cnt := len(n) if cnt == 1 { return n[0].String() } s := strings.Builder{} s.Write([]byte{'['}) for k, v := range n { s.WriteString(v.String()) if k != cnt-1 { s.Write([]byte{','}) } } s.Write([]byte{']'}) return s.String() } func (n NaturalLanguageValues) Get(ref LangRef) string { for _, val := range n { if val.Ref == ref { return val.Value } } return "" } // Set sets a language, value pair in a NaturalLanguageValues array func (n *NaturalLanguageValues) Set(ref LangRef, v string) error { found := false for k, vv := range *n { if vv.Ref == ref { (*n)[k] = LangRefValue{ref, v} found = true } } if !found { n.Append(ref, v) } return nil } // MarshalJSON serializes the NaturalLanguageValues into JSON func (n NaturalLanguageValues) MarshalJSON() ([]byte, error) { if len(n) == 0 { return json.Marshal(nil) } if len(n) == 1 { v := n[0] if v.Ref == NilLangRef { return v.MarshalJSON() } } mm := make(map[LangRef]string) for _, val := range n { mm[val.Ref] = val.Value } return json.Marshal(mm) } // First returns the first element in the array func (n NaturalLanguageValues) First() LangRefValue { for _, v := range n { return v } return LangRefValue{} } // MarshalText serializes the NaturalLanguageValues into Text func (n NaturalLanguageValues) MarshalText() ([]byte, error) { for _, v := range n { return []byte(fmt.Sprintf("%q", v)), nil } return nil, nil } // Append is syntactic sugar for resizing the NaturalLanguageValues map // and appending an element func (n *NaturalLanguageValues) Append(lang LangRef, value string) error { var t NaturalLanguageValues if len(*n) == 0 { t = make(NaturalLanguageValues, 0) } else { t = *n } t = append(*n, LangRefValue{lang, value}) *n = t return nil } // Count returns the length of Items in the item collection func (n *NaturalLanguageValues) Count() uint { return uint(len(*n)) } // String adds support for Stringer interface. It returns the Value[LangRef] text or just Value if LangRef is NIL func (l LangRefValue) String() string { if l.Ref == NilLangRef { return l.Value } return fmt.Sprintf("%s[%s]", l.Value, l.Ref) } // UnmarshalJSON implements the JsonEncoder interface func (l *LangRefValue) UnmarshalJSON(data []byte) error { _, typ, _, err := jsonparser.Get(data) if err != nil { l.Ref = NilLangRef l.Value = string(unescape(data)) return nil } switch typ { case jsonparser.Object: jsonparser.ObjectEach(data, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error { l.Ref = LangRef(key) l.Value = string(unescape(value)) return err }) case jsonparser.String: l.Ref = NilLangRef l.Value = string(unescape(data)) } return nil } // UnmarshalText implements the TextEncoder interface func (l *LangRefValue) UnmarshalText(data []byte) error { return nil } // MarshalJSON serializes the LangRefValue into JSON func (l LangRefValue) MarshalJSON() ([]byte, error) { buf := bytes.Buffer{} if l.Ref != NilLangRef { if l.Value == "" { return nil, nil } buf.WriteByte('"') buf.WriteString(string(l.Ref)) buf.Write([]byte{'"', ':'}) } l.Value = string(unescape([]byte(l.Value))) buf.WriteString(strconv.Quote(l.Value)) return buf.Bytes(), nil } // MarshalText serializes the LangRefValue into JSON func (l LangRefValue) MarshalText() ([]byte, error) { if l.Ref != NilLangRef && l.Value == "" { return nil, nil } buf := bytes.Buffer{} buf.WriteString(l.Value) if l.Ref != NilLangRef { buf.WriteByte('[') buf.WriteString(string(l.Ref)) buf.WriteByte(']') } return buf.Bytes(), nil } // UnmarshalJSON implements the JsonEncoder interface func (l *LangRef) UnmarshalJSON(data []byte) error { return l.UnmarshalText(data) } // UnmarshalText implements the TextEncoder interface func (l *LangRef) UnmarshalText(data []byte) error { *l = LangRef("") if len(data) == 0 { return nil } if len(data) > 2 { if data[0] == '"' && data[len(data)-1] == '"' { *l = LangRef(data[1 : len(data)-1]) } } else { *l = LangRef(data) } return nil } func unescape(b []byte) []byte { // FIMXE(marius): I feel like I'm missing something really obvious about encoding/decoding from Json regarding // escape characters, and that this function is just a hack. Be better future Marius, find the real problem! b = bytes.ReplaceAll(b, []byte{'\\', 'a'}, []byte{'\a'}) b = bytes.ReplaceAll(b, []byte{'\\', 'f'}, []byte{'\f'}) b = bytes.ReplaceAll(b, []byte{'\\', 'n'}, []byte{'\n'}) b = bytes.ReplaceAll(b, []byte{'\\', 'r'}, []byte{'\r'}) b = bytes.ReplaceAll(b, []byte{'\\', 't'}, []byte{'\t'}) b = bytes.ReplaceAll(b, []byte{'\\', 'v'}, []byte{'\v'}) b = bytes.ReplaceAll(b, []byte{'\\', '"'}, []byte{'"'}) b = bytes.ReplaceAll(b, []byte{'\\', '\\'}, []byte{'\\'}) // this should cover the case of \\u -> \u return b } // UnmarshalJSON tries to load the NaturalLanguage array from the incoming json value func (n *NaturalLanguageValues) UnmarshalJSON(data []byte) error { val, typ, _, err := jsonparser.Get(data) if err != nil { // try our luck if data contains an unquoted string n.Append(NilLangRef, string(unescape(data))) return nil } switch typ { case jsonparser.Object: jsonparser.ObjectEach(data, func(key []byte, val []byte, dataType jsonparser.ValueType, offset int) error { n.Append(LangRef(key), string(unescape(val))) return err }) case jsonparser.String: n.Append(NilLangRef, string(unescape(val))) case jsonparser.Array: jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) { l := LangRefValue{} l.UnmarshalJSON(value) n.Append(l.Ref, l.Value) }) } return nil } // UnmarshalText tries to load the NaturalLanguage array from the incoming Text value func (n *NaturalLanguageValues) UnmarshalText(data []byte) error { if data[0] == '"' { // a quoted string - loading it to c.URL if data[len(data)-1] != '"' { return fmt.Errorf("invalid string value when unmarshaling %T value", n) } n.Append(LangRef(NilLangRef), string(data[1:len(data)-1])) } return nil } // Describes an object of any kind. // The Activity Pub Object type serves as the base type for most of the other kinds of objects defined in the Activity // Object describes an ActivityPub object of any kind. // It serves as the base type for most of the other kinds of objects defined in the Activity // Vocabulary, including other Core types such as Activity, IntransitiveActivity, Collection and OrderedCollection. type Object struct { // ID provides the globally unique identifier for anActivity Pub Object or Link.
-
-
-
@@ -1,10 +1,7 @@package activitypub import ( "encoding/json" "fmt" "reflect" "strconv" "testing" )
-
@@ -190,117 +187,6 @@ func TestActivityVocabularyTypes_Contains(t *testing.T) {} } func TestNaturalLanguageValue_MarshalJSON(t *testing.T) { p := NaturalLanguageValues{ { "en", "the test", }, { "fr", "le test", }, } js := "{\"en\":\"the test\",\"fr\":\"le test\"}" out, err := p.MarshalJSON() if err != nil { t.Errorf("Error: '%s'", err) } if js != string(out) { t.Errorf("Different marshal result '%s', instead of '%s'", out, js) } p1 := NaturalLanguageValues{ { "en", "the test", }, } out1, err1 := p1.MarshalJSON() if err1 != nil { t.Errorf("Error: '%s'", err1) } txt := `{"en":"the test"}` if txt != string(out1) { t.Errorf("Different marshal result '%s', instead of '%s'", out1, txt) } } func TestLangRefValue_MarshalJSON(t *testing.T) { { tst := LangRefValue{ Ref: NilLangRef, Value: "test", } j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error: %s", err) } expected := `"test"` if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } { tst := LangRefValue{ Ref: "en", Value: "test", } j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error: %s", err) } expected := `"en":"test"` if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } { tst := LangRefValue{ Ref: "en", Value: "test\nwith characters\tneeding escaping\r\n", } j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error: %s", err) } expected := `"en":"test\nwith characters\tneeding escaping\r\n"` if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } } func TestLangRefValue_MarshalText(t *testing.T) { { tst := LangRefValue{ Ref: NilLangRef, Value: "test", } j, err := tst.MarshalText() if err != nil { t.Errorf("Error: %s", err) } expected := "test" if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } { tst := LangRefValue{ Ref: "en", Value: "test", } j, err := tst.MarshalText() if err != nil { t.Errorf("Error: %s", err) } expected := "test[en]" if string(j) != expected { t.Errorf("Different marshal result '%s', expected '%s'", j, expected) } } } func TestObject_IsLink(t *testing.T) { o := ObjectNew(ObjectType) o.ID = "test"
-
@@ -392,102 +278,6 @@ func TestRecipients(t *testing.T) {} } func TestNaturalLanguageValue_Get(t *testing.T) { testVal := "test" a := NaturalLanguageValues{{NilLangRef, testVal}} if a.Get(NilLangRef) != testVal { t.Errorf("Invalid Get result. Expected %s received %s", testVal, a.Get(NilLangRef)) } } func TestNaturalLanguageValue_Set(t *testing.T) { testVal := "test" a := NaturalLanguageValues{{NilLangRef, "ana are mere"}} err := a.Set(LangRef("en"), testVal) if err != nil { t.Errorf("Received error when doing Set %s", err) } } func TestNaturalLanguageValue_Append(t *testing.T) { var a NaturalLanguageValues if len(a) != 0 { t.Errorf("Invalid initialization of %T. Size %d > 0 ", a, len(a)) } langEn := LangRef("en") valEn := "random value" a.Append(langEn, valEn) if len(a) != 1 { t.Errorf("Invalid append of one element to %T. Size %d != 1", a, len(a)) } if a.Get(langEn) != valEn { t.Errorf("Invalid append of one element to %T. Value of %q not equal to %q, but %q", a, langEn, valEn, a.Get(langEn)) } langDe := LangRef("de") valDe := "randomisch" a.Append(langDe, valDe) if len(a) != 2 { t.Errorf("Invalid append of one element to %T. Size %d != 2", a, len(a)) } if a.Get(langEn) != valEn { t.Errorf("Invalid append of one element to %T. Value of %q not equal to %q, but %q", a, langEn, valEn, a.Get(langEn)) } if a.Get(langDe) != valDe { t.Errorf("Invalid append of one element to %T. Value of %q not equal to %q, but %q", a, langDe, valDe, a.Get(langDe)) } } func TestLangRef_UnmarshalJSON(t *testing.T) { lang := "en-US" json := `"` + lang + `"` var a LangRef a.UnmarshalJSON([]byte(json)) if string(a) != lang { t.Errorf("Invalid json unmarshal for %T. Expected %q, found %q", lang, lang, string(a)) } } func TestNaturalLanguageValue_UnmarshalFullObjectJSON(t *testing.T) { langEn := "en-US" valEn := "random" langDe := "de-DE" valDe := "zufällig\n" //m := make(map[string]string) //m[langEn] = valEn //m[langDe] = valDe json := `{ "` + langEn + `": "` + valEn + `", "` + langDe + `": "` + valDe + `" }` a := make(NaturalLanguageValues, 0) _ = a.Append(LangRef(langEn), valEn) _ = a.Append(LangRef(langDe), valDe) err := a.UnmarshalJSON([]byte(json)) if err != nil { t.Error(err) } for lang, val := range a { if val.Ref != LangRef(langEn) && val.Ref != LangRef(langDe) { t.Errorf("Invalid json unmarshal for %T. Expected lang %q or %q, found %q", a, langEn, langDe, lang) } if val.Ref == LangRef(langEn) && val.Value != valEn { t.Errorf("Invalid json unmarshal for %T. Expected value %q, found %q", a, valEn, val) } if val.Ref == LangRef(langDe) && val.Value != valDe { t.Errorf("Invalid json unmarshal for %T. Expected value %q, found %q", a, valDe, val) } } } func validateEmptyObject(o Object, t *testing.T) { if o.ID != "" { t.Errorf("Unmarshaled object %T should have empty ID, received %q", o, o.ID)
-
@@ -605,26 +395,6 @@ func TestObjectID_UnmarshalJSON(t *testing.T) {} } func TestNaturalLanguageValue_UnmarshalJSON(t *testing.T) { l := LangRef("") dataEmpty := []byte("") l.UnmarshalJSON(dataEmpty) if l != "" { t.Errorf("Unmarshaled object %T should be an empty string, received %q", l, l) } } func TestNaturalLanguageValue_UnmarshalText(t *testing.T) { l := LangRef("") dataEmpty := []byte("") l.UnmarshalText(dataEmpty) if l != "" { t.Errorf("Unmarshaled object %T should be an empty string, received %q", l, l) } } func TestObject_GetID(t *testing.T) { a := Object{} testVal := "crash$"
-
@@ -651,230 +421,6 @@ func TestObject_GetType(t *testing.T) {} } func TestNaturalLanguageValue_First(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValueNew(t *testing.T) { n := NaturalLanguageValuesNew() if len(n) != 0 { t.Errorf("Initial %T should have length 0, received %d", n, len(n)) } } func TestNaturalLanguageValue_MarshalText(t *testing.T) { nlv := LangRefValue{ Ref: "en", Value: "test", } tst := NaturalLanguageValues{nlv} j, err := tst.MarshalText() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("\"%s[%s]\"", nlv.Value, nlv.Ref) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } func TestNaturalLanguageValues_Append(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_First(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_Get(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_MarshalJSON(t *testing.T) { { m := NaturalLanguageValues{ { "en", "test", }, { "de", "test", }, } result, err := m.MarshalJSON() if err != nil { t.Errorf("Failed marshaling '%v'", err) } mRes := "{\"de\":\"test\",\"en\":\"test\"}" if string(result) != mRes { t.Errorf("Different results '%v' vs. '%v'", string(result), mRes) } //n := NaturalLanguageValuesNew() //result, err := n.MarshalJSON() s := make(map[LangRef]string) s["en"] = "test" n1 := NaturalLanguageValues{{ "en", "test", }} result1, err1 := n1.MarshalJSON() if err1 != nil { t.Errorf("Failed marshaling '%v'", err1) } mRes1 := `{"en":"test"}` if string(result1) != mRes1 { t.Errorf("Different results '%v' vs. '%v'", string(result1), mRes1) } } { nlv := LangRefValue{ Ref: NilLangRef, Value: "test", } tst := NaturalLanguageValues{nlv} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("\"%s\"", nlv.Value) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } { nlv := LangRefValue{ Ref: "en", Value: "test", } tst := NaturalLanguageValues{nlv} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("{\"%s\":\"%s\"}", nlv.Ref, nlv.Value) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } { nlvEn := LangRefValue{ Ref: "en", Value: "test", } nlvFr := LangRefValue{ Ref: "fr", Value: "teste", } tst := NaturalLanguageValues{nlvEn, nlvFr} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("{\"%s\":\"%s\",\"%s\":\"%s\"}", nlvEn.Ref, nlvEn.Value, nlvFr.Ref, nlvFr.Value) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } { nlvEn := LangRefValue{ Ref: "en", Value: "test\nwith new line", } nlvFr := LangRefValue{ Ref: "fr", Value: "teste\navec une ligne nouvelle", } tst := NaturalLanguageValues{nlvEn, nlvFr} j, err := tst.MarshalJSON() if err != nil { t.Errorf("Error marshaling: %s", err) } if j == nil { t.Errorf("Error marshaling: nil value returned") } expected := fmt.Sprintf("{\"%s\":%s,\"%s\":%s}", nlvEn.Ref, strconv.Quote(nlvEn.Value), nlvFr.Ref, strconv.Quote(nlvFr.Value)) if string(j) != expected { t.Errorf("Wrong value: %s, expected %s", j, expected) } } } func TestNaturalLanguageValues_MarshalText(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_Set(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_UnmarshalJSON(t *testing.T) { { lang := []byte{'e', 'n'} val := []byte{'a', 'n', 'a', ' ', 'a', 'r', 'e', ' ', 'm', 'e', 'r', 'e', '\n'} js := fmt.Sprintf(`[{"%s": "%s"}]`, lang, val) n := NaturalLanguageValues{} err := n.UnmarshalJSON([]byte(js)) if err != nil { t.Errorf("Unexpected error when unmarshaling %T: %s", n, err) } if n.Count() != 1 { t.Errorf("Invalid number of elements %d, expected %d", n.Count(), 1) } l := n.First() if l.Value != "ana are mere\n" { t.Errorf("Invalid %T value %q, expected %q", l, l.Value, "ana are mere\n") } if l.Ref != "en" { t.Errorf("Invalid %T ref %q, expected %q", l, l.Ref, "en") } } { ob := make(map[string]string) ob["en"] = "ana are mere\n" js, err := json.Marshal(ob) if err != nil { t.Errorf("Unexpected error when marshaling %T: %s", ob, err) } n := NaturalLanguageValues{} err = n.UnmarshalJSON(js) if err != nil { t.Errorf("Unexpected error when unmarshaling %T: %s", n, err) } if n.Count() != 1 { t.Errorf("Invalid number of elements %d, expected %d", n.Count(), 1) } l := n.First() if l.Value != "ana are mere\n" { t.Errorf("Invalid %T value %q, expected %q", l, l.Value, "ana are mere\n") } if l.Ref != "en" { t.Errorf("Invalid %T ref %q, expected %q", l, l.Ref, "en") } } } func TestNaturalLanguageValues_UnmarshalText(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValuesNew(t *testing.T) { t.Skipf("TODO") } func TestToObject(t *testing.T) { var it Item ob := ObjectNew(ArticleType)
-
@@ -928,19 +474,10 @@ func TestTombstone_Recipients(t *testing.T) {t.Skipf("TODO") } func TestNaturalLanguageValues_String(t *testing.T) { t.Skipf("TODO") } func TestNaturalLanguageValues_Count(t *testing.T) { t.Skipf("TODO") } func TestItemCollectionDeduplication(t *testing.T) { t.Skipf("TODO") } func TestSource_UnmarshalJSON(t *testing.T) { s := Source{}
-