174 lines
3.2 KiB
Go
174 lines
3.2 KiB
Go
// API:
|
|
//
|
|
// type Grade struct {
|
|
// int, []string
|
|
// }
|
|
//
|
|
// type School
|
|
// func New() *School
|
|
// func (s *School) Add(string, int)
|
|
// func (s *School) Grade(int) []string
|
|
// func (s *School) Enrollment() []Grade
|
|
|
|
package school
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func TestNewSchoolIsEmpty(t *testing.T) {
|
|
if len(New().Enrollment()) != 0 {
|
|
t.Error("New school not empty")
|
|
}
|
|
}
|
|
|
|
func list(e []Grade) (s string) {
|
|
for _, l := range e {
|
|
s += fmt.Sprintln(l)
|
|
}
|
|
return s
|
|
}
|
|
|
|
func TestAddStudent(t *testing.T) {
|
|
exp := list([]Grade{{2, []string{"Aimee"}}})
|
|
s := New()
|
|
s.Add("Aimee", 2)
|
|
got := list(s.Enrollment())
|
|
if got != exp {
|
|
t.Errorf(`Add Aimee level 2, got
|
|
%sexpected:
|
|
%s`, got, exp)
|
|
}
|
|
}
|
|
|
|
func TestAddMoreSameGrade(t *testing.T) {
|
|
exp := list([]Grade{{2, []string{"Blair James Paul"}}})
|
|
s := New()
|
|
s.Add("Blair", 2)
|
|
s.Add("James", 2)
|
|
s.Add("Paul", 2)
|
|
got := list(s.Enrollment())
|
|
if got != exp {
|
|
t.Errorf(`Add more same grade, got
|
|
%sexpected:
|
|
%s`, got, exp)
|
|
}
|
|
}
|
|
|
|
func TestAddDifferentGrades(t *testing.T) {
|
|
exp := list([]Grade{
|
|
{3, []string{"Chelsea"}},
|
|
{7, []string{"Logan"}},
|
|
})
|
|
s := New()
|
|
s.Add("Chelsea", 3)
|
|
s.Add("Logan", 7)
|
|
got := list(s.Enrollment())
|
|
if got != exp {
|
|
t.Errorf(`Add different grades, got
|
|
%sexpected:
|
|
%s`, got, exp)
|
|
}
|
|
}
|
|
|
|
func TestGetGrade(t *testing.T) {
|
|
exp := []string{"Bradley", "Franklin"}
|
|
s := New()
|
|
s.Add("Bradley", 5)
|
|
s.Add("Franklin", 5)
|
|
s.Add("Jeff", 1)
|
|
got := s.Grade(5)
|
|
if len(got) == len(exp) {
|
|
if got[0] == exp[0] && got[1] == exp[1] ||
|
|
got[0] == exp[1] && got[1] == exp[0] { // accept out of order
|
|
return
|
|
}
|
|
}
|
|
t.Errorf(`Get grade, got
|
|
%v
|
|
expected
|
|
%v`, got, exp)
|
|
}
|
|
|
|
func TestNonExistantGrade(t *testing.T) {
|
|
s := New()
|
|
got := s.Grade(1)
|
|
if len(got) != 0 {
|
|
t.Errorf(`Get non-existant grade, got
|
|
%v
|
|
expected
|
|
[]`, got)
|
|
}
|
|
}
|
|
|
|
func TestSortedEnrollment(t *testing.T) {
|
|
exp := list([]Grade{
|
|
{3, []string{"Kyle"}},
|
|
{4, []string{"Christopher Jennifer"}},
|
|
{6, []string{"Kareem"}},
|
|
})
|
|
s := New()
|
|
s.Add("Jennifer", 4)
|
|
s.Add("Kareem", 6)
|
|
s.Add("Christopher", 4)
|
|
s.Add("Kyle", 3)
|
|
got := list(s.Enrollment())
|
|
if got != exp {
|
|
t.Errorf(`Sorted enrollment, got
|
|
%sexpected:
|
|
%s`, got, exp)
|
|
}
|
|
}
|
|
|
|
const (
|
|
minLevel = 1
|
|
maxLevel = 9
|
|
enrollment = 400
|
|
)
|
|
|
|
func BenchmarkAddStudents(b *testing.B) {
|
|
const pool = 1e6 // pool of students
|
|
names := make([]string, pool)
|
|
levels := make([]int, pool)
|
|
for i := range names {
|
|
names[i] = strconv.Itoa(rand.Intn(1e5))
|
|
levels[i] = minLevel + rand.Intn(maxLevel-minLevel+1)
|
|
}
|
|
p := 0
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// bench combined time to create a school and add
|
|
// a number of students, drawn from a pool of students
|
|
s := New()
|
|
for t := 0; t < enrollment; t++ {
|
|
s.Add(names[p], levels[p])
|
|
p = (p + 1) % pool
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkEnrollment(b *testing.B) {
|
|
const pool = 1000 // pool of schools
|
|
ss := make([]*School, pool)
|
|
for i := range ss {
|
|
s := New()
|
|
for t := 0; t < enrollment; t++ {
|
|
s.Add(
|
|
strconv.Itoa(rand.Intn(1e5)),
|
|
minLevel+rand.Intn(maxLevel-minLevel+1))
|
|
}
|
|
ss[i] = s
|
|
}
|
|
p := 0
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// bench time to get enrollment of a full school,
|
|
// averaged over a pool of schools.
|
|
ss[p].Enrollment()
|
|
p = (p + 1) % pool
|
|
}
|
|
}
|