database.TestUniqueTupleIterator   F
last analyzed

Complexity

Conditions 14

Size

Total Lines 108
Code Lines 72

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 72
nop 1
dl 0
loc 108
rs 3.4363
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like database.TestUniqueTupleIterator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
package database
2
3
import (
4
	"testing"
5
6
	"github.com/stretchr/testify/assert"
7
	"google.golang.org/protobuf/types/known/anypb"
8
9
	base "github.com/Permify/permify/pkg/pb/base/v1"
10
)
11
12
func TestTupleIterator(t *testing.T) {
13
	// Create some tuples
14
	tuple1 := &base.Tuple{
15
		Subject:  &base.Subject{Type: "user", Id: "u1"},
16
		Relation: "rel1",
17
		Entity: &base.Entity{
18
			Type: "entity",
19
			Id:   "e1",
20
		},
21
	}
22
23
	tuple2 := &base.Tuple{
24
		Subject:  &base.Subject{Type: "user", Id: "u2"},
25
		Relation: "rel2",
26
		Entity: &base.Entity{
27
			Type: "entity",
28
			Id:   "e2",
29
		},
30
	}
31
32
	tuple3 := &base.Tuple{
33
		Subject:  &base.Subject{Type: "user", Id: "u3"},
34
		Relation: "rel3",
35
		Entity: &base.Entity{
36
			Type: "entity",
37
			Id:   "e3",
38
		},
39
	}
40
41
	// Create a tuple collection and add the tuples
42
	tupleCollection := NewTupleCollection(tuple1, tuple2, tuple3)
43
44
	// Create a tuple iterator
45
	tupleIterator := tupleCollection.CreateTupleIterator()
46
47
	// Test HasNext() and GetNext() methods
48
	if !tupleIterator.HasNext() {
49
		t.Error("Expected true for HasNext(), but got false")
50
	}
51
	if tupleIterator.GetNext() != tuple1 {
52
		t.Error("Expected tuple1 for GetNext(), but got something else")
53
	}
54
	if !tupleIterator.HasNext() {
55
		t.Error("Expected true for HasNext(), but got false")
56
	}
57
	if tupleIterator.GetNext() != tuple2 {
58
		t.Error("Expected tuple2 for GetNext(), but got something else")
59
	}
60
	if !tupleIterator.HasNext() {
61
		t.Error("Expected true for HasNext(), but got false")
62
	}
63
	if tupleIterator.GetNext() != tuple3 {
64
		t.Error("Expected tuple3 for GetNext(), but got something else")
65
	}
66
	if tupleIterator.HasNext() {
67
		t.Error("Expected false for HasNext(), but got true")
68
	}
69
}
70
71
func TestSubjectIterator(t *testing.T) {
72
	// Create some subjects
73
	subject1 := &base.Subject{Type: "user", Id: "u1"}
74
	subject2 := &base.Subject{Type: "user", Id: "u2"}
75
	subject3 := &base.Subject{Type: "user", Id: "u3"}
76
77
	// Create a subject collection and add the subjects
78
	subjectCollection := NewSubjectCollection(subject1, subject2, subject3)
79
80
	// Create a subject iterator
81
	subjectIterator := subjectCollection.CreateSubjectIterator()
82
83
	// Test HasNext() and GetNext() methods
84
	if !subjectIterator.HasNext() {
85
		t.Error("Expected true for HasNext(), but got false")
86
	}
87
	if subjectIterator.GetNext() != subject1 {
88
		t.Error("Expected subject1 for GetNext(), but got something else")
89
	}
90
	if !subjectIterator.HasNext() {
91
		t.Error("Expected true for HasNext(), but got false")
92
	}
93
	if subjectIterator.GetNext() != subject2 {
94
		t.Error("Expected subject2 for GetNext(), but got something else")
95
	}
96
	if !subjectIterator.HasNext() {
97
		t.Error("Expected true for HasNext(), but got false")
98
	}
99
	if subjectIterator.GetNext() != subject3 {
100
		t.Error("Expected subject3 for GetNext(), but got something else")
101
	}
102
	if subjectIterator.HasNext() {
103
		t.Error("Expected false for HasNext(), but got true")
104
	}
105
}
106
107
func TestUniqueTupleIterator(t *testing.T) {
108
	// Create some tuples
109
	tuple1 := &base.Tuple{
110
		Entity: &base.Entity{
111
			Type: "entity",
112
			Id:   "e1",
113
		},
114
		Relation: "rel1",
115
		Subject:  &base.Subject{Type: "user", Id: "u1"},
116
	}
117
118
	tuple2 := &base.Tuple{
119
		Entity: &base.Entity{
120
			Type: "entity",
121
			Id:   "e2",
122
		},
123
		Relation: "rel2",
124
		Subject:  &base.Subject{Type: "user", Id: "u2"},
125
	}
126
127
	tuple3 := &base.Tuple{
128
		Entity: &base.Entity{
129
			Type: "entity",
130
			Id:   "e3",
131
		},
132
		Relation: "rel3",
133
		Subject:  &base.Subject{Type: "user", Id: "u3"},
134
	}
135
136
	tuple4 := &base.Tuple{
137
		Entity: &base.Entity{
138
			Type: "entity",
139
			Id:   "e4",
140
		},
141
		Relation: "rel4",
142
		Subject:  &base.Subject{Type: "organization", Id: "o4", Relation: "member"},
143
	}
144
145
	tuple5 := &base.Tuple{
146
		Entity: &base.Entity{
147
			Type: "entity",
148
			Id:   "e5",
149
		},
150
		Relation: "rel5",
151
		Subject:  &base.Subject{Type: "user", Id: "u5"},
152
	}
153
154
	tuple6 := &base.Tuple{
155
		Entity: &base.Entity{
156
			Type: "entity",
157
			Id:   "e6",
158
		},
159
		Relation: "rel6",
160
		Subject:  &base.Subject{Type: "organization", Id: "o6", Relation: "admin"},
161
	}
162
163
	// Create a tuple iterators
164
	tupleIterator1 := NewTupleIterator(tuple1, tuple2, tuple3, tuple6)
165
	tupleIterator2 := NewTupleIterator(tuple6, tuple1, tuple2, tuple4, tuple5)
166
167
	// Create a unique iterator
168
	uniqueIterator := NewUniqueTupleIterator(tupleIterator1, tupleIterator2)
169
170
	// Test HasNext() and GetNext() methods
171
	if !uniqueIterator.HasNext() {
172
		t.Error("Expected true for HasNext(), but got false")
173
	}
174
	i, _ := uniqueIterator.GetNext()
175
	if i != tuple1 {
176
		t.Error("Expected tuple1 for GetNext(), but got something else")
177
	}
178
	if !uniqueIterator.HasNext() {
179
		t.Error("Expected true for HasNext(), but got false")
180
	}
181
	i, _ = uniqueIterator.GetNext()
182
	if i != tuple2 {
183
		t.Error("Expected tuple2 for GetNext(), but got something else")
184
	}
185
	if !uniqueIterator.HasNext() {
186
		t.Error("Expected true for HasNext(), but got false")
187
	}
188
	i, _ = uniqueIterator.GetNext()
189
	if i != tuple3 {
190
		t.Error("Expected tuple3 for GetNext(), but got something else")
191
	}
192
	if !uniqueIterator.HasNext() {
193
		t.Error("Expected false for HasNext(), but got true")
194
	}
195
	i, _ = uniqueIterator.GetNext()
196
	if i != tuple6 {
197
		t.Error("Expected tuple6 for GetNext(), but got something else")
198
	}
199
	if !uniqueIterator.HasNext() {
200
		t.Error("Expected false for HasNext(), but got true")
201
	}
202
	i, _ = uniqueIterator.GetNext()
203
	if i != tuple4 {
204
		t.Error("Expected tuple4 for GetNext(), but got something else")
205
	}
206
	if !uniqueIterator.HasNext() {
207
		t.Error("Expected false for HasNext(), but got true")
208
	}
209
	i, _ = uniqueIterator.GetNext()
210
	if i != tuple5 {
211
		t.Error("Expected tuple5 for GetNext(), but got something else")
212
	}
213
	if uniqueIterator.HasNext() {
214
		t.Error("Expected false for HasNext(), but got true")
215
	}
216
}
217
218
func TestAttributeIterator(t *testing.T) {
219
	isPublic, err := anypb.New(&base.BooleanValue{Data: true})
220
	assert.NoError(t, err)
221
222
	isPublic2, err := anypb.New(&base.BooleanValue{Data: false})
223
	assert.NoError(t, err)
224
225
	// Create some attributes
226
	attribute1 := &base.Attribute{
227
		Entity: &base.Entity{
228
			Type: "entity",
229
			Id:   "e1",
230
		},
231
		Attribute: "public",
232
		Value:     isPublic,
233
	}
234
235
	attribute2 := &base.Attribute{
236
		Entity: &base.Entity{
237
			Type: "entity",
238
			Id:   "e2",
239
		},
240
		Attribute: "public",
241
		Value:     isPublic2,
242
	}
243
244
	attribute3 := &base.Attribute{
245
		Entity: &base.Entity{
246
			Type: "entity",
247
			Id:   "e3",
248
		},
249
		Attribute: "public",
250
		Value:     isPublic,
251
	}
252
253
	// Create an attribute collection and add the tuples
254
	attributeCollection := NewAttributeCollection(attribute1, attribute2, attribute3)
255
256
	// Create a attribute iterator
257
	attributeIterator := attributeCollection.CreateAttributeIterator()
258
259
	// Test HasNext() and GetNext() methods
260
	if !attributeIterator.HasNext() {
261
		t.Error("Expected true for HasNext(), but got false")
262
	}
263
	if attributeIterator.GetNext() != attribute1 {
264
		t.Error("Expected tuple1 for GetNext(), but got something else")
265
	}
266
	if !attributeIterator.HasNext() {
267
		t.Error("Expected true for HasNext(), but got false")
268
	}
269
	if attributeIterator.GetNext() != attribute2 {
270
		t.Error("Expected tuple2 for GetNext(), but got something else")
271
	}
272
	if !attributeIterator.HasNext() {
273
		t.Error("Expected true for HasNext(), but got false")
274
	}
275
	if attributeIterator.GetNext() != attribute3 {
276
		t.Error("Expected tuple3 for GetNext(), but got something else")
277
	}
278
	if attributeIterator.HasNext() {
279
		t.Error("Expected false for HasNext(), but got true")
280
	}
281
}
282
283
func TestUniqueAttributeIterator(t *testing.T) {
284
	isPublic, err := anypb.New(&base.BooleanValue{Data: true})
285
	assert.NoError(t, err)
286
287
	// Create some attributes
288
	attribute1 := &base.Attribute{
289
		Entity: &base.Entity{
290
			Type: "entity",
291
			Id:   "e1",
292
		},
293
		Attribute: "public",
294
		Value:     isPublic,
295
	}
296
297
	attribute2 := &base.Attribute{
298
		Entity: &base.Entity{
299
			Type: "entity",
300
			Id:   "e2",
301
		},
302
		Attribute: "public",
303
		Value:     isPublic,
304
	}
305
306
	attribute3 := &base.Attribute{
307
		Entity: &base.Entity{
308
			Type: "entity",
309
			Id:   "e3",
310
		},
311
		Attribute: "public",
312
		Value:     isPublic,
313
	}
314
315
	attribute4 := &base.Attribute{
316
		Entity: &base.Entity{
317
			Type: "entity",
318
			Id:   "e4",
319
		},
320
		Attribute: "public",
321
		Value:     isPublic,
322
	}
323
324
	attribute5 := &base.Attribute{
325
		Entity: &base.Entity{
326
			Type: "entity",
327
			Id:   "e5",
328
		},
329
		Attribute: "public",
330
		Value:     isPublic,
331
	}
332
333
	attribute6 := &base.Attribute{
334
		Entity: &base.Entity{
335
			Type: "entity",
336
			Id:   "e6",
337
		},
338
		Attribute: "public",
339
		Value:     isPublic,
340
	}
341
342
	// Create a tuple iterators
343
	attributeIterator1 := NewAttributeIterator(attribute1, attribute2, attribute3, attribute6)
344
	attributeIterator2 := NewAttributeIterator(attribute6, attribute1, attribute2, attribute4, attribute5)
345
346
	// Create a unique iterator
347
	uniqueIterator := NewUniqueAttributeIterator(attributeIterator1, attributeIterator2)
348
349
	// Test HasNext() and GetNext() methods
350
	if !uniqueIterator.HasNext() {
351
		t.Error("Expected true for HasNext(), but got false")
352
	}
353
	i, _ := uniqueIterator.GetNext()
354
	if i != attribute1 {
355
		t.Error("Expected tuple1 for GetNext(), but got something else")
356
	}
357
	if !uniqueIterator.HasNext() {
358
		t.Error("Expected true for HasNext(), but got false")
359
	}
360
	i, _ = uniqueIterator.GetNext()
361
	if i != attribute2 {
362
		t.Error("Expected tuple2 for GetNext(), but got something else")
363
	}
364
	if !uniqueIterator.HasNext() {
365
		t.Error("Expected true for HasNext(), but got false")
366
	}
367
	i, _ = uniqueIterator.GetNext()
368
	if i != attribute3 {
369
		t.Error("Expected tuple3 for GetNext(), but got something else")
370
	}
371
	if !uniqueIterator.HasNext() {
372
		t.Error("Expected false for HasNext(), but got true")
373
	}
374
	i, _ = uniqueIterator.GetNext()
375
	if i != attribute6 {
376
		t.Error("Expected tuple6 for GetNext(), but got something else")
377
	}
378
	if !uniqueIterator.HasNext() {
379
		t.Error("Expected false for HasNext(), but got true")
380
	}
381
	i, _ = uniqueIterator.GetNext()
382
	if i != attribute4 {
383
		t.Error("Expected tuple4 for GetNext(), but got something else")
384
	}
385
	if !uniqueIterator.HasNext() {
386
		t.Error("Expected false for HasNext(), but got true")
387
	}
388
	i, _ = uniqueIterator.GetNext()
389
	if i != attribute5 {
390
		t.Error("Expected tuple5 for GetNext(), but got something else")
391
	}
392
	if uniqueIterator.HasNext() {
393
		t.Error("Expected false for HasNext(), but got true")
394
	}
395
}
396
397
func TestEntityIterator(t *testing.T) {
398
	// Create some tuples
399
	en1 := &base.Entity{
400
		Type: "entity",
401
		Id:   "e1",
402
	}
403
404
	en2 := &base.Entity{
405
		Type: "entity",
406
		Id:   "e2",
407
	}
408
409
	en3 := &base.Entity{
410
		Type: "entity",
411
		Id:   "e3",
412
	}
413
414
	// Create a entity collection and add the tuples
415
	entityCollection := NewEntityCollection(en1, en2, en3)
416
417
	// Create an entity iterator
418
	entityIterator := entityCollection.CreateEntityIterator()
419
420
	// Test HasNext() and GetNext() methods
421
	if !entityIterator.HasNext() {
422
		t.Error("Expected true for HasNext(), but got false")
423
	}
424
	if entityIterator.GetNext() != en1 {
425
		t.Error("Expected tuple1 for GetNext(), but got something else")
426
	}
427
	if !entityIterator.HasNext() {
428
		t.Error("Expected true for HasNext(), but got false")
429
	}
430
	if entityIterator.GetNext() != en2 {
431
		t.Error("Expected tuple2 for GetNext(), but got something else")
432
	}
433
	if !entityIterator.HasNext() {
434
		t.Error("Expected true for HasNext(), but got false")
435
	}
436
	if entityIterator.GetNext() != en3 {
437
		t.Error("Expected tuple3 for GetNext(), but got something else")
438
	}
439
	if entityIterator.HasNext() {
440
		t.Error("Expected false for HasNext(), but got true")
441
	}
442
}
443