1package funk
2
3import (
4	"fmt"
5	"testing"
6
7	"github.com/stretchr/testify/assert"
8)
9
10func TestJoin_InnerJoin(t *testing.T) {
11	testCases := []struct {
12		LeftArr  interface{}
13		RightArr interface{}
14		Expect   interface{}
15	}{
16		{[]string{"foo", "bar"}, []string{"bar", "baz"}, []string{"bar"}},
17		{[]string{"foo", "bar", "bar"}, []string{"bar", "baz"}, []string{"bar"}},
18		{[]string{"foo", "bar"}, []string{"bar", "bar", "baz"}, []string{"bar"}},
19		{[]string{"foo", "bar", "bar"}, []string{"bar", "bar", "baz"}, []string{"bar"}},
20		{[]int{0, 1, 2, 3, 4}, []int{3, 4, 5, 6, 7}, []int{3, 4}},
21		{[]*Foo{f, b}, []*Foo{b, c}, []*Foo{b}},
22	}
23
24	for idx, tt := range testCases {
25		t.Run(fmt.Sprintf("test case #%d", idx+1), func(t *testing.T) {
26			is := assert.New(t)
27
28			actual := Join(tt.LeftArr, tt.RightArr, InnerJoin)
29			is.Equal(tt.Expect, actual)
30		})
31	}
32}
33
34func TestJoin_OuterJoin(t *testing.T) {
35	testCases := []struct {
36		LeftArr  interface{}
37		RightArr interface{}
38		Expect   interface{}
39	}{
40		{[]string{"foo", "bar"}, []string{"bar", "baz"}, []string{"foo", "baz"}},
41		{[]int{0, 1, 2, 3, 4}, []int{3, 4, 5, 6, 7}, []int{0, 1, 2, 5, 6, 7}},
42		{[]*Foo{f, b}, []*Foo{b, c}, []*Foo{f, c}},
43	}
44
45	for idx, tt := range testCases {
46		t.Run(fmt.Sprintf("test case #%d", idx+1), func(t *testing.T) {
47			is := assert.New(t)
48
49			actual := Join(tt.LeftArr, tt.RightArr, OuterJoin)
50			is.Equal(tt.Expect, actual)
51		})
52	}
53}
54
55func TestJoin_LeftJoin(t *testing.T) {
56	testCases := []struct {
57		LeftArr  interface{}
58		RightArr interface{}
59		Expect   interface{}
60	}{
61		{[]string{"foo", "bar"}, []string{"bar", "baz"}, []string{"foo"}},
62		{[]int{0, 1, 2, 3, 4}, []int{3, 4, 5, 6, 7}, []int{0, 1, 2}},
63		{[]*Foo{f, b}, []*Foo{b, c}, []*Foo{f}},
64	}
65
66	for idx, tt := range testCases {
67		t.Run(fmt.Sprintf("test case #%d", idx+1), func(t *testing.T) {
68			is := assert.New(t)
69
70			actual := Join(tt.LeftArr, tt.RightArr, LeftJoin)
71			is.Equal(tt.Expect, actual)
72		})
73	}
74}
75
76func TestJoin_RightJoin(t *testing.T) {
77	testCases := []struct {
78		LeftArr  interface{}
79		RightArr interface{}
80		Expect   interface{}
81	}{
82		{[]string{"foo", "bar"}, []string{"bar", "baz"}, []string{"baz"}},
83		{[]int{0, 1, 2, 3, 4}, []int{3, 4, 5, 6, 7}, []int{5, 6, 7}},
84		{[]*Foo{f, b}, []*Foo{b, c}, []*Foo{c}},
85	}
86
87	for idx, tt := range testCases {
88		t.Run(fmt.Sprintf("test case #%d", idx+1), func(t *testing.T) {
89			is := assert.New(t)
90
91			actual := Join(tt.LeftArr, tt.RightArr, RightJoin)
92			is.Equal(tt.Expect, actual)
93		})
94	}
95}
96
97// Struct which implements the String() method to test StringerJoin().
98type S struct {
99	Value string
100}
101
102func (s S) String() string {
103	return s.Value
104}
105
106func TestJoin_StringerJoin(t *testing.T) {
107	testCases := []struct {
108		Arr    []interface{ String() string }
109		Sep    string
110		Expect string
111	}{
112		{[]interface{ String() string }{}, ", ", ""},
113		{[]interface{ String() string }{S{"foo"}}, ", ", "foo"},
114		{[]interface{ String() string }{S{"foo"}, S{"bar"}, S{"baz"}}, ", ", "foo, bar, baz"},
115	}
116
117	for idx, tt := range testCases {
118		t.Run(fmt.Sprintf("test case #%d", idx+1), func(t *testing.T) {
119			is := assert.New(t)
120
121			actual := StringerJoin(tt.Arr, tt.Sep)
122			is.Equal(tt.Expect, actual)
123		})
124	}
125}
126