Skip to content

Commit 057c90e

Browse files
committed
Simplify domain generation
This removes the configurable domain generation in favor of one that generates domains within the full rnage allowed by the specification.
1 parent 116ac3a commit 057c90e

File tree

3 files changed

+56
-94
lines changed

3 files changed

+56
-94
lines changed

url.go

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,51 +11,49 @@ import (
1111
"net/url"
1212
"path"
1313
"reflect"
14-
"strings"
1514
"unicode"
1615
)
1716

18-
type domainNameGen struct {
19-
maxLength int
20-
maxElementLength int
21-
}
17+
const (
18+
domainMaxLength = 255
19+
domainMaxElementLength = 63
20+
)
21+
22+
var (
23+
domainType = reflect.TypeOf("")
24+
urlType = reflect.TypeOf(url.URL{})
25+
)
26+
27+
type domainNameGen struct{}
2228

23-
func (g *domainNameGen) String() string {
24-
return fmt.Sprintf("Domain(maxLength=%v, mmaxElementLength%v)", g.maxLength, g.maxElementLength)
29+
func (*domainNameGen) String() string {
30+
return "Domain()"
2531
}
2632

27-
func (g *domainNameGen) type_() reflect.Type {
28-
return stringType
33+
func (*domainNameGen) type_() reflect.Type {
34+
return domainType
2935
}
3036

37+
var tldGenerator = SampledFrom(tlds)
38+
3139
func (g *domainNameGen) value(t *T) value {
32-
domain := SampledFrom(tlds).
33-
Filter(func(s string) bool { return len(s)+2 <= g.maxLength }).
40+
domain := tldGenerator.
41+
Filter(func(s string) bool { return len(s)+2 <= domainMaxLength }).
3442
Map(func(s string) string {
3543
var n string
3644
for _, ch := range s {
37-
n += string(SampledFrom([]rune{unicode.ToUpper(ch), unicode.ToLower(ch)}).Draw(t, "").(rune))
45+
n += string(SampledFrom([]rune{unicode.ToLower(ch), unicode.ToUpper(ch)}).Draw(t, "").(rune))
3846
}
3947

4048
return n
41-
}).Draw(t, "domain").(string)
49+
}).
50+
Draw(t, "domain").(string)
4251

43-
var b strings.Builder
52+
expr := fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, domainMaxElementLength-2)
4453
elements := newRepeat(1, 126, 1)
45-
b.Grow(elements.avg())
46-
47-
var expr string
48-
switch g.maxElementLength {
49-
case 1:
50-
expr = `[a-zA-Z]`
51-
case 2:
52-
expr = `[a-zA-Z][a-zA-Z0-9]?`
53-
default:
54-
expr = fmt.Sprintf(`[a-zA-Z]([a-zA-Z0-9\-]{0,%d}[a-zA-Z0-9])?`, g.maxElementLength-2)
55-
}
5654
for elements.more(t.s, g.String()) {
5755
subDomain := StringMatching(expr).Draw(t, "subdomain").(string)
58-
if len(domain)+len(subDomain) >= g.maxLength {
56+
if len(domain)+len(subDomain) >= domainMaxLength {
5957
break
6058
}
6159
domain = subDomain + "." + domain
@@ -66,34 +64,19 @@ func (g *domainNameGen) value(t *T) value {
6664

6765
// Domain generates an RFC 1035 compliant domain name.
6866
func Domain() *Generator {
69-
return DomainOf(255, 63)
70-
}
71-
72-
// DomainOf generates an RFC 1035 compliant domain name,
73-
// with a maximum overall length of maxLength
74-
// and a maximum number of elements of maxElements.
75-
func DomainOf(maxLength, maxElementLength int) *Generator {
76-
assertf(4 <= maxLength, "maximum length (%v) should not be less than 4, to generate a two character domain and a one character subdomain", maxLength)
77-
assertf(maxLength <= 255, "maximum length (%v) should not be greater than 255 to comply with RFC 1035", maxLength)
78-
assertf(1 <= maxElementLength, "maximum element length (%v) should not be less than 1 to comply with RFC 1035", maxElementLength)
79-
assertf(maxElementLength <= 63, "maximum element length (%v) should not be greater than 63 to comply with RFC 1035", maxElementLength)
80-
81-
return newGenerator(&domainNameGen{
82-
maxElementLength: maxElementLength,
83-
maxLength: maxLength,
84-
})
67+
return newGenerator(&domainNameGen{})
8568
}
8669

8770
type urlGenerator struct {
8871
schemes []string
8972
}
9073

9174
func (g *urlGenerator) String() string {
92-
return fmt.Sprintf("URLGenerator(schemes=%v)", g.schemes)
75+
return "URL()"
9376
}
9477

9578
func (g *urlGenerator) type_() reflect.Type {
96-
return reflect.TypeOf(url.URL{})
79+
return urlType
9780
}
9881

9982
func (g *urlGenerator) value(t *T) value {

url_example_test.go

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package rapid_test
88

99
import (
1010
"fmt"
11+
"net/url"
1112

1213
"pgregory.net/rapid"
1314
)
@@ -20,39 +21,25 @@ func ExampleDomain() {
2021
}
2122

2223
// Output:
23-
// MV2zb0-S2j.trAveLcHAnnEL
24-
// Z.CU
25-
// r.ABBotT
26-
// r.AcCoUNTaNT
27-
// R.
28-
}
29-
30-
func ExampleDomainOf() {
31-
gen := rapid.DomainOf(6, 5)
32-
33-
for i := 0; i < 5; i++ {
34-
fmt.Println(gen.Example(i))
35-
}
36-
37-
// Output:
38-
// Dg5G.
39-
// Z.CU
40-
// Bs.
41-
// AI.HkT
42-
// R.
24+
// D1C.TRaVElErs
25+
// C.cuISiNeLlA
26+
// r.abbVIe
27+
// MC0zJ.aCcOuntAnTs
28+
// T6hFdv10.aaa
4329
}
4430

4531
func ExampleURL() {
4632
gen := rapid.URL()
4733

4834
for i := 0; i < 5; i++ {
49-
fmt.Println(gen.Example(i))
35+
e := gen.Example(i).(url.URL)
36+
fmt.Println(e.String())
5037
}
5138

5239
// Output:
53-
// {https U.aaA:4 V0%E2%90%9A%226%E0%BC%B0%F0%91%82%B0%F0%97%B3%80%F0%92%91%ADX/1=%22 false }
54-
// {http C.AarP:11 1%EF%BD%9F/%F0%9F%AA%95%22%D6%93%E0%A9%AD%E1%B3%930%D0%8A/%C2%BC%E0%B4%BE3%F0%9E%8B%B0%F0%91%86%BD%C2%B2%E0%B3%A9%CC%80D/%7C+%F0%9F%81%9D+%5D%CC%81%CB%85/%CC%80/%E1%B0%BF/%CD%82K%E0%A5%A9%CC%81 false }
55-
// {https Bs.:11 false }
56-
// {http MC0zJ.aCcOUNtAnT:2 J%E2%9D%87 false }
57-
// {http t.Xn--RvC1e0am3E:3 %CC%82/%E2%80%A60%CC%80%C3%B7/%CC%81%CC%A2%21%E0%AF%AB%CC%81%C3%A4/%F0%9F%AA%95%EA%99%B4%CC%80%E0%A5%AD/%F0%AD%B9%A9%F0%91%87%AE/%E1%B7%93%CC%8B%E2%87%94%E2%90%8E%EA%A3%A5%E0%B5%9A=%E5%8E%A4%D9%AAB%F0%A5%8F%9A=%C2%A4%C3%AE%F0%91%84%AD%DC%8A%21%E2%82%8D3/%E1%81%8F%23 false }
40+
// https://r125pz05Rz-0j1d-11.AArP:17
41+
// http://L2.aBArTh:7/%25F0%259F%25AA%2595%2522%25D6%2593%25E0%25A9%25AD%25E1%25B3%25930%25D0%258A/%25C2%25BC%25E0%25B4%25BE3%25F0%259E%258B%25B0%25F0%2591%2586%25BD%25C2%25B2%25E0%25B3%25A9%25CC%2580D/%257C+%25F0%259F%2581%259D+%255D%25CC%2581%25CB%2585/%25CC%2580/%25E1%25B0%25BF/%25CD%2582K%25E0%25A5%25A9%25CC%2581
42+
// https://pH20DR11.aaA
43+
// http://h.AcCounTaNtS:4/%25F0%259E%25A5%259F/:%2521J%25E2%259D%2587
44+
// http://A.xN--s9bRJ9C:2
5845
}

url_external_test.go

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ package rapid_test
99
import (
1010
"net/url"
1111
"regexp"
12-
"strconv"
1312
"strings"
1413
"testing"
1514

1615
. "pgregory.net/rapid"
1716
)
1817

18+
var pathEscapeRegex = regexp.MustCompile(`^[0-9A-Fa-f]{2}`)
19+
1920
func TestURL(t *testing.T) {
20-
pathEscapeRegex := regexp.MustCompile(`^[0-9A-Fa-f]{2}`)
21+
t.Parallel()
2122

2223
Check(t, func(t *T) {
2324
u := URL().Draw(t, "url").(url.URL)
@@ -43,31 +44,22 @@ func TestURL(t *testing.T) {
4344
})
4445
}
4546

46-
func TestDomainOf(t *testing.T) {
47+
func TestDomain(t *testing.T) {
4748
t.Parallel()
4849

49-
genFuncs := []func(int, int) *Generator{
50-
func(i, j int) *Generator { return DomainOf(i, j) },
51-
}
52-
53-
for i, gf := range genFuncs {
54-
t.Run(strconv.Itoa(i), MakeCheck(func(t *T) {
55-
maxLength := IntRange(4, 255).Draw(t, "maxLength").(int)
56-
maxElementLength := IntRange(1, 63).Draw(t, "maxElementLength").(int)
57-
58-
d := gf(maxLength, maxElementLength).Draw(t, "d").(string)
59-
if got, want := len(d), maxLength; got > want {
60-
t.Errorf("got domain of length %d with maxLenght of %d", got, want)
61-
}
50+
Check(t, func(t *T) {
51+
d := Domain().Draw(t, "d").(string)
52+
if got, want := len(d), 255; got > want {
53+
t.Errorf("got domain of length %d with maxLenght of %d", got, want)
54+
}
6255

63-
elements := strings.Split(d, ".")
56+
elements := strings.Split(d, ".")
6457

65-
// ignore the tld
66-
for i, elem := range elements[:len(elements)-1] {
67-
if got, want := len(elem), maxElementLength; got > want {
68-
t.Errorf("got domain element %d of length %d with maxElementLength %d", i, got, want)
69-
}
58+
// ignore the tld
59+
for i, elem := range elements[:len(elements)-1] {
60+
if got, want := len(elem), 63; got > want {
61+
t.Errorf("got domain element %d of length %d with maxElementLength %d", i, got, want)
7062
}
71-
}))
72-
}
63+
}
64+
})
7365
}

0 commit comments

Comments
 (0)