1
exercism fetch go perfect-numbers

cases_test.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package perfect

// Source: exercism/problem-specifications
// Commit: 924bb7a perfect-numbers: fix misleading test description
// Problem Specifications Version: 1.0.1

var classificationTestCases = []struct {
	description string
	input       int64
	ok          bool
	expected    Classification
}{
	{
		description: "Smallest perfect number is classified correctly",
		input:       6,
		ok:          true,
		expected:    ClassificationPerfect,
	},
	{
		description: "Medium perfect number is classified correctly",
		input:       28,
		ok:          true,
		expected:    ClassificationPerfect,
	},
	{
		description: "Large perfect number is classified correctly",
		input:       33550336,
		ok:          true,
		expected:    ClassificationPerfect,
	},
	{
		description: "Smallest abundant number is classified correctly",
		input:       12,
		ok:          true,
		expected:    ClassificationAbundant,
	},
	{
		description: "Medium abundant number is classified correctly",
		input:       30,
		ok:          true,
		expected:    ClassificationAbundant,
	},
	{
		description: "Large abundant number is classified correctly",
		input:       33550335,
		ok:          true,
		expected:    ClassificationAbundant,
	},
	{
		description: "Smallest prime deficient number is classified correctly",
		input:       2,
		ok:          true,
		expected:    ClassificationDeficient,
	},
	{
		description: "Smallest non-prime deficient number is classified correctly",
		input:       4,
		ok:          true,
		expected:    ClassificationDeficient,
	},
	{
		description: "Medium deficient number is classified correctly",
		input:       32,
		ok:          true,
		expected:    ClassificationDeficient,
	},
	{
		description: "Large deficient number is classified correctly",
		input:       33550337,
		ok:          true,
		expected:    ClassificationDeficient,
	},
	{
		description: "Edge case (no factors other than itself) is classified correctly",
		input:       1,
		ok:          true,
		expected:    ClassificationDeficient,
	},
	{
		description: "Zero is rejected (not a natural number)",
		input:       0,
		ok:          false,
	},
	{
		description: "Negative integer is rejected (not a natural number)",
		input:       -1,
		ok:          false,
	},
}

perfect_numbers_test.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package perfect

import "testing"

var _ error = ErrOnlyPositive

func TestGivesPositiveRequiredError(t *testing.T) {
	if _, err := Classify(0); err != ErrOnlyPositive {
		t.Fatalf("FAIL GivesPositiveRequiredError Expected error %q but got %q", ErrOnlyPositive, err)
	}
	t.Logf("PASS GivesPositiveRequiredError")
}

func TestClassifiesCorrectly(t *testing.T) {
	for _, c := range classificationTestCases {
		cat, err := Classify(c.input)
		switch {
		case err != nil:
			if c.ok {
				t.Fatalf("FAIL %s\nClassify(%d)\nExpected no error but got error %q", c.description, c.input, err)
			}
		case !c.ok:
			t.Fatalf("FAIL %s\nClassify(%d)\nExpected error but got %q", c.description, c.input, cat)
		case cat != c.expected:
			t.Fatalf("FAIL %s\nClassify(%d)\nExpected %q, got %q", c.description, c.input, c.expected, cat)
		}
		t.Logf("PASS %s", c.description)
	}
}

// Test that the classifications are not equal to each other.
// If they are equal, then the tests will return false positives.
func TestClassificationsNotEqual(t *testing.T) {
	classifications := []struct {
		class Classification
		name  string
	}{
		{ClassificationAbundant, "ClassificationAbundant"},
		{ClassificationDeficient, "ClassificationDeficient"},
		{ClassificationPerfect, "ClassificationPerfect"},
	}

	for i, pair1 := range classifications {
		for j := i + 1; j < len(classifications); j++ {
			pair2 := classifications[j]
			if pair1.class == pair2.class {
				t.Fatalf("%s should not be equal to %s", pair1.name, pair2.name)
			}
		}
	}
}

func BenchmarkClassify(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for _, c := range classificationTestCases {
			Classify(c.input)
		}
	}
}