Example #1
0
// TestAlloc tests that some mapping methods should not cause any allocation.
func TestAlloc(t *testing.T) {
	dst := make([]byte, 256) // big enough to hold any result
	src := []byte(txtNonASCII)

	for i, f := range []func() Caser{
		func() Caser { return Upper(language.Und) },
		func() Caser { return Lower(language.Und) },
		func() Caser { return Title(language.Und) },
	} {
		var c Caser
		v := testtext.AllocsPerRun(2, func() {
			c = f()
		})
		if v > 1 {
			// TODO: Right now only Upper has 1 allocation. Special-case Lower
			// and Title as well to have less allocations for the root locale.
			t.Skipf("%d:init: number of allocs was %f; want 0", i, v)
		}
		v = testtext.AllocsPerRun(2, func() {
			c.Transform(dst, src, true)
		})
		if v > 0 {
			t.Errorf("%d:transform: number of allocs was %f; want 0", i, v)
		}
	}
}
Example #2
0
// TestAlloc tests that some mapping methods should not cause any allocation.
func TestAlloc(t *testing.T) {
	dst := make([]byte, 256) // big enough to hold any result
	src := []byte(txtNonASCII)

	for i, f := range []func() Caser{
		func() Caser { return Upper(language.Und) },
		func() Caser { return Lower(language.Und) },
		func() Caser { return Lower(language.Und, HandleFinalSigma(false)) },
		// TODO: use a shared copy for these casers as well, in order of
		// importance, starting with the most important:
		// func() Caser { return Title(language.Und) },
		// func() Caser { return Title(language.Und, HandleFinalSigma(false)) },
	} {
		testtext.Run(t, "", func(t *testing.T) {
			var c Caser
			v := testtext.AllocsPerRun(10, func() {
				c = f()
			})
			if v > 0 {
				// TODO: Right now only Upper has 1 allocation. Special-case Lower
				// and Title as well to have less allocations for the root locale.
				t.Errorf("%d:init: number of allocs was %f; want 0", i, v)
			}
			v = testtext.AllocsPerRun(2, func() {
				c.Transform(dst, src, true)
			})
			if v > 0 {
				t.Errorf("%d:transform: number of allocs was %f; want 0", i, v)
			}
		})
	}
}
Example #3
0
func TestNumericWeighterAlloc(t *testing.T) {
	buf := make([]Elem, 100)
	w := NewNumericWeighter(numWeighter)
	s := "1234567890a"

	nNormal := testtext.AllocsPerRun(3, func() { numWeighter.AppendNextString(buf, s) })
	nNumeric := testtext.AllocsPerRun(3, func() { w.AppendNextString(buf, s) })
	if n := nNumeric - nNormal; n > 0 {
		t.Errorf("got %f; want 0", n)
	}
}
Example #4
0
func TestReplaceIllFormedAlloc(t *testing.T) {
	if n := testtext.AllocsPerRun(3, func() {
		ReplaceIllFormed().Transform(nil, nil, false)
	}); n > 0 {
		t.Errorf("got %f; want 0", n)
	}
}
Example #5
0
func TestRemoveAlloc(t *testing.T) {
	if n := testtext.AllocsPerRun(3, func() {
		Remove(Predicate(rmNop)).Transform(nil, nil, false)
	}); n > 0 {
		t.Errorf("got %f; want 0", n)
	}
}
Example #6
0
func TestMapAlloc(t *testing.T) {
	if n := testtext.AllocsPerRun(3, func() {
		Map(idem).Transform(nil, nil, false)
	}); n > 0 {
		t.Errorf("got %f; want 0", n)
	}
}
Example #7
0
func TestFold(t *testing.T) {
	for _, tc := range foldTestCases {
		testEntry := func(name string, c Caser, m func(r rune) string) {
			want := ""
			for _, r := range tc {
				want += m(r)
			}
			if got := c.String(tc); got != want {
				t.Errorf("%s(%s) = %+q; want %+q", name, tc, got, want)
			}
			dst := make([]byte, 256) // big enough to hold any result
			src := []byte(tc)
			v := testtext.AllocsPerRun(20, func() {
				c.Transform(dst, src, true)
			})
			if v > 0 {
				t.Errorf("%s(%s): number of allocs was %f; want 0", name, tc, v)
			}
		}
		testEntry("FullFold", Fold(), func(r rune) string {
			return runeFoldData(r).full
		})
		// TODO:
		// testEntry("SimpleFold", Fold(Compact), func(r rune) string {
		// 	return runeFoldData(r).simple
		// })
		// testEntry("SpecialFold", Fold(Turkic), func(r rune) string {
		// 	return runeFoldData(r).special
		// })
	}
}
Example #8
0
func TestAppendMallocs(t *testing.T) {
	str := []byte("helloworld")
	out := make([]byte, 0, len(str))
	if n := testtext.AllocsPerRun(100, func() { UsernameCaseMapped.Append(out, str) }); n > 0 {
		t.Errorf("got %f allocs, want 0", n)
	}
}
Example #9
0
func TestMakeString(t *testing.T) {
	tests := []struct{ in, out string }{
		{"und", "und"},
		{"und", "und-CW"},
		{"nl", "nl-NL"},
		{"de-1901", "nl-1901"},
		{"de-1901", "de-Arab-1901"},
		{"x-a-b", "de-Arab-x-a-b"},
		{"x-a-b", "x-a-b"},
	}
	for i, tt := range tests {
		id, _ := Parse(tt.in)
		mod, _ := Parse(tt.out)
		id.setTagsFrom(mod)
		for j := 0; j < 2; j++ {
			id.remakeString()
			if str := id.String(); str != tt.out {
				t.Errorf("%d:%d: found %s; want %s", i, j, id.String(), tt.out)
			}
		}
		// The bytes to string conversion as used in remakeString
		// occasionally measures as more than one alloc, breaking this test.
		// To alleviate this we set the number of runs to more than 1.
		if n := testtext.AllocsPerRun(8, id.remakeString); n > 1 {
			t.Errorf("%d: # allocs got %.1f; want <= 1", i, n)
		}
	}
}
Example #10
0
func TestAllocToASCII(t *testing.T) {
	avg := testtext.AllocsPerRun(1000, func() {
		ToASCII("www.golang.org")
	})
	if avg > 0 {
		t.Errorf("got %f; want 0", avg)
	}
}
Example #11
0
func TestBestMatchAlloc(t *testing.T) {
	m := NewMatcher(parseSupported("en sr nl"))
	// Go allocates when creating a list of tags from a single tag!
	list := []Tag{English}
	avg := testtext.AllocsPerRun(1, func() {
		m.Match(list...)
	})
	if avg > 0 {
		t.Errorf("got %f; want 0", avg)
	}
}
Example #12
0
func TestTransformMallocs(t *testing.T) {
	str := []byte("helloworld")
	out := make([]byte, 0, len(str))
	tr := UsernameCaseMapped.NewTransformer()
	if n := testtext.AllocsPerRun(100, func() {
		tr.Reset()
		tr.Transform(out, str, true)
	}); n > 0 {
		t.Errorf("got %f allocs, want 0", n)
	}
}
Example #13
0
func TestFold(t *testing.T) {
	testCases := []string{
		"βß\u13f8",        // "βssᏰ"
		"ab\u13fc\uab7aꭰ", // abᏴᎪᎠ
		"affifflast",           // affifflast
		"Iİiı\u0345",      // ii̇iıι
		"µµΜΜςσΣΣ",        // μμμμσσσσ
	}
	for _, tc := range testCases {
		testEntry := func(name string, c Caser, m func(r rune) string) {
			want := ""
			for _, r := range tc {
				want += m(r)
			}
			if got := c.String(tc); got != want {
				t.Errorf("%s(%s) = %+q; want %+q", name, tc, got, want)
			}
			dst := make([]byte, 256) // big enough to hold any result
			src := []byte(tc)
			v := testtext.AllocsPerRun(20, func() {
				c.Transform(dst, src, true)
			})
			if v > 0 {
				t.Errorf("%s(%s): number of allocs was %f; want 0", name, tc, v)
			}
		}
		testEntry("FullFold", Fold(), func(r rune) string {
			return runeFoldData(r).full
		})
		// TODO:
		// testEntry("SimpleFold", Fold(Compact), func(r rune) string {
		// 	return runeFoldData(r).simple
		// })
		// testEntry("SpecialFold", Fold(Turkic), func(r rune) string {
		// 	return runeFoldData(r).special
		// })
	}
}
Example #14
0
func TestCaseMappings(t *testing.T) {
	for i, tt := range testCases {
		src, ok := tt.src.([]string)
		if !ok {
			src = strings.Split(tt.src.(string), " ")
		}

		for _, lang := range strings.Split(tt.lang, " ") {
			tag := language.MustParse(lang)
			testEntry := func(name string, mk func(language.Tag, options) transform.Transformer, gold interface{}) {
				c := Caser{mk(tag, tt.opts)}
				if gold != nil {
					wants, ok := gold.([]string)
					if !ok {
						wants = strings.Split(gold.(string), " ")
					}
					for j, want := range wants {
						if got := c.String(src[j]); got != want {
							t.Errorf("%d:%s:\n%s.String(%+q):\ngot  %+q;\nwant %+q", i, lang, name, src[j], got, want)
						}
					}
				}
				dst := make([]byte, 256) // big enough to hold any result
				src := []byte(strings.Join(src, " "))
				v := testtext.AllocsPerRun(20, func() {
					c.Transform(dst, src, true)
				})
				if v > 1.1 {
					t.Errorf("%d:%s:\n%s: number of allocs was %f; want 0", i, lang, name, v)
				}
			}
			testEntry("Upper", makeUpper, tt.upper)
			testEntry("Lower", makeLower, tt.lower)
			testEntry("Title", makeTitle, tt.title)
		}
	}
}
Example #15
0
func TestStringMallocs(t *testing.T) {
	if n := testtext.AllocsPerRun(100, func() { UsernameCaseMapped.String("helloworld") }); n > 0 {
		// TODO: reduce this to 0.
		t.Skipf("got %f allocs, want 0", n)
	}
}
Example #16
0
func TestString(t *testing.T) {
	testtext.Run(t, "transform", func(t *testing.T) { testString(t, String) })

	// Overrun the internal destination buffer.
	for i, s := range []string{
		aaa[:1*initialBufSize-1],
		aaa[:1*initialBufSize+0],
		aaa[:1*initialBufSize+1],
		AAA[:1*initialBufSize-1],
		AAA[:1*initialBufSize+0],
		AAA[:1*initialBufSize+1],
		AAA[:2*initialBufSize-1],
		AAA[:2*initialBufSize+0],
		AAA[:2*initialBufSize+1],
		aaa[:1*initialBufSize-2] + "A",
		aaa[:1*initialBufSize-1] + "A",
		aaa[:1*initialBufSize+0] + "A",
		aaa[:1*initialBufSize+1] + "A",
	} {
		testtext.Run(t, fmt.Sprint("dst buffer test using lower/", i), func(t *testing.T) {
			got, _, _ := String(lowerCaseASCII{}, s)
			if want := strings.ToLower(s); got != want {
				t.Errorf("got %s (%d); want %s (%d)", got, len(got), want, len(want))
			}
		})
	}

	// Overrun the internal source buffer.
	for i, s := range []string{
		aaa[:1*initialBufSize-1],
		aaa[:1*initialBufSize+0],
		aaa[:1*initialBufSize+1],
		aaa[:2*initialBufSize+1],
		aaa[:2*initialBufSize+0],
		aaa[:2*initialBufSize+1],
	} {
		testtext.Run(t, fmt.Sprint("src buffer test using rleEncode/", i), func(t *testing.T) {
			got, _, _ := String(rleEncode{}, s)
			if want := fmt.Sprintf("%da", len(s)); got != want {
				t.Errorf("got %s (%d); want %s (%d)", got, len(got), want, len(want))
			}
		})
	}

	// Test allocations for non-changing strings.
	// Note we still need to allocate a single buffer.
	for i, s := range []string{
		"",
		"123456789",
		aaa[:initialBufSize-1],
		aaa[:initialBufSize+0],
		aaa[:initialBufSize+1],
		aaa[:10*initialBufSize],
	} {
		testtext.Run(t, fmt.Sprint("alloc/", i), func(t *testing.T) {
			if n := testtext.AllocsPerRun(5, func() { String(&lowerCaseASCIILookahead{}, s) }); n > 1 {
				t.Errorf("#allocs was %f; want 1", n)
			}
		})
	}
}