From 1499acecf6e11e39f6799b680b7e944e1b553116 Mon Sep 17 00:00:00 2001 From: Walter Scheper Date: Sat, 24 Sep 2022 22:10:12 -0400 Subject: [PATCH] Update to use new generic API --- ip_addr.go | 23 ++++-------- ip_addr_example_test.go | 5 +-- tld.go | 17 ++------- update_tld.sh | 2 +- url.go | 81 ++++++++++++++++++----------------------- url_example_test.go | 24 ++++++------ url_external_test.go | 4 +- 7 files changed, 64 insertions(+), 92 deletions(-) diff --git a/ip_addr.go b/ip_addr.go index 13e24ec..a0f50a3 100644 --- a/ip_addr.go +++ b/ip_addr.go @@ -1,4 +1,4 @@ -// Copyright 2020 Walter Scheper +// Copyright 2022 Walter Scheper // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,7 +9,6 @@ package rapid import ( "fmt" "net" - "reflect" ) const ( @@ -18,8 +17,6 @@ const ( ) var ( - ipType = reflect.TypeOf(net.IP{}) - ipv4Gen = SliceOfN(Byte(), ipv4Len, ipv4Len) ipv6Gen = SliceOfN(Byte(), ipv6Len, ipv6Len) ) @@ -32,30 +29,26 @@ func (g *ipGen) String() string { return fmt.Sprintf("IP(ipv6=%v)", g.ipv6) } -func (*ipGen) type_() reflect.Type { - return ipType -} - -func (g *ipGen) value(t *T) value { - var gen *Generator +func (g *ipGen) value(t *T) net.IP { + var gen *Generator[[]byte] if g.ipv6 { gen = ipv6Gen } else { gen = ipv4Gen } - b := gen.Draw(t, g.String()).([]byte) + b := gen.Draw(t, g.String()) return net.IP(b) } -func IPv4() *Generator { - return newGenerator(&ipGen{ +func IPv4() *Generator[net.IP] { + return newGenerator[net.IP](&ipGen{ ipv6: false, }) } -func IPv6() *Generator { - return newGenerator(&ipGen{ +func IPv6() *Generator[net.IP] { + return newGenerator[net.IP](&ipGen{ ipv6: true, }) } diff --git a/ip_addr_example_test.go b/ip_addr_example_test.go index 1379835..8839d42 100644 --- a/ip_addr_example_test.go +++ b/ip_addr_example_test.go @@ -8,7 +8,6 @@ package rapid_test import ( "fmt" - "net" "pgregory.net/rapid" ) @@ -17,7 +16,7 @@ func ExampleIPv4() { gen := rapid.IPv4() for i := 0; i < 5; i++ { - addr := gen.Example(i).(net.IP) + addr := gen.Example(i) fmt.Println(addr.String()) } @@ -33,7 +32,7 @@ func ExampleIPv6() { gen := rapid.IPv6() for i := 0; i < 5; i++ { - addr := gen.Example(i).(net.IP) + addr := gen.Example(i) fmt.Println(addr.String()) } diff --git a/tld.go b/tld.go index aa9bc46..d3774ea 100644 --- a/tld.go +++ b/tld.go @@ -9,7 +9,7 @@ package rapid import "strings" // sourced from https://data.iana.org/TLD/tlds-alpha-by-domain.txt -// Version 2021090100, Last Updated Thu Sep 2 02:57:25 UTC 2021 +// Version 2022092400, Last Updated Sun Sep 25 02:07:59 UTC 2022 const tldsByAlpha = ` AAA AARP @@ -37,7 +37,6 @@ AEG AERO AETNA AF -AFAMILYCOMPANY AFL AFRICA AG @@ -189,7 +188,6 @@ BROTHER BRUSSELS BS BT -BUDAPEST BUGATTI BUILD BUILDERS @@ -313,7 +311,6 @@ CROWN CRS CRUISE CRUISES -CSC CU CUISINELLA CV @@ -372,7 +369,6 @@ DOWNLOAD DRIVE DTV DUBAI -DUCK DUNLOP DUPONT DURBAN @@ -506,7 +502,6 @@ GIFTS GIVES GIVING GL -GLADE GLASS GLE GLOBAL @@ -670,6 +665,7 @@ KG KH KI KIA +KIDS KIM KINDER KINDLE @@ -732,7 +728,6 @@ LINK LIPSY LIVE LIVING -LIXIL LK LLC LLP @@ -833,6 +828,7 @@ MTN MTR MU MUSEUM +MUSIC MUTUAL MV MW @@ -889,7 +885,6 @@ NYC NZ OBI OBSERVER -OFF OFFICE OKINAWA OLAYAN @@ -988,10 +983,8 @@ QA QPON QUEBEC QUEST -QVC RACING RADIO -RAID RE READ REALESTATE @@ -1023,7 +1016,6 @@ RICOH RIL RIO RIP -RMIT RO ROCHER ROCKS @@ -1069,7 +1061,6 @@ SCHOOL SCHULE SCHWARZ SCIENCE -SCJOHNSON SCOT SD SE @@ -1162,7 +1153,6 @@ SURGERY SUZUKI SV SWATCH -SWIFTCOVER SWISS SX SY @@ -1341,7 +1331,6 @@ XN--3BST00M XN--3DS443G XN--3E0B707E XN--3HCRJ9C -XN--3OQ18VL8PN36A XN--3PXU8K XN--42C2D9A XN--45BR5CYL diff --git a/update_tld.sh b/update_tld.sh index b6b6186..779320b 100755 --- a/update_tld.sh +++ b/update_tld.sh @@ -17,7 +17,7 @@ package rapid import "strings" // sourced from https://data.iana.org/TLD/tlds-alpha-by-domain.txt -// Version $(date +%Y%m%d00), Last Updated $(date --utc) +// Version $(date +%Y%m%d00), Last Updated $(date -u) const tldsByAlpha = \` ${TLD} \` diff --git a/url.go b/url.go index 27fb5cd..fa954b0 100644 --- a/url.go +++ b/url.go @@ -8,7 +8,6 @@ package rapid import ( "fmt" - "net" "net/url" "reflect" "strings" @@ -31,29 +30,17 @@ func (*domainNameGen) String() string { return "Domain()" } -func (*domainNameGen) type_() reflect.Type { - return domainType -} - var tldGenerator = SampledFrom(tlds) -func (g *domainNameGen) value(t *T) value { +func (g *domainNameGen) value(t *T) string { domain := tldGenerator. Filter(func(s string) bool { return len(s)+2 <= domainMaxLength }). - Map(func(s string) string { - var n string - for _, ch := range s { - n += string(SampledFrom([]rune{unicode.ToLower(ch), unicode.ToUpper(ch)}).Draw(t, "").(rune)) - } - - return n - }). - Draw(t, "domain").(string) + Draw(t, "domain") expr := fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, domainMaxElementLength-2) - elements := newRepeat(1, 126, 1) - for elements.more(t.s, g.String()) { - subDomain := StringMatching(expr).Draw(t, "subdomain").(string) + elements := newRepeat(1, 126, 1, g.String()) + for elements.more(t.s) { + subDomain := StringMatching(expr).Draw(t, "subdomain") if len(domain)+len(subDomain) >= domainMaxLength { break } @@ -64,8 +51,8 @@ func (g *domainNameGen) value(t *T) value { } // Domain generates an RFC 1035 compliant domain name. -func Domain() *Generator { - return newGenerator(&domainNameGen{}) +func Domain() *Generator[string] { + return newGenerator[string](&domainNameGen{}) } type urlGenerator struct { @@ -76,38 +63,42 @@ func (g *urlGenerator) String() string { return "URL()" } -func (g *urlGenerator) type_() reflect.Type { - return urlType -} - var printableGen = StringOf(RuneFrom(nil, unicode.PrintRanges...)) -func (g *urlGenerator) value(t *T) value { - scheme := SampledFrom(g.schemes).Draw(t, "scheme").(string) +func (g *urlGenerator) value(t *T) url.URL { + scheme := SampledFrom(g.schemes).Draw(t, "scheme") var domain string - switch SampledFrom([]int{0, 1, 2}).Draw(t, "g").(int) { + switch SampledFrom([]int{0, 1, 2}).Draw(t, "g") { case 2: - domain = Domain().Draw(t, "domain").(string) + domain = Domain().Draw(t, "domain") case 1: - domain = IPv6().Draw(t, "domain").(net.IP).String() + domain = IPv6().Draw(t, "domain").String() domain = "[" + domain + "]" case 0: - domain = IPv4().Draw(t, "domain").(net.IP).String() + domain = IPv4().Draw(t, "domain").String() + } + port := IntRange(0, 2^16-1).Draw(t, "port") + path_ := SliceOf(printableGen).Draw(t, "path") + query := SliceOf(printableGen).Draw(t, "query") + fragment := printableGen.Draw(t, "fragment") + + // join domain and port + if port > 0 { + domain += fmt.Sprintf(":%d", port) + } + + // URL escape path + for i := range path_ { + path_[i] = url.PathEscape(path_[i]) + } + + // url escape query strings + for i := range query { + query[i] = url.QueryEscape(query[i]) } - port := IntRange(0, 2^16-1). - Map(func(i int) string { - if i == 0 { - return "" - } - return fmt.Sprintf(":%d", i) - }). - Draw(t, "port").(string) - path_ := SliceOf(printableGen).Draw(t, "path").([]string) - query := SliceOf(printableGen.Map(url.QueryEscape)).Draw(t, "query").([]string) - fragment := printableGen.Draw(t, "fragment").(string) return url.URL{ - Host: domain + port, + Host: domain, Path: strings.Join(path_, "/"), Scheme: scheme, RawQuery: strings.Join(query, "&"), @@ -116,12 +107,12 @@ func (g *urlGenerator) value(t *T) value { } // URL generates RFC 3986 compliant http/https URLs. -func URL() *Generator { +func URL() *Generator[url.URL] { return urlOf([]string{"http", "https"}) } -func urlOf(schemes []string) *Generator { - return newGenerator(&urlGenerator{ +func urlOf(schemes []string) *Generator[url.URL] { + return newGenerator[url.URL](&urlGenerator{ schemes: schemes, }) } diff --git a/url_example_test.go b/url_example_test.go index e5acbfd..a6ad37c 100644 --- a/url_example_test.go +++ b/url_example_test.go @@ -5,13 +5,13 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. // String generation depends on the Unicode tables, which change with Go versions: +//go:build go1.16 // +build go1.16 package rapid_test import ( "fmt" - "net/url" "pgregory.net/rapid" ) @@ -24,25 +24,25 @@ func ExampleDomain() { } // Output: - // D1C.TRaVElErs - // C.cuISiNeLlA - // r.abbVIe - // MC0zJ.aCcOuntAnTs - // T6hFdv10.aaa + // l.UOL + // S.CYMRU + // e.ABBVIE + // x.ACCOUNTANTS + // R.AAA } func ExampleURL() { gen := rapid.URL() for i := 0; i < 5; i++ { - e := gen.Example(i).(url.URL) + e := gen.Example(i) fmt.Println(e.String()) } // Output: - // https://[e506:816b:407:316:fb4c:ffa0:e208:dc0e]/%F0%97%B0%A0%F0%92%91%9CX/1=%22?%C4%90%F0%90%A9%87%26#%F0%96%AC%B21%CC%88%CC%81D - // http://G.BLoG/%E0%AD%8C~%F0%9F%AF%8A%22%D6%93%E0%A9%AD%E1%B3%930%D0%8A/%C2%BC%E0%B4%BC3%F0%9D%9F%B9%F0%91%91%82%C2%B2%E0%B3%A9%CC%80D/%7C+%F0%9F%82%92+%5D%CC%81%CB%85/%CC%80/%E1%B0%BF/%CD%82K%E0%A5%A9%CC%81#%CC%82 - // https://1.47.4.5:11/+%3E%E2%9F%BCK//A%DB%97%F0%91%99%83$%E0%A0%BD%E2%82%A5%F0%9D%A9%A9%E0%BC%95%E0%B5%A8%3C%E0%BE%AE%F0%97%8A%B1%E2%9E%8E%E0%B9%91$v%CC%80/%CC%94Z%E4%87%94?%F0%96%A9%AEC%C2%B9%E2%8A%A5%F0%92%91%B41%E0%A0%BE%CB%BE%C3%9D%E1%B3%A4%E0%AB%A6%CC%81%CC%86&%E2%A4%88%F0%91%BF%BF%24B%F0%96%BA%90%CC%9A&&%CC%80%C2%A7%E8%93%8B&#%E0%AB%AE%F0%92%91%91 - // http://G.hM/%CC%80%E0%A0%B1%CC%82%CC%80%F0%9E%A5%9F/:%21J%E2%9D%87#L%CC%82%E9%98%8C%22 - // http://1.1.4.6:2/%F0%A7%A8%A4%F0%A1%AD%8D%E2%92%8B0/%DC%B4B?%E2%80%A60%CC%80%C3%B7&%CC%81%CC%A2%21%E0%AF%AB%CC%81%C3%A4&%F0%9F%AF%8A%EA%99%AF%CC%80%E0%A5%AD&%E5%8B%B71&%E1%B7%8F%CC%8B%E2%87%94%E2%90%8E%EA%A3%A0%E0%B5%9A%3D%E5%8E%8A%D9%AAB%F0%A8%83%A2%EF%B8%B4%E0%A0%BD%F0%9D%84%86%C6%81%211A3&%E1%81%8F%23#%CC%80%E0%BF%8B+$ + // https://[e506:816b:407:316:fb4c:ffa0:e208:dc0e]/%25F0%2597%25B0%25A0%25F0%2592%2591%259CX/1=%2522?%C4%90%F0%90%A9%87%26#%F0%96%AC%B21%CC%88%CC%81D + // http://Z.BLOOMBERG:2/%25E2%259C%25A1/1%25F0%2591%2588%25BD/%25F0%259F%25AF%258A%2522%25D6%2593%25E0%25A9%25AD%25E1%25B3%25930%25D0%258A/%25C2%25BC%25E0%25B4%25BC3%25F0%259D%259F%25B9%25F0%2591%2591%2582%25C2%25B2%25E0%25B3%25A9%25CC%2580D/%257C+%25F0%259F%2582%2592+%255D%25CC%2581%25CB%2585/%25CC%2580/%25E1%25B0%25BF/%25CD%2582K%25E0%25A5%25A9%25CC%2581#%CC%82 + // https://1.47.4.5:11/+%253E%25E2%259F%25BCK//A%25DB%2597%25F0%2591%2599%2583$%25E0%25A0%25BD%25E2%2582%25A5%25F0%259D%25A9%25A9%25E0%25BC%2595%25E0%25B5%25A8%253C%25E0%25BE%25AE%25F0%2597%258A%25B1%25E2%259E%258E%25E0%25B9%2591$v%25CC%2580/%25CC%2594Z%25E4%2587%2594?%F0%96%A9%AEC%C2%B9%E2%8A%A5%F0%92%91%B41%E0%A0%BE%CB%BE%C3%9D%E1%B3%A4%E0%AB%A6%CC%81%CC%86&%E2%A4%88%F0%91%BF%BF%24B%F0%96%BA%90%CC%9A&&%CC%80%C2%A7%E8%93%8B&#%E0%AB%AE%F0%92%91%91 + // http://J.HOMESENSE/%25F0%259B%2589%259D%25C2%25B86%25CC%2580%25F0%259E%25A5%259F/:%2521J%25E2%259D%2587#L%CC%82%E9%98%8C%22 + // http://1.1.4.6:2/%25F0%25A7%25A8%25A4%25F0%25A1%25AD%258D%25E2%2592%258B0/%25DC%25B4B?%E2%80%A60%CC%80%C3%B7&%CC%81%CC%A2%21%E0%AF%AB%CC%81%C3%A4&%F0%9F%AF%8A%EA%99%AF%CC%80%E0%A5%AD&%E5%8B%B71&%E1%B7%8F%CC%8B%E2%87%94%E2%90%8E%EA%A3%A0%E0%B5%9A%3D%E5%8E%8A%D9%AAB%F0%A8%83%A2%EF%B8%B4%E0%A0%BD%F0%9D%84%86%C6%81%211A3&%E1%81%8F%23#%CC%80%E0%BF%8B+$ } diff --git a/url_external_test.go b/url_external_test.go index 285f6e3..1aef129 100644 --- a/url_external_test.go +++ b/url_external_test.go @@ -18,7 +18,7 @@ func TestURL(t *testing.T) { t.Parallel() Check(t, func(t *T) { - u := URL().Draw(t, "url").(url.URL) + u := URL().Draw(t, "url") // should be parseable if _, err := url.Parse(u.String()); err != nil { @@ -31,7 +31,7 @@ func TestDomain(t *testing.T) { t.Parallel() Check(t, func(t *T) { - d := Domain().Draw(t, "d").(string) + d := Domain().Draw(t, "d") if got, want := len(d), 255; got > want { t.Errorf("got domain of length %d with maxLenght of %d", got, want) }