profile
viewpoint
Gregory Petrosyan flyingmutant St.-Petersburg, Russia https://pgregory.net

flyingmutant/rapid 182

Rapid is a Go library for property-based testing that supports state machine ("stateful" or "model-based") testing and fully automatic test case minimization ("shrinking")

flyingmutant/changepoint 11

Changepoint is a Go library for changepoint detection with support for nonparametric distributions

flyingmutant/siphash 6

Naïve C implementation of the SipHash-2-4 pseudo-random function

flyingmutant/bdigest 1

B-digest is a Go library for fast and memory-efficient estimation of quantiles with guaranteed relative error and full mergeability

flyingmutant/BlockSci 0

A high-performance tool for blockchain science and exploration

flyingmutant/CAD 0

Attempt at refactoring Contextual Anomaly Detector

flyingmutant/cmus 0

Small, fast and powerful console music player for Unix-like operating systems.

flyingmutant/go 0

The Go programming language

flyingmutant/mustela 0

Mustela - must be something cute

flyingmutant/pgregory.net 0

Personal website

pull request commentflyingmutant/rapid

Add generators for URLs and domain names

I'm at a loss on how to address the 1.13 issue. I think I may need to install go 1.13 and try stepping through the example with delve. I should have some time tonight.

wfscheper

comment created time in 7 days

startedflyingmutant/rapid

started time in 9 days

startedflyingmutant/rapid

started time in 10 days

issue commentZannick/demystify

Scryfall API breaking changes

I've been making some changes by myself. It's running fine so far. You can see the changes here in case you have more advice.

Fulmene

comment created time in 10 days

issue commentZannick/demystify

Scryfall API breaking changes

Hello! Sorry for the long delay, I appear to have notifications not set up right. I have not attempted to run this in some time. Do you have a recent error message?

Fulmene

comment created time in 10 days

pull request commentflyingmutant/rapid

add pull request

Hmm. Yes, didn't work quite the way I expected.

Main thing was to keep the CI change separate in case you didn't want me to include it in the original PR. If you're okay with it, I'll just push this to the other PR and close this one.

wfscheper

comment created time in 14 days

PR opened flyingmutant/rapid

add pull request

Simply adds pull_request to the triggers in ci.yaml.

Note that at least on my pushes, the CI check for go 1.13 is failing, because the encoded version of the paths differ. I'm still looking for a reason why that's the case.

+1854 -2

0 comment

7 changed files

pr created time in 15 days

pull request commentflyingmutant/rapid

Add generators for URLs and domain names

I think GitHub treats pushes to pull requests differently than pushes to "normal" branches.

I'll try a rebase later today.

On Thu, Nov 12, 2020, 11:28 Gregory Petrosyan notifications@github.com wrote:

Shouldn't "on (any) push" https://github.com/flyingmutant/rapid/blob/master/.github/workflows/ci.yml#L3 be enough?

Also, can you please try rebasing on top of current master? Maybe it can help CI to unstuck itself as well.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/flyingmutant/rapid/pull/18#issuecomment-726186571, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAPTM5GSAMBL5HO2WDFC7TSPQEL3ANCNFSM4TGGHHMA .

wfscheper

comment created time in 16 days

pull request commentflyingmutant/rapid

Add generators for URLs and domain names

I don't think anything is being scheduled for the PR, but I'm not sure why.

wfscheper

comment created time in 16 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)++	return newGenerator(&domainNameGen{+		maxElementLength: maxElementLength,+		maxLength:        maxLength,+	})+}++type urlGenerator struct {+	schemes []string+}++func (g *urlGenerator) String() string {+	return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)+}++func (g *urlGenerator) type_() reflect.Type {+	return reflect.TypeOf(url.URL{})+}++func (g *urlGenerator) value(t *T) value {+	scheme := SampledFrom(g.schemes).Draw(t, "scheme").(string)+	domain := Domain().Draw(t, "domain").(string)

Done.

wfscheper

comment created time in 17 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)++	return newGenerator(&domainNameGen{+		maxElementLength: maxElementLength,+		maxLength:        maxLength,+	})+}++type urlGenerator struct {+	schemes []string+}++func (g *urlGenerator) String() string {+	return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)+}++func (g *urlGenerator) type_() reflect.Type {+	return reflect.TypeOf(url.URL{})+}++func (g *urlGenerator) value(t *T) value {+	scheme := SampledFrom(g.schemes).Draw(t, "scheme").(string)+	domain := Domain().Draw(t, "domain").(string)

Adding the IPv4 and IPv6 generators is pretty straightforward, but I'm not sure how to incorporate them into the URL generator.

I can think of three ways to do this:

  • One generator, URL(), that generates both DNS URLs and IP URLs
  • Two generators, URL() that generates DNS URLs and URLOf(schemes []string, domain *Generator).
  • Three generators, URL(), URLIPv4(), andURLIPv6()`

I think you're looking for the first option, but wanted to float the other two and see what you think.

wfscheper

comment created time in 18 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid_test++import (+	"fmt"++	"pgregory.net/rapid"+)++func ExampleDomain() {+	gen := rapid.Domain()++	for i := 0; i < 5; i++ {+		fmt.Println(gen.Example(i))+	}++	// Output:+	// MV2zb0-S2j.trAveLcHAnnEL+	// Z.CU+	// r.ABBotT+	// r.AcCoUNTaNT+	// R.

Yeah, that's probably coming from the two empty string entries that are incorrectly included.

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)++	return newGenerator(&domainNameGen{+		maxElementLength: maxElementLength,+		maxLength:        maxLength,+	})+}++type urlGenerator struct {+	schemes []string+}++func (g *urlGenerator) String() string {+	return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)+}++func (g *urlGenerator) type_() reflect.Type {+	return reflect.TypeOf(url.URL{})+}++func (g *urlGenerator) value(t *T) value {+	scheme := SampledFrom(g.schemes).Draw(t, "scheme").(string)+	domain := Domain().Draw(t, "domain").(string)+	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_ := path.Join(+		SliceOf(+			StringOf(RuneFrom(nil, unicode.PrintRanges...)).Map(url.PathEscape),+		).Draw(t, "path").([]string)...)++	return url.URL{

I thought about that, but wasn't sure what to do.

With the very simple API currently exposed, there's no configurability of whether or not to generate query parameters or fragments. I suppose the consumer could use a Filter or Map to strip the parts they don't want. What are your thoughts?

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)++	return newGenerator(&domainNameGen{+		maxElementLength: maxElementLength,+		maxLength:        maxLength,+	})+}++type urlGenerator struct {+	schemes []string+}++func (g *urlGenerator) String() string {+	return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)+}++func (g *urlGenerator) type_() reflect.Type {+	return reflect.TypeOf(url.URL{})+}++func (g *urlGenerator) value(t *T) value {+	scheme := SampledFrom(g.schemes).Draw(t, "scheme").(string)+	domain := Domain().Draw(t, "domain").(string)+	port := IntRange(0, 2^16-1).

My intuition is that the RFC is refraining from specifying something that's out of the scope of the standard, rather than positively asserting that there is no limit on the range of valid ports.

Your call, but I think limiting the generation to the standard 16-bit valid port range is reasonable.

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)++	return newGenerator(&domainNameGen{+		maxElementLength: maxElementLength,+		maxLength:        maxLength,+	})+}++type urlGenerator struct {+	schemes []string+}++func (g *urlGenerator) String() string {+	return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)+}++func (g *urlGenerator) type_() reflect.Type {+	return reflect.TypeOf(url.URL{})+}++func (g *urlGenerator) value(t *T) value {+	scheme := SampledFrom(g.schemes).Draw(t, "scheme").(string)+	domain := Domain().Draw(t, "domain").(string)

Good question. If I add those options, should I do so via public IPv4 and IPv6 Generators?

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid_test++import (+	"net/url"+	"regexp"+	"strconv"+	"strings"+	"testing"++	. "pgregory.net/rapid"+)++func TestURL(t *testing.T) {+	pathEscapeRegex := regexp.MustCompile(`^[0-9A-Fa-f]{2}`)

Ack

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid_test++import (+	"fmt"++	"pgregory.net/rapid"+)++func ExampleDomain() {+	gen := rapid.Domain()++	for i := 0; i < 5; i++ {+		fmt.Println(gen.Example(i))+	}++	// Output:+	// MV2zb0-S2j.trAveLcHAnnEL+	// Z.CU+	// r.ABBotT+	// r.AcCoUNTaNT+	// R.+}++func ExampleDomainOf() {+	gen := rapid.DomainOf(6, 5)++	for i := 0; i < 5; i++ {+		fmt.Println(gen.Example(i))+	}++	// Output:+	// Dg5G.+	// Z.CU+	// Bs.+	// AI.HkT+	// R.+}++func ExampleURL() {+	gen := rapid.URL()++	for i := 0; i < 5; i++ {+		fmt.Println(gen.Example(i))

Ack.

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)++	return newGenerator(&domainNameGen{+		maxElementLength: maxElementLength,+		maxLength:        maxLength,+	})+}++type urlGenerator struct {+	schemes []string+}++func (g *urlGenerator) String() string {+	return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)+}++func (g *urlGenerator) type_() reflect.Type {+	return reflect.TypeOf(url.URL{})

Ack

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)++	return newGenerator(&domainNameGen{+		maxElementLength: maxElementLength,+		maxLength:        maxLength,+	})+}++type urlGenerator struct {+	schemes []string+}++func (g *urlGenerator) String() string {+	return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)

Okay, I thought it was supposed to match the name of the private struct. I'll fix that.

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)

Ack

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import "strings"++// sourced from https://data.iana.org/TLD/tlds-alpha-by-domain.txt+// Version 2020103100, Last Updated Sat Oct 31 07:07:01 2020 UTC

This seems beyond what hypothesis is doing, but I also don't know how frequently they update the tlds list.

Is that an explicit guarantee of the API, that the generation for a given seed will never change?

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))

Ack

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain

If it's in the spec, then we probably should, but I don't really grasp what " " as a domain even means. Guess I'll go back and re-read the spec.

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())

This was me cargo-culting from another implementation that used a repeat. I'll clean it up.

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)

Ack.

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import (+	"fmt"+	"net/url"+	"path"+	"reflect"+	"strings"+	"unicode"+)++type domainNameGen struct {+	maxLength        int+	maxElementLength int+}++func (g *domainNameGen) String() string {+	return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)+}++func (g *domainNameGen) type_() reflect.Type {+	return stringType+}++func (g *domainNameGen) value(t *T) value {+	domain := SampledFrom(tlds).+		Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).+		Map(func(s string) string {+			var n string+			for _, ch := range s {+				n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))+			}++			return n+		}).Draw(t, "domain").(string)++	var b strings.Builder+	elements := newRepeat(1, 126, 1)+	b.Grow(elements.avg())++	var expr string+	switch g.maxElementLength {+	case 1:+		expr = `[a-zA-Z]`+	case 2:+		expr = `[a-zA-Z][a-zA-Z0-9]?`+	default:+		expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)+	}+	for elements.more(t.s, g.String()) {+		subDomain := StringMatching(expr).Draw(t, "subdomain").(string)+		if len(domain)+len(subDomain) >= g.maxLength {+			break+		}+		domain = subDomain + "." + domain+	}++	return domain+}++// Domain generates an RFC 1035 compliant domain name.+func Domain() *Generator {+	return DomainOf(255, 63)+}++// DomainOf generates an RFC 1035 compliant domain name,+// with a maximum overall length of maxLength+// and a maximum number of elements of maxElements.+func DomainOf(maxLength, maxElementLength int) *Generator {+	assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)+	assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)+	assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)+	assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)

Will do

wfscheper

comment created time in 19 days

Pull request review commentflyingmutant/rapid

Add generators for URLs and domain names

+// Copyright 2020 Walter Scheper <walter.scheper@gmail.com>+//+// 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+// file, You can obtain one at https://mozilla.org/MPL/2.0/.++package rapid++import "strings"++// sourced from https://data.iana.org/TLD/tlds-alpha-by-domain.txt+// Version 2020103100, Last Updated Sat Oct 31 07:07:01 2020 UTC+const tldsByAlpha = `+AAA+AARP+ABARTH+ABB+ABBOTT+ABBVIE+ABC+ABLE+ABOGADO+ABUDHABI+AC+ACADEMY+ACCENTURE+ACCOUNTANT+ACCOUNTANTS+ACO+ACTOR+AD+ADAC+ADS+ADULT+AE+AEG+AERO+AETNA+AF+AFAMILYCOMPANY+AFL+AFRICA+AG+AGAKHAN+AGENCY+AI+AIG+AIRBUS+AIRFORCE+AIRTEL+AKDN+AL+ALFAROMEO+ALIBABA+ALIPAY+ALLFINANZ+ALLSTATE+ALLY+ALSACE+ALSTOM+AM+AMAZON+AMERICANEXPRESS+AMERICANFAMILY+AMEX+AMFAM+AMICA+AMSTERDAM+ANALYTICS+ANDROID+ANQUAN+ANZ+AO+AOL+APARTMENTS+APP+APPLE+AQ+AQUARELLE+AR+ARAB+ARAMCO+ARCHI+ARMY+ARPA+ART+ARTE+AS+ASDA+ASIA+ASSOCIATES+AT+ATHLETA+ATTORNEY+AU+AUCTION+AUDI+AUDIBLE+AUDIO+AUSPOST+AUTHOR+AUTO+AUTOS+AVIANCA+AW+AWS+AX+AXA+AZ+AZURE+BA+BABY+BAIDU+BANAMEX+BANANAREPUBLIC+BAND+BANK+BAR+BARCELONA+BARCLAYCARD+BARCLAYS+BAREFOOT+BARGAINS+BASEBALL+BASKETBALL+BAUHAUS+BAYERN+BB+BBC+BBT+BBVA+BCG+BCN+BD+BE+BEATS+BEAUTY+BEER+BENTLEY+BERLIN+BEST+BESTBUY+BET+BF+BG+BH+BHARTI+BI+BIBLE+BID+BIKE+BING+BINGO+BIO+BIZ+BJ+BLACK+BLACKFRIDAY+BLOCKBUSTER+BLOG+BLOOMBERG+BLUE+BM+BMS+BMW+BN+BNPPARIBAS+BO+BOATS+BOEHRINGER+BOFA+BOM+BOND+BOO+BOOK+BOOKING+BOSCH+BOSTIK+BOSTON+BOT+BOUTIQUE+BOX+BR+BRADESCO+BRIDGESTONE+BROADWAY+BROKER+BROTHER+BRUSSELS+BS+BT+BUDAPEST+BUGATTI+BUILD+BUILDERS+BUSINESS+BUY+BUZZ+BV+BW+BY+BZ+BZH+CA+CAB+CAFE+CAL+CALL+CALVINKLEIN+CAM+CAMERA+CAMP+CANCERRESEARCH+CANON+CAPETOWN+CAPITAL+CAPITALONE+CAR+CARAVAN+CARDS+CARE+CAREER+CAREERS+CARS+CASA+CASE+CASEIH+CASH+CASINO+CAT+CATERING+CATHOLIC+CBA+CBN+CBRE+CBS+CC+CD+CEB+CENTER+CEO+CERN+CF+CFA+CFD+CG+CH+CHANEL+CHANNEL+CHARITY+CHASE+CHAT+CHEAP+CHINTAI+CHRISTMAS+CHROME+CHURCH+CI+CIPRIANI+CIRCLE+CISCO+CITADEL+CITI+CITIC+CITY+CITYEATS+CK+CL+CLAIMS+CLEANING+CLICK+CLINIC+CLINIQUE+CLOTHING+CLOUD+CLUB+CLUBMED+CM+CN+CO+COACH+CODES+COFFEE+COLLEGE+COLOGNE+COM+COMCAST+COMMBANK+COMMUNITY+COMPANY+COMPARE+COMPUTER+COMSEC+CONDOS+CONSTRUCTION+CONSULTING+CONTACT+CONTRACTORS+COOKING+COOKINGCHANNEL+COOL+COOP+CORSICA+COUNTRY+COUPON+COUPONS+COURSES+CPA+CR+CREDIT+CREDITCARD+CREDITUNION+CRICKET+CROWN+CRS+CRUISE+CRUISES+CSC+CU+CUISINELLA+CV+CW+CX+CY+CYMRU+CYOU+CZ+DABUR+DAD+DANCE+DATA+DATE+DATING+DATSUN+DAY+DCLK+DDS+DE+DEAL+DEALER+DEALS+DEGREE+DELIVERY+DELL+DELOITTE+DELTA+DEMOCRAT+DENTAL+DENTIST+DESI+DESIGN+DEV+DHL+DIAMONDS+DIET+DIGITAL+DIRECT+DIRECTORY+DISCOUNT+DISCOVER+DISH+DIY+DJ+DK+DM+DNP+DO+DOCS+DOCTOR+DOG+DOMAINS+DOT+DOWNLOAD+DRIVE+DTV+DUBAI+DUCK+DUNLOP+DUPONT+DURBAN+DVAG+DVR+DZ+EARTH+EAT+EC+ECO+EDEKA+EDU+EDUCATION+EE+EG+EMAIL+EMERCK+ENERGY+ENGINEER+ENGINEERING+ENTERPRISES+EPSON+EQUIPMENT+ER+ERICSSON+ERNI+ES+ESQ+ESTATE+ET+ETISALAT+EU+EUROVISION+EUS+EVENTS+EXCHANGE+EXPERT+EXPOSED+EXPRESS+EXTRASPACE+FAGE+FAIL+FAIRWINDS+FAITH+FAMILY+FAN+FANS+FARM+FARMERS+FASHION+FAST+FEDEX+FEEDBACK+FERRARI+FERRERO+FI+FIAT+FIDELITY+FIDO+FILM+FINAL+FINANCE+FINANCIAL+FIRE+FIRESTONE+FIRMDALE+FISH+FISHING+FIT+FITNESS+FJ+FK+FLICKR+FLIGHTS+FLIR+FLORIST+FLOWERS+FLY+FM+FO+FOO+FOOD+FOODNETWORK+FOOTBALL+FORD+FOREX+FORSALE+FORUM+FOUNDATION+FOX+FR+FREE+FRESENIUS+FRL+FROGANS+FRONTDOOR+FRONTIER+FTR+FUJITSU+FUJIXEROX+FUN+FUND+FURNITURE+FUTBOL+FYI+GA+GAL+GALLERY+GALLO+GALLUP+GAME+GAMES+GAP+GARDEN+GAY+GB+GBIZ+GD+GDN+GE+GEA+GENT+GENTING+GEORGE+GF+GG+GGEE+GH+GI+GIFT+GIFTS+GIVES+GIVING+GL+GLADE+GLASS+GLE+GLOBAL+GLOBO+GM+GMAIL+GMBH+GMO+GMX+GN+GODADDY+GOLD+GOLDPOINT+GOLF+GOO+GOODYEAR+GOOG+GOOGLE+GOP+GOT+GOV+GP+GQ+GR+GRAINGER+GRAPHICS+GRATIS+GREEN+GRIPE+GROCERY+GROUP+GS+GT+GU+GUARDIAN+GUCCI+GUGE+GUIDE+GUITARS+GURU+GW+GY+HAIR+HAMBURG+HANGOUT+HAUS+HBO+HDFC+HDFCBANK+HEALTH+HEALTHCARE+HELP+HELSINKI+HERE+HERMES+HGTV+HIPHOP+HISAMITSU+HITACHI+HIV+HK+HKT+HM+HN+HOCKEY+HOLDINGS+HOLIDAY+HOMEDEPOT+HOMEGOODS+HOMES+HOMESENSE+HONDA+HORSE+HOSPITAL+HOST+HOSTING+HOT+HOTELES+HOTELS+HOTMAIL+HOUSE+HOW+HR+HSBC+HT+HU+HUGHES+HYATT+HYUNDAI+IBM+ICBC+ICE+ICU+ID+IE+IEEE+IFM+IKANO+IL+IM+IMAMAT+IMDB+IMMO+IMMOBILIEN+IN+INC+INDUSTRIES+INFINITI+INFO+ING+INK+INSTITUTE+INSURANCE+INSURE+INT+INTERNATIONAL+INTUIT+INVESTMENTS+IO+IPIRANGA+IQ+IR+IRISH+IS+ISMAILI+IST+ISTANBUL+IT+ITAU+ITV+IVECO+JAGUAR+JAVA+JCB+JCP+JE+JEEP+JETZT+JEWELRY+JIO+JLL+JM+JMP+JNJ+JO+JOBS+JOBURG+JOT+JOY+JP+JPMORGAN+JPRS+JUEGOS+JUNIPER+KAUFEN+KDDI+KE+KERRYHOTELS+KERRYLOGISTICS+KERRYPROPERTIES+KFH+KG+KH+KI+KIA+KIM+KINDER+KINDLE+KITCHEN+KIWI+KM+KN+KOELN+KOMATSU+KOSHER+KP+KPMG+KPN+KR+KRD+KRED+KUOKGROUP+KW+KY+KYOTO+KZ+LA+LACAIXA+LAMBORGHINI+LAMER+LANCASTER+LANCIA+LAND+LANDROVER+LANXESS+LASALLE+LAT+LATINO+LATROBE+LAW+LAWYER+LB+LC+LDS+LEASE+LECLERC+LEFRAK+LEGAL+LEGO+LEXUS+LGBT+LI+LIDL+LIFE+LIFEINSURANCE+LIFESTYLE+LIGHTING+LIKE+LILLY+LIMITED+LIMO+LINCOLN+LINDE+LINK+LIPSY+LIVE+LIVING+LIXIL+LK+LLC+LLP+LOAN+LOANS+LOCKER+LOCUS+LOFT+LOL+LONDON+LOTTE+LOTTO+LOVE+LPL+LPLFINANCIAL+LR+LS+LT+LTD+LTDA+LU+LUNDBECK+LUPIN+LUXE+LUXURY+LV+LY+MA+MACYS+MADRID+MAIF+MAISON+MAKEUP+MAN+MANAGEMENT+MANGO+MAP+MARKET+MARKETING+MARKETS+MARRIOTT+MARSHALLS+MASERATI+MATTEL+MBA+MC+MCKINSEY+MD+ME+MED+MEDIA+MEET+MELBOURNE+MEME+MEMORIAL+MEN+MENU+MERCKMSD+MG+MH+MIAMI+MICROSOFT+MIL+MINI+MINT+MIT+MITSUBISHI+MK+ML+MLB+MLS+MM+MMA+MN+MO+MOBI+MOBILE+MODA+MOE+MOI+MOM+MONASH+MONEY+MONSTER+MORMON+MORTGAGE+MOSCOW+MOTO+MOTORCYCLES+MOV+MOVIE+MP+MQ+MR+MS+MSD+MT+MTN+MTR+MU+MUSEUM+MUTUAL+MV+MW+MX+MY+MZ+NA+NAB+NAGOYA+NAME+NATIONWIDE+NATURA+NAVY+NBA+NC+NE+NEC+NET+NETBANK+NETFLIX+NETWORK+NEUSTAR+NEW+NEWHOLLAND+NEWS+NEXT+NEXTDIRECT+NEXUS+NF+NFL+NG+NGO+NHK+NI+NICO+NIKE+NIKON+NINJA+NISSAN+NISSAY+NL+NO+NOKIA+NORTHWESTERNMUTUAL+NORTON+NOW+NOWRUZ+NOWTV+NP+NR+NRA+NRW+NTT+NU+NYC+NZ+OBI+OBSERVER+OFF+OFFICE+OKINAWA+OLAYAN+OLAYANGROUP+OLDNAVY+OLLO+OM+OMEGA+ONE+ONG+ONL+ONLINE+ONYOURSIDE+OOO+OPEN+ORACLE+ORANGE+ORG+ORGANIC+ORIGINS+OSAKA+OTSUKA+OTT+OVH+PA+PAGE+PANASONIC+PARIS+PARS+PARTNERS+PARTS+PARTY+PASSAGENS+PAY+PCCW+PE+PET+PF+PFIZER+PG+PH+PHARMACY+PHD+PHILIPS+PHONE+PHOTO+PHOTOGRAPHY+PHOTOS+PHYSIO+PICS+PICTET+PICTURES+PID+PIN+PING+PINK+PIONEER+PIZZA+PK+PL+PLACE+PLAY+PLAYSTATION+PLUMBING+PLUS+PM+PN+PNC+POHL+POKER+POLITIE+PORN+POST+PR+PRAMERICA+PRAXI+PRESS+PRIME+PRO+PROD+PRODUCTIONS+PROF+PROGRESSIVE+PROMO+PROPERTIES+PROPERTY+PROTECTION+PRU+PRUDENTIAL+PS+PT+PUB+PW+PWC+PY+QA+QPON+QUEBEC+QUEST+QVC+RACING+RADIO+RAID+RE+READ+REALESTATE+REALTOR+REALTY+RECIPES+RED+REDSTONE+REDUMBRELLA+REHAB+REISE+REISEN+REIT+RELIANCE+REN+RENT+RENTALS+REPAIR+REPORT+REPUBLICAN+REST+RESTAURANT+REVIEW+REVIEWS+REXROTH+RICH+RICHARDLI+RICOH+RIL+RIO+RIP+RMIT+RO+ROCHER+ROCKS+RODEO+ROGERS+ROOM+RS+RSVP+RU+RUGBY+RUHR+RUN+RW+RWE+RYUKYU+SA+SAARLAND+SAFE+SAFETY+SAKURA+SALE+SALON+SAMSCLUB+SAMSUNG+SANDVIK+SANDVIKCOROMANT+SANOFI+SAP+SARL+SAS+SAVE+SAXO+SB+SBI+SBS+SC+SCA+SCB+SCHAEFFLER+SCHMIDT+SCHOLARSHIPS+SCHOOL+SCHULE+SCHWARZ+SCIENCE+SCJOHNSON+SCOT+SD+SE+SEARCH+SEAT+SECURE+SECURITY+SEEK+SELECT+SENER+SERVICES+SES+SEVEN+SEW+SEX+SEXY+SFR+SG+SH+SHANGRILA+SHARP+SHAW+SHELL+SHIA+SHIKSHA+SHOES+SHOP+SHOPPING+SHOUJI+SHOW+SHOWTIME+SHRIRAM+SI+SILK+SINA+SINGLES+SITE+SJ+SK+SKI+SKIN+SKY+SKYPE+SL+SLING+SM+SMART+SMILE+SN+SNCF+SO+SOCCER+SOCIAL+SOFTBANK+SOFTWARE+SOHU+SOLAR+SOLUTIONS+SONG+SONY+SOY+SPA+SPACE+SPORT+SPOT+SPREADBETTING+SR+SRL+SS+ST+STADA+STAPLES+STAR+STATEBANK+STATEFARM+STC+STCGROUP+STOCKHOLM+STORAGE+STORE+STREAM+STUDIO+STUDY+STYLE+SU+SUCKS+SUPPLIES+SUPPLY+SUPPORT+SURF+SURGERY+SUZUKI+SV+SWATCH+SWIFTCOVER+SWISS+SX+SY+SYDNEY+SYSTEMS+SZ+TAB+TAIPEI+TALK+TAOBAO+TARGET+TATAMOTORS+TATAR+TATTOO+TAX+TAXI+TC+TCI+TD+TDK+TEAM+TECH+TECHNOLOGY+TEL+TEMASEK+TENNIS+TEVA+TF+TG+TH+THD+THEATER+THEATRE+TIAA+TICKETS+TIENDA+TIFFANY+TIPS+TIRES+TIROL+TJ+TJMAXX+TJX+TK+TKMAXX+TL+TM+TMALL+TN+TO+TODAY+TOKYO+TOOLS+TOP+TORAY+TOSHIBA+TOTAL+TOURS+TOWN+TOYOTA+TOYS+TR+TRADE+TRADING+TRAINING+TRAVEL+TRAVELCHANNEL+TRAVELERS+TRAVELERSINSURANCE+TRUST+TRV+TT+TUBE+TUI+TUNES+TUSHU+TV+TVS+TW+TZ+UA+UBANK+UBS+UG+UK+UNICOM+UNIVERSITY+UNO+UOL+UPS+US+UY+UZ+VA+VACATIONS+VANA+VANGUARD+VC+VE+VEGAS+VENTURES+VERISIGN+VERSICHERUNG+VET+VG+VI+VIAJES+VIDEO+VIG+VIKING+VILLAS+VIN+VIP+VIRGIN+VISA+VISION+VIVA+VIVO+VLAANDEREN+VN+VODKA+VOLKSWAGEN+VOLVO+VOTE+VOTING+VOTO+VOYAGE+VU+VUELOS+WALES+WALMART+WALTER+WANG+WANGGOU+WATCH+WATCHES+WEATHER+WEATHERCHANNEL+WEBCAM+WEBER+WEBSITE+WED+WEDDING+WEIBO+WEIR+WF+WHOSWHO+WIEN+WIKI+WILLIAMHILL+WIN+WINDOWS+WINE+WINNERS+WME+WOLTERSKLUWER+WOODSIDE+WORK+WORKS+WORLD+WOW+WS+WTC+WTF+XBOX+XEROX+XFINITY+XIHUAN+XIN+XN--11B4C3D+XN--1CK2E1B+XN--1QQW23A+XN--2SCRJ9C+XN--30RR7Y+XN--3BST00M+XN--3DS443G+XN--3E0B707E+XN--3HCRJ9C+XN--3OQ18VL8PN36A+XN--3PXU8K+XN--42C2D9A+XN--45BR5CYL+XN--45BRJ9C+XN--45Q11C+XN--4GBRIM+XN--54B7FTA0CC+XN--55QW42G+XN--55QX5D+XN--5SU34J936BGSG+XN--5TZM5G+XN--6FRZ82G+XN--6QQ986B3XL+XN--80ADXHKS+XN--80AO21A+XN--80AQECDR1A+XN--80ASEHDB+XN--80ASWG+XN--8Y0A063A+XN--90A3AC+XN--90AE+XN--90AIS+XN--9DBQ2A+XN--9ET52U+XN--9KRT00A+XN--B4W605FERD+XN--BCK1B9A5DRE4C+XN--C1AVG+XN--C2BR7G+XN--CCK2B3B+XN--CCKWCXETD+XN--CG4BKI+XN--CLCHC0EA0B2G2A9GCD+XN--CZR694B+XN--CZRS0T+XN--CZRU2D+XN--D1ACJ3B+XN--D1ALF+XN--E1A4C+XN--ECKVDTC9D+XN--EFVY88H+XN--FCT429K+XN--FHBEI+XN--FIQ228C5HS+XN--FIQ64B+XN--FIQS8S+XN--FIQZ9S+XN--FJQ720A+XN--FLW351E+XN--FPCRJ9C3D+XN--FZC2C9E2C+XN--FZYS8D69UVGM+XN--G2XX48C+XN--GCKR3F0F+XN--GECRJ9C+XN--GK3AT1E+XN--H2BREG3EVE+XN--H2BRJ9C+XN--H2BRJ9C8C+XN--HXT814E+XN--I1B6B1A6A2E+XN--IMR513N+XN--IO0A7I+XN--J1AEF+XN--J1AMH+XN--J6W193G+XN--JLQ480N2RG+XN--JLQ61U9W7B+XN--JVR189M+XN--KCRX77D1X4A+XN--KPRW13D+XN--KPRY57D+XN--KPUT3I+XN--L1ACC+XN--LGBBAT1AD8J+XN--MGB9AWBF+XN--MGBA3A3EJT+XN--MGBA3A4F16A+XN--MGBA7C0BBN0A+XN--MGBAAKC7DVF+XN--MGBAAM7A8H+XN--MGBAB2BD+XN--MGBAH1A3HJKRD+XN--MGBAI9AZGQP6J+XN--MGBAYH7GPA+XN--MGBBH1A+XN--MGBBH1A71E+XN--MGBC0A9AZCG+XN--MGBCA7DZDO+XN--MGBCPQ6GPA1A+XN--MGBERP4A5D4AR+XN--MGBGU82A+XN--MGBI4ECEXP+XN--MGBPL2FH+XN--MGBT3DHD+XN--MGBTX2B+XN--MGBX4CD0AB+XN--MIX891F+XN--MK1BU44C+XN--MXTQ1M+XN--NGBC5AZD+XN--NGBE9E0A+XN--NGBRX+XN--NODE+XN--NQV7F+XN--NQV7FS00EMA+XN--NYQY26A+XN--O3CW4H+XN--OGBPF8FL+XN--OTU796D+XN--P1ACF+XN--P1AI+XN--PGBS0DH+XN--PSSY2U+XN--Q7CE6A+XN--Q9JYB4C+XN--QCKA1PMC+XN--QXA6A+XN--QXAM+XN--RHQV96G+XN--ROVU88B+XN--RVC1E0AM3E+XN--S9BRJ9C+XN--SES554G+XN--T60B56A+XN--TCKWE+XN--TIQ49XQYJ+XN--UNUP4Y+XN--VERMGENSBERATER-CTB+XN--VERMGENSBERATUNG-PWB+XN--VHQUV+XN--VUQ861B+XN--W4R85EL8FHU5DNRA+XN--W4RS40L+XN--WGBH1C+XN--WGBL6A+XN--XHQ521B+XN--XKC2AL3HYE2A+XN--XKC2DL3A5EE0H+XN--Y9A3AQ+XN--YFRO4I67O+XN--YGBI2AMMX+XN--ZFR164B+XXX+XYZ+YACHTS+YAHOO+YAMAXUN+YANDEX+YE+YODOBASHI+YOGA+YOKOHAMA+YOU+YOUTUBE+YT+YUN+ZA+ZAPPOS+ZARA+ZERO+ZIP+ZM+ZONE+ZUERICH+ZW+`++var tlds = strings.Split(tldsByAlpha, "\n")

Good catch, no I need to runtldsByAlpha through TrimSpace.

wfscheper

comment created time in 19 days

startedflyingmutant/rapid

started time in 22 days

startedflyingmutant/rapid

started time in 22 days

startedflyingmutant/rapid

started time in 25 days

more