func TestEnclosureBasic(t *testing.T) { var testdata = []testEnclosure{ {`<enclosure url="http://www.scripting.com/mp3s/weatherReportSuite.mp3" length="12216320" type="audio/mpeg" />`, nil, NewTestEnclosure("http://www.scripting.com/mp3s/weatherReportSuite.mp3", "12216320", "audio/mpeg"), }, {`<enclosure length="12216320" type="audio/mpeg" />`, xmlutils.NewError(MissingAttribute, ""), NewTestEnclosure("", "12216320", "audio/mpeg"), }, {`<enclosure url="http://www.scripting.com/mp3s/weatherReportSuite.mp3" type="audio/mpeg" />`, xmlutils.NewError(MissingAttribute, ""), NewTestEnclosure("http://www.scripting.com/mp3s/weatherReportSuite.mp3", "", "audio/mpeg"), }, {`<enclosure url="http://www.scripting.com/mp3s/weatherReportSuite.mp3" length="12216320" />`, xmlutils.NewError(MissingAttribute, ""), NewTestEnclosure("http://www.scripting.com/mp3s/weatherReportSuite.mp3", "12216320", ""), }, } nbErrors := 0 len := len(testdata) for _, testenclosure := range testdata { testcase := _TestEnclosureToTestVisitor(testenclosure) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (e *Entry) validateLinks(err *utils.ErrorAggregator) { combinations := make([]string, 0) hasAlternateRel := false for _, link := range e.Links { if link.Rel.Value == "alternate" { hasAlternateRel = true s := link.Type.Value + link.HrefLang.Value unique := true for _, comb := range combinations { if s == comb { err.NewError(xmlutils.NewError(LinkAlternateDuplicated, fmt.Sprintf("Alternate Link duplicated: hreflang '%s' type '%s'", link.HrefLang.Value, link.Type.Value))) unique = false } } if unique { combinations = append(combinations, s) } } } if e.Occurences.Count("content") == 0 && !hasAlternateRel { err.NewError(xmlutils.NewError(NoContentOrAlternateLink, "Entry should have either a Content element or a Link with alternate type")) } }
func TestDateBasic(t *testing.T) { var testdata = []testDate{ {`<updated>Tue, 20 Sep 2010 16:02:50 GMT</updated>`, nil, NewTestDate("Tue, 20 Sep 2010 16:02:50 GMT"), }, {`<updated>Tue, 20 Sep 2010 16:02:50</updated>`, xmlutils.NewError(DateFormat, ""), NewTestDate("0"), }, {`<updated>2003-12-13T18:30:02.25</updated>`, xmlutils.NewError(DateFormat, ""), NewTestDate("0"), }, } nbErrors := 0 len := len(testdata) for _, testdate := range testdata { testcase := testDateToTestVisitor(testdate) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func TestIdBasic(t *testing.T) { var testdata = []testId{ {`<id xml:lang="en-us" xml:base="http://yo.com">https://www.yo.com</id>`, nil, IdWithBaseLang(NewTestId("https://www.yo.com"), "en-us", "http://yo.com"), }, {`<id>https://www.yo.com</id>`, nil, NewTestId("https://www.yo.com"), }, {`<id>https://www.%yo.com</id>`, xmlutils.NewError(IriNotAbsolute, ""), NewTestId("https://www.%yo.com"), }, {`<id> https://www.%yo.com </id>`, xmlutils.NewError(IriNotAbsolute, ""), NewTestId("https://www.%yo.com"), }, } nbErrors := 0 len := len(testdata) for _, testid := range testdata { testcase := testIdToTestVisitor(testid) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (i *InlineXHTMLContent) ProcessEndElement(el xml.EndElement) (xmlutils.Visitor, xmlutils.ParserError) { level := i.depth.Up() if level == xmlutils.RootLevel { if err := i.EncodeXHTMLToken(el); err != nil { return i, xmlutils.NewError(XHTMLEncodeToStringError, "cannot encode XHTML") } if err := i.flush(); err != nil { return i, err } i.completed = true return i, nil } if level == xmlutils.ParentLevel { if err := i.flush(); err != nil { return i.Parent, err } if i.Parent != nil { return i.Parent.ProcessEndElement(el) } return nil, nil } if err := i.EncodeXHTMLToken(el); err != nil { return i, xmlutils.NewError(XHTMLEncodeToStringError, "cannot encode XHTML") } return i, nil }
func (f *Feed) validateLinks(err *utils.ErrorAggregator) { combinations := make([]string, 0) hasSelf := false for _, link := range f.Links { if link.Rel.Value == "alternate" { s := link.Type.Value + link.HrefLang.Value unique := true for _, comb := range combinations { if s == comb { err.NewError(xmlutils.NewError(LinkAlternateDuplicated, fmt.Sprintf("Alternate Link duplicated: hreflang '%s' type '%s'", link.HrefLang.Value, link.Type.Value))) unique = false } } if unique { combinations = append(combinations, s) } } else if link.Rel.Value == "self" { hasSelf = true } } if !hasSelf { err.NewError(xmlutils.NewError(MissingSelfLink, "Feed must have a link with rel attribute set to 'self'")) } }
func TestGeneratorBasic(t *testing.T) { var testdata = []testGenerator{ {`<generator uri="http://there.com" version="4.0" xml:lang="en-us" xml:base="http://yo.com">my generator</generator>`, nil, GeneratorWithBaseLang(NewTestGenerator("4.0", "http://there.com", "my generator"), "en-us", "http://yo.com"), }, {`<generator uri="http://there.com" version="4.0">my generator</generator>`, nil, NewTestGenerator("4.0", "http://there.com", "my generator"), }, {`<generator uri="http://there.com" version="4.0"><name>CHILD</name></generator>`, xmlutils.NewError(LeafElementHasChild, ""), NewTestGenerator("4.0", "http://there.com", "CHILD"), }, {`<generator uri="http://%there.com" version="4.0">my generator</generator>`, xmlutils.NewError(IriNotValid, ""), NewTestGenerator("4.0", "http://%there.com", "my generator"), }, } nbErrors := 0 len := len(testdata) for _, testgenerator := range testdata { testcase := testGeneratorToTestVisitor(testgenerator) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (u *Updated) Validate() xmlutils.ParserError { errAgg := utils.NewErrorAggregator() link, ok := u.Parent.(*atom.Link) if !ok { errAgg.NewError(xmlutils.NewError(NotInLinkElement, "updated attr should be placed in link element")) } else { if link.Rel.String() != "replies" { errAgg.NewError(xmlutils.NewError(LinkNotReplies, "link element should avec a 'replies' rel for this extension")) } } return errAgg.ErrorObject() }
func relIsIANA(name, s string) xmlutils.ParserError { if s == "alternate" || s == "related" || s == "self" || s == "enclosure" || s == "via" { return nil } return xmlutils.NewError(RelNotValid, fmt.Sprintf("rel is not valid: %s", s)) }
func contentTypeIsValid(name, s string) xmlutils.ParserError { if s == "text" || s == "html" || s == "xhtml" { return xmlutils.NewError(ContentTypeIsNotValid, "type not valid") } return nil }
func (i *InlineOtherContent) ProcessStartElement(el xmlutils.StartElement) (xmlutils.Visitor, xmlutils.ParserError) { err := utils.NewErrorAggregator() if i.depth.IsRoot() { for _, attr := range el.Attr { switch attr.Name.Local { case "type": i.Type.Value = attr.Value i.Type.IncOccurence() } } } else { if error := i.Encoder.EncodeToken(el); error != nil { err.NewError(xmlutils.NewError(XHTMLEncodeToStringError, "cannot encode XHTML")) } if i.depth.Level > 0 { i.hasChild = true } } i.depth.Down() return i, nil }
func TestLogoBasic(t *testing.T) { var testdata = []testLogo{ {`<logo xml:lang="en-us" xml:base="http://yo.com">https://www.yo.com</logo>`, nil, LogoWithBaseLang(NewTestLogo("https://www.yo.com"), "en-us", "http://yo.com"), }, {`<logo>https://www.yo.com</logo>`, nil, NewTestLogo("https://www.yo.com"), }, {`<logo>https://www.%yo.com</logo>`, xmlutils.NewError(IriNotValid, ""), NewTestLogo("https://www.%yo.com"), }, } nbErrors := 0 len := len(testdata) for _, testlogo := range testdata { testcase := testLogoToTestVisitor(testlogo) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (g *Generator) ProcessStartElement(el xmlutils.StartElement) (xmlutils.Visitor, xmlutils.ParserError) { if g.depth.IsRoot() { g.reset() for _, attr := range el.Attr { switch attr.Name.Space { case xmlutils.XML_NS: g.ProcessAttr(attr) case "": switch attr.Name.Local { case "uri": g.Uri.Value = attr.Value g.Uri.IncOccurence() case "version": g.Version.Value = attr.Value g.Version.IncOccurence() } default: g.Extension.ProcessAttr(attr, g) } } } if g.depth.Down() == xmlutils.MaxDepthReached { return g, xmlutils.NewError(LeafElementHasChild, "'generator' shoud not have childs") } return g, nil }
func TestSourceBasic(t *testing.T) { var testdata = []testSource{ {`<source>Tomalak's Realm</source>`, xmlutils.NewError(MissingAttribute, ""), NewTestSource("", "Tomalak's Realm"), }, {`<source url="http://www.tomaltak.org/links2.xml">Tomalak's Realm</source>`, nil, NewTestSource("http://www.tomaltak.org/links2.xml", "Tomalak's Realm"), }, } nbErrors := 0 len := len(testdata) for _, testsource := range testdata { testcase := _TestSourceToTestVisitor(testsource) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (c *Count) Validate() xmlutils.ParserError { errAgg := utils.NewErrorAggregator() link, ok := c.Parent.(*atom.Link) if !ok { errAgg.NewError(xmlutils.NewError(NotInLinkElement, "count attr should be placed in link element")) } else { if link.Rel.String() != "replies" { errAgg.NewError(xmlutils.NewError(LinkNotReplies, "link element should avec a 'replies' rel for this extension")) } } if err := c.Validator(c.Name().Local, c.Content); err != nil { errAgg.NewError(err) } return errAgg.ErrorObject() }
func (i *InlineXHTMLContent) flush() xmlutils.ParserError { err := i.Encoder.Flush() if err != nil { return xmlutils.NewError(CannotFlush, "cannot flush XHTML") } return nil }
func (i *InlineXHTMLContent) ProcessCharData(el xml.CharData) (xmlutils.Visitor, xmlutils.ParserError) { if len(strings.Fields(string(el))) > 0 { if err := i.flush(); err != nil { return i, err } if _, err := i.Content.Write(el); err != nil { return i, xmlutils.NewError(CannotFlush, "cannot flush content") } if i.depth.Level == 0 { return i, xmlutils.NewError(XHTMLRootNodeNotDiv, "XHTML element should have a root") } } return i, nil }
func TestDateBasic(t *testing.T) { var testdata = []testDate{ {`<updated xml:lang="en-us" xml:base="http://yo.com">2003-12-13T18:30:02Z</updated>`, nil, DateWithBaseLang(NewTestDate("2003-12-13T18:30:02Z"), "en-us", "http://yo.com"), }, {`<updated>2003-12-13T18:30:02Z</updated>`, nil, NewTestDate("2003-12-13T18:30:02Z"), }, {`<updated>2003-12-13T18:30:02.25Z</updated>`, nil, NewTestDate("2003-12-13T18:30:02.25Z"), }, {`<updated>2003-12-13T18:30:02+01:00</updated>`, nil, NewTestDate("2003-12-13T18:30:02+01:00"), }, {`<updated>2003-12-13T18:30:02.25+01:00</updated>`, nil, NewTestDate("2003-12-13T18:30:02.25+01:00"), }, {`<updated>2003-12-13t18:30:02z</updated>`, xmlutils.NewError(DateFormat, ""), NewTestDate("0"), }, {`<updated>2003-12-13T18:30:02.25</updated>`, xmlutils.NewError(DateFormat, ""), NewTestDate("0"), }, } nbErrors := 0 len := len(testdata) for _, testdate := range testdata { testcase := testDateToTestVisitor(testdate) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (d *Date) ProcessCharData(el xml.CharData) (xmlutils.Visitor, xmlutils.ParserError) { var err error d.Time, err = time.Parse(time.RFC3339, string(el)) if err != nil || d.Time.IsZero() { return d, xmlutils.NewError(DateFormat, fmt.Sprintf("date not well formatted '%v'", string(el))) } return d, nil }
func TestCloudBasic(t *testing.T) { var testdata = []testCloud{ {`<cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="myCloud.rssPleaseNotify" protocol="xml-rpc" />`, nil, NewTestCloud("rpc.sys.com", "80", "/RPC2", "myCloud.rssPleaseNotify", "xml-rpc"), }, {`<cloud port="80" path="/RPC2" registerProcedure="myCloud.rssPleaseNotify" protocol="xml-rpc" />`, xmlutils.NewError(MissingAttribute, ""), NewTestCloud("", "80", "/RPC2", "myCloud.rssPleaseNotify", "xml-rpc"), }, {`<cloud domain="rpc.sys.com" path="/RPC2" registerProcedure="myCloud.rssPleaseNotify" protocol="xml-rpc" />`, xmlutils.NewError(MissingAttribute, ""), NewTestCloud("rpc.sys.com", "", "/RPC2", "myCloud.rssPleaseNotify", "xml-rpc"), }, {`<cloud domain="rpc.sys.com" port="80" registerProcedure="myCloud.rssPleaseNotify" protocol="xml-rpc" />`, xmlutils.NewError(MissingAttribute, ""), NewTestCloud("rpc.sys.com", "80", "", "myCloud.rssPleaseNotify", "xml-rpc"), }, {`<cloud domain="rpc.sys.com" port="80" path="/RPC2" protocol="xml-rpc" />`, xmlutils.NewError(MissingAttribute, ""), NewTestCloud("rpc.sys.com", "80", "/RPC2", "", "xml-rpc"), }, {`<cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="myCloud.rssPleaseNotify" />`, xmlutils.NewError(MissingAttribute, ""), NewTestCloud("rpc.sys.com", "80", "/RPC2", "myCloud.rssPleaseNotify", ""), }, } nbErrors := 0 len := len(testdata) for _, testcloud := range testdata { testcase := _TestCloudToTestVisitor(testcloud) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (i *InlineXHTMLContent) ProcessStartElement(el xmlutils.StartElement) (xmlutils.Visitor, xmlutils.ParserError) { err := utils.NewErrorAggregator() if i.depth.Level == 0 && el.Name.Local != "div" { err.NewError(xmlutils.NewError(XHTMLRootNodeNotDiv, "Inline XHTML root node must be a div")) } if i.completed == true { err.NewError(xmlutils.NewError(NotUniqueChild, "Inline XHTML should be contained in a unique node")) } i.depth.Down() if error := i.CheckXHTMLSpace(el); error != nil { err.NewError(error) } if error := i.EncodeXHTMLToken(el); error != nil { err.NewError(xmlutils.NewError(XHTMLEncodeToStringError, "cannot encode XHTML")) } return i, err.ErrorObject() }
func (b *BasicElement) Validate() xmlutils.ParserError { error := utils.NewErrorAggregator() b.Extension.Validate(&error) if err := b.Content.Validate(); err != nil { error.NewError(xmlutils.NewError(err.Flag(), fmt.Sprintf("%s's %s", b.name.Local, err.Msg()))) } return error.ErrorObject() }
func (i *InlineOtherContent) validate() xmlutils.ParserError { error := utils.NewErrorAggregator() xmlutils.ValidateElements("inlineothercontent", &error, i.Type) if strings.HasPrefix(i.Type.Value, "text/") && i.hasChild { error.NewError(xmlutils.NewError(LeafElementHasChild, "text content should not have child")) } return error.ErrorObject() }
func (i *Item) validate() xmlutils.ParserError { err := utils.NewErrorAggregator() xmlutils.ValidateOccurenceCollection("item", &err, i.Occurences) i.Extension.Validate(&err) if i.Occurences.Count("description") == 0 && i.Occurences.Count("title") == 0 { err.NewError(xmlutils.NewError(MissingAttribute, "item should have at least a title or a description")) } return err.ErrorObject() }
func (u *UnescapedContent) ProcessCharData(el xml.CharData) (xmlutils.Visitor, xmlutils.ParserError) { if len(strings.Fields(string(el))) > 0 { if ferr := u.flush(); ferr != nil { return u, ferr } if _, err := u.Content.Write(el); err != nil { return u, xmlutils.NewError(CannotFlush, "cannot flush content") } } return u, nil }
func (d *Date) ProcessStartElement(el xmlutils.StartElement) (xmlutils.Visitor, xmlutils.ParserError) { if d.depth.IsRoot() { for _, attr := range el.Attr { d.Extension.ProcessAttr(attr, d) } } if d.depth.Down() == xmlutils.RootLevel { return d.Parent, xmlutils.NewError(LeafElementHasChild, "date construct shoud not have childs") } return d, nil }
func (d *Date) ProcessCharData(el xml.CharData) (xmlutils.Visitor, xmlutils.ParserError) { var err error d.RawContent = string(el) for _, dateFormat := range rssDateFormat { d.Time, err = time.Parse(dateFormat, string(el)) if err == nil && !d.Time.IsZero() { return d, nil } } return d, xmlutils.NewError(DateFormat, fmt.Sprintf("date not well formatted '%v'", string(el))) }
func TestCategoryBasic(t *testing.T) { var testdata = []testCategory{ {`<category xml:lang="en-us" xml:base="http://yo.com" scheme='https://www.yo.com' term='music' />`, nil, CategoryWithBaseLang(NewTestCategory("https://www.yo.com", "music", ""), "en-us", "http://yo.com"), }, {`<category scheme='https://www.yo.com' term='music' />`, nil, NewTestCategory("https://www.yo.com", "music", ""), }, {`<category scheme='https://www.tbray.org/ongoing/What/' />`, xmlutils.NewError(MissingAttribute, ""), NewTestCategory("https://www.tbray.org/ongoing/What/", "", ""), }, {`<category term="music" label='house' />`, nil, NewTestCategory("", "music", "house"), }, {`<category term="music" label='house' scheme='http://www.%scheme.com'/>`, xmlutils.NewError(IriNotValid, ""), NewTestCategory("http://www.%scheme.com", "music", "house"), }, } nbErrors := 0 len := len(testdata) for _, testcategory := range testdata { testcase := testCategoryToTestVisitor(testcategory) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }
func (i *InlineOtherContent) ProcessEndElement(el xml.EndElement) (xmlutils.Visitor, xmlutils.ParserError) { level := i.depth.Up() if level == xmlutils.RootLevel { i.Encoder.Flush() return i.Parent, i.validate() } if err := i.Encoder.EncodeToken(el); err != nil { return i, xmlutils.NewError(XHTMLEncodeToStringError, "cannot encode XHTML") } return i, nil }
func TestLinkBasic(t *testing.T) { var testdata = []testLink{ {`<link xml:lang="en-us" xml:base="http://yo.com" href="http://www.go.com" rel="alternate" type="text/html"/>`, nil, LinkWithBaseLang(NewTestLink("http://www.go.com", "alternate", "text/html", "", "", ""), "en-us", "http://yo.com"), }, {`<link rel="alternate" type="text/html"/>`, xmlutils.NewError(MissingAttribute, ""), NewTestLink("", "alternate", "text/html", "", "", ""), }, {`<link rel="alternate" type="text/html" href="http://%%%www.go.com"/>`, xmlutils.NewError(IriNotValid, ""), NewTestLink("http://%%%www.go.com", "alternate", "text/html", "", "", ""), }, {`<link rel="alternate" type="text/html" href="http://www.go.com" length="-56"/>`, xmlutils.NewError(NotPositiveNumber, ""), NewTestLink("http://www.go.com", "alternate", "text/html", "", "", "-56"), }, {`<link rel="alternate" type="text/html" href="http://www.go.com" length="ab"/>`, xmlutils.NewError(NotPositiveNumber, ""), NewTestLink("http://www.go.com", "alternate", "text/html", "", "", "ab"), }, } nbErrors := 0 len := len(testdata) for _, testlink := range testdata { testcase := testLinkToTestVisitor(testlink) if err := testcase.CheckTestCase(); err != nil { t.Errorf("FAIL\n%s\nXML:\n %s\n", err, testcase.XML) nbErrors++ } } t.Logf("PASS RATIO = %v/%v\n", len-nbErrors, len) }