1// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package cldr
6
7import (
8	"reflect"
9	"testing"
10)
11
12type testSlice []*Common
13
14func mkElem(alt, typ, ref string) *Common {
15	return &Common{
16		Type:      typ,
17		Reference: ref,
18		Alt:       alt,
19	}
20}
21
22var (
23	testSlice1 = testSlice{
24		mkElem("1", "a", "i.a"),
25		mkElem("1", "b", "i.b"),
26		mkElem("1", "c", "i.c"),
27		mkElem("2", "b", "ii"),
28		mkElem("3", "c", "iii"),
29		mkElem("4", "a", "iv.a"),
30		mkElem("4", "d", "iv.d"),
31	}
32	testSliceE = testSlice{}
33)
34
35func panics(f func()) (panics bool) {
36	defer func() {
37		if err := recover(); err != nil {
38			panics = true
39		}
40	}()
41	f()
42	return panics
43}
44
45func TestMakeSlice(t *testing.T) {
46	foo := 1
47	bar := []int{}
48	tests := []struct {
49		i      interface{}
50		panics bool
51		err    string
52	}{
53		{&foo, true, "should panic when passed a pointer to the wrong type"},
54		{&bar, true, "should panic when slice element of the wrong type"},
55		{testSlice1, true, "should panic when passed a slice"},
56		{&testSlice1, false, "should not panic"},
57	}
58	for i, tt := range tests {
59		if panics(func() { MakeSlice(tt.i) }) != tt.panics {
60			t.Errorf("%d: %s", i, tt.err)
61		}
62	}
63}
64
65var anyOfTests = []struct {
66	sl     testSlice
67	values []string
68	n      int
69}{
70	{testSliceE, []string{}, 0},
71	{testSliceE, []string{"1", "2", "3"}, 0},
72	{testSlice1, []string{}, 0},
73	{testSlice1, []string{"1"}, 3},
74	{testSlice1, []string{"2"}, 1},
75	{testSlice1, []string{"5"}, 0},
76	{testSlice1, []string{"1", "2", "3"}, 5},
77}
78
79func TestSelectAnyOf(t *testing.T) {
80	for i, tt := range anyOfTests {
81		sl := tt.sl
82		s := MakeSlice(&sl)
83		s.SelectAnyOf("alt", tt.values...)
84		if len(sl) != tt.n {
85			t.Errorf("%d: found len == %d; want %d", i, len(sl), tt.n)
86		}
87	}
88	sl := testSlice1
89	s := MakeSlice(&sl)
90	if !panics(func() { s.SelectAnyOf("foo") }) {
91		t.Errorf("should panic on non-existing attribute")
92	}
93}
94
95func TestFilter(t *testing.T) {
96	for i, tt := range anyOfTests {
97		sl := tt.sl
98		s := MakeSlice(&sl)
99		s.Filter(func(e Elem) bool {
100			v, _ := findField(reflect.ValueOf(e), "alt")
101			return in(tt.values, v.String())
102		})
103		if len(sl) != tt.n {
104			t.Errorf("%d: found len == %d; want %d", i, len(sl), tt.n)
105		}
106	}
107}
108
109func TestGroup(t *testing.T) {
110	f := func(excl ...string) func(Elem) string {
111		return func(e Elem) string {
112			return Key(e, excl...)
113		}
114	}
115	tests := []struct {
116		sl   testSlice
117		f    func(Elem) string
118		lens []int
119	}{
120		{testSliceE, f(), []int{}},
121		{testSlice1, f(), []int{1, 1, 1, 1, 1, 1, 1}},
122		{testSlice1, f("type"), []int{3, 1, 1, 2}},
123		{testSlice1, f("alt"), []int{2, 2, 2, 1}},
124		{testSlice1, f("alt", "type"), []int{7}},
125		{testSlice1, f("alt", "type"), []int{7}},
126	}
127	for i, tt := range tests {
128		sl := tt.sl
129		s := MakeSlice(&sl)
130		g := s.Group(tt.f)
131		if len(tt.lens) != len(g) {
132			t.Errorf("%d: found %d; want %d", i, len(g), len(tt.lens))
133			continue
134		}
135		for j, v := range tt.lens {
136			if n := g[j].Value().Len(); n != v {
137				t.Errorf("%d: found %d for length of group %d; want %d", i, n, j, v)
138			}
139		}
140	}
141}
142
143func TestSelectOnePerGroup(t *testing.T) {
144	tests := []struct {
145		sl     testSlice
146		attr   string
147		values []string
148		refs   []string
149	}{
150		{testSliceE, "alt", []string{"1"}, []string{}},
151		{testSliceE, "type", []string{"a"}, []string{}},
152		{testSlice1, "alt", []string{"2", "3", "1"}, []string{"i.a", "ii", "iii"}},
153		{testSlice1, "alt", []string{"1", "4"}, []string{"i.a", "i.b", "i.c", "iv.d"}},
154		{testSlice1, "type", []string{"c", "d"}, []string{"i.c", "iii", "iv.d"}},
155	}
156	for i, tt := range tests {
157		sl := tt.sl
158		s := MakeSlice(&sl)
159		s.SelectOnePerGroup(tt.attr, tt.values)
160		if len(sl) != len(tt.refs) {
161			t.Errorf("%d: found result length %d; want %d", i, len(sl), len(tt.refs))
162			continue
163		}
164		for j, e := range sl {
165			if tt.refs[j] != e.Reference {
166				t.Errorf("%d:%d found %s; want %s", i, j, e.Reference, tt.refs[i])
167			}
168		}
169	}
170	sl := testSlice1
171	s := MakeSlice(&sl)
172	if !panics(func() { s.SelectOnePerGroup("foo", nil) }) {
173		t.Errorf("should panic on non-existing attribute")
174	}
175}
176