summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/cmd/gotest/gotest5
-rw-r--r--src/lib/bufio_test.go342
-rw-r--r--src/lib/sort_test.go238
-rw-r--r--src/lib/strings_test.go99
-rw-r--r--src/lib/time/time_test.go79
5 files changed, 762 insertions, 1 deletions
diff --git a/src/cmd/gotest/gotest b/src/cmd/gotest/gotest
index 988e6f4ee..55d22e729 100755
--- a/src/cmd/gotest/gotest
+++ b/src/cmd/gotest/gotest
@@ -55,7 +55,10 @@ trap "rm -f _testmain.go _testmain.6" 0 1 2 3 14 15
# test array
echo
echo 'var tests = &[]testing.Test {'
- for i in $(6nm -s $ofiles | grep ' T .*·Test' | sed 's/.* //; s/·/./')
+ # test functions are named TestFoo
+ # the grep -v eliminates methods and other special names
+ # that have multiple dots.
+ for i in $(6nm -s $ofiles | grep ' T .*·Test[A-Z]' | grep -v '·.*[.·]' | sed 's/.* //; s/·/./')
do
echo ' testing.Test{ "'$i'", &'$i' },'
done
diff --git a/src/lib/bufio_test.go b/src/lib/bufio_test.go
new file mode 100644
index 000000000..8265c0a55
--- /dev/null
+++ b/src/lib/bufio_test.go
@@ -0,0 +1,342 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bufio
+
+import (
+ "bufio";
+ "fmt";
+ "io";
+ "os";
+ "syscall";
+ "testing";
+)
+
+func StringToBytes(s string) *[]byte {
+ b := new([]byte, len(s));
+ for i := 0; i < len(s); i++ {
+ b[i] = s[i]
+ }
+ return b
+}
+
+// Should be in language!
+func Copy(p *[]byte, q *[]byte) {
+ for i := 0; i < len(p); i++ {
+ p[i] = q[i]
+ }
+}
+
+// Reads from p.
+type ByteReader struct {
+ p *[]byte
+}
+
+func NewByteReader(p *[]byte) io.Read {
+ b := new(ByteReader);
+ b.p = p;
+ return b
+}
+
+func (b *ByteReader) Read(p *[]byte) (int, *os.Error) {
+ n := len(p);
+ if n > len(b.p) {
+ n = len(b.p)
+ }
+ Copy(p[0:n], b.p[0:n]);
+ b.p = b.p[n:len(b.p)];
+ return n, nil
+}
+
+
+// Reads from p but only returns half of what you asked for.
+type HalfByteReader struct {
+ p *[]byte
+}
+
+func NewHalfByteReader(p *[]byte) io.Read {
+ b := new(HalfByteReader);
+ b.p = p;
+ return b
+}
+
+func (b *HalfByteReader) Read(p *[]byte) (int, *os.Error) {
+ n := len(p)/2;
+ if n == 0 && len(p) > 0 {
+ n = 1
+ }
+ if n > len(b.p) {
+ n = len(b.p)
+ }
+ Copy(p[0:n], b.p[0:n]);
+ b.p = b.p[n:len(b.p)];
+ return n, nil
+}
+
+// Reads from a reader and rot13s the result.
+type Rot13Reader struct {
+ r io.Read
+}
+
+func NewRot13Reader(r io.Read) *Rot13Reader {
+ r13 := new(Rot13Reader);
+ r13.r = r;
+ return r13
+}
+
+func (r13 *Rot13Reader) Read(p *[]byte) (int, *os.Error) {
+ n, e := r13.r.Read(p);
+ if e != nil {
+ return n, e
+ }
+ for i := 0; i < n; i++ {
+ if 'a' <= p[i] && p[i] <= 'z' || 'A' <= p[i] && p[i] <= 'Z' {
+ if 'a' <= p[i] && p[i] <= 'm' || 'A' <= p[i] && p[i] <= 'M' {
+ p[i] += 13;
+ } else {
+ p[i] -= 13;
+ }
+ }
+ }
+ return n, nil
+}
+
+type Readmaker struct {
+ name string;
+ fn *(*[]byte) io.Read;
+}
+var readmakers = []Readmaker {
+ Readmaker{ "full", func(p *[]byte) io.Read { return NewByteReader(p) } },
+ Readmaker{ "half", func(p *[]byte) io.Read { return NewHalfByteReader(p) } },
+}
+
+// Call ReadLineString (which ends up calling everything else)
+// to accumulate the text of a file.
+func ReadLines(b *BufRead) string {
+ s := "";
+ for {
+ s1, e := b.ReadLineString('\n', true);
+ if e == EndOfFile {
+ break
+ }
+ if e != nil {
+ panic("GetLines: "+e.String())
+ }
+ s += s1
+ }
+ return s
+}
+
+// Call ReadByte to accumulate the text of a file
+func ReadBytes(buf *BufRead) string {
+ var b [1000]byte;
+ nb := 0;
+ for {
+ c, e := buf.ReadByte();
+ if e == EndOfFile {
+ break
+ }
+ if e != nil {
+ panic("GetBytes: "+e.String())
+ }
+ b[nb] = c;
+ nb++;
+ }
+ // BUG return string(b[0:nb]) ?
+ return string(b)[0:nb]
+}
+
+// Call Read to accumulate the text of a file
+func Reads(buf *BufRead, m int) string {
+ var b [1000]byte;
+ nb := 0;
+ for {
+ // BUG parens around (&b) should not be needed
+ n, e := buf.Read((&b)[nb:nb+m]);
+ nb += n;
+ if e == EndOfFile {
+ break
+ }
+ }
+ return string((&b)[0:nb])
+}
+
+type Bufreader struct {
+ name string;
+ fn *(*BufRead) string;
+}
+var bufreaders = []Bufreader {
+ Bufreader{ "1", func(b *BufRead) string { return Reads(b, 1) } },
+ Bufreader{ "2", func(b *BufRead) string { return Reads(b, 2) } },
+ Bufreader{ "3", func(b *BufRead) string { return Reads(b, 3) } },
+ Bufreader{ "4", func(b *BufRead) string { return Reads(b, 4) } },
+ Bufreader{ "5", func(b *BufRead) string { return Reads(b, 5) } },
+ Bufreader{ "7", func(b *BufRead) string { return Reads(b, 7) } },
+ Bufreader{ "bytes", &ReadBytes },
+ Bufreader{ "lines", &ReadLines },
+}
+
+var bufsizes = []int {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 23, 32, 46, 64, 93, 128, 1024, 4096
+}
+
+export func TestBufReadSimple(t *testing.T) {
+ b, e := NewBufRead(NewByteReader(StringToBytes("hello world")));
+ if s := ReadBytes(b); s != "hello world" {
+ t.Errorf("simple hello world test failed: got %q", s);
+ }
+
+ b, e = NewBufRead(NewRot13Reader(NewByteReader(StringToBytes("hello world"))));
+ if s := ReadBytes(b); s != "uryyb jbeyq" {
+ t.Error("rot13 hello world test failed: got %q", s);
+ }
+}
+
+export func TestBufRead(t *testing.T) {
+ var texts [31]string;
+ str := "";
+ all := "";
+ for i := 0; i < len(texts)-1; i++ {
+ texts[i] = str + "\n";
+ all += texts[i];
+ str += string(i%26+'a')
+ }
+ texts[len(texts)-1] = all;
+
+ for h := 0; h < len(texts); h++ {
+ text := texts[h];
+ textbytes := StringToBytes(text);
+ for i := 0; i < len(readmakers); i++ {
+ for j := 0; j < len(bufreaders); j++ {
+ for k := 0; k < len(bufsizes); k++ {
+ readmaker := readmakers[i];
+ bufreader := bufreaders[j];
+ bufsize := bufsizes[k];
+ read := readmaker.fn(textbytes);
+ buf, e := NewBufReadSize(read, bufsize);
+ s := bufreader.fn(buf);
+ if s != text {
+ t.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q",
+ readmaker.name, bufreader.name, bufsize, text, s);
+ }
+ }
+ }
+ }
+ }
+}
+
+type WriteBuffer interface {
+ Write(p *[]byte) (int, *os.Error);
+ GetBytes() *[]byte
+}
+
+// Accumulates bytes into a byte array.
+type ByteWriter struct {
+ p *[]byte;
+ n int
+}
+
+func NewByteWriter() WriteBuffer {
+ return new(ByteWriter)
+}
+
+func (w *ByteWriter) Write(p *[]byte) (int, *os.Error) {
+ if w.p == nil {
+ w.p = new([]byte, len(p)+100)
+ } else if w.n + len(p) >= len(w.p) {
+ newp := new([]byte, len(w.p)*2 + len(p));
+ Copy(newp[0:w.n], w.p[0:w.n]);
+ w.p = newp
+ }
+ Copy(w.p[w.n:w.n+len(p)], p);
+ w.n += len(p);
+ return len(p), nil
+}
+
+func (w *ByteWriter) GetBytes() *[]byte {
+ return w.p[0:w.n]
+}
+
+// Accumulates bytes written into a byte array
+// but Write only takes half of what you give it.
+// TODO: Could toss this -- Write() is not supposed to do that.
+type HalfByteWriter struct {
+ bw WriteBuffer
+}
+
+func NewHalfByteWriter() WriteBuffer {
+ w := new(HalfByteWriter);
+ w.bw = NewByteWriter();
+ return w
+}
+
+func (w *HalfByteWriter) Write(p *[]byte) (int, *os.Error) {
+ n := (len(p)+1) / 2;
+ // BUG return w.bw.Write(p[0:n])
+ r, e := w.bw.Write(p[0:n]);
+ return r, e
+}
+
+func (w *HalfByteWriter) GetBytes() *[]byte {
+ return w.bw.GetBytes()
+}
+
+type Writemaker struct {
+ name string;
+ fn *()WriteBuffer;
+}
+export func TestBufWrite(t *testing.T) {
+ var data [8192]byte;
+
+ var writers = []Writemaker {
+ Writemaker{ "full", &NewByteWriter },
+ Writemaker{ "half", &NewHalfByteWriter },
+ };
+
+ for i := 0; i < len(data); i++ {
+ data[i] = byte(' '+ i%('~'-' '));
+ }
+ for i := 0; i < len(bufsizes); i++ {
+ for j := 0; j < len(bufsizes); j++ {
+ for k := 0; k < len(writers); k++ {
+ nwrite := bufsizes[i];
+ bs := bufsizes[j];
+
+ // Write nwrite bytes using buffer size bs.
+ // Check that the right amount makes it out
+ // and that the data is correct.
+
+ write := writers[k].fn();
+ buf, e := NewBufWriteSize(write, bs);
+ context := fmt.sprintf("write=%s nwrite=%d bufsize=%d", writers[k].name, nwrite, bs);
+ if e != nil {
+ t.Errorf("%s: NewBufWriteSize %d: %v", context, bs, e);
+ continue;
+ }
+ n, e1 := buf.Write((&data)[0:nwrite]);
+ if e1 != nil || n != nwrite {
+ t.Errorf("%s: buf.Write %d = %d, %v", context, nwrite, n, e1);
+ continue;
+ }
+ if e = buf.Flush(); e != nil {
+ t.Errorf("%s: buf.Flush = %v", context, e);
+ }
+
+ written := write.GetBytes();
+ if len(written) != nwrite {
+ t.Errorf("%s: %d bytes written", context, len(written));
+ }
+ for l := 0; l < len(written); l++ {
+ if written[i] != data[i] {
+ t.Errorf("%s: wrong bytes written");
+ t.Errorf("want=%s", (&data)[0:len(written)]);
+ t.Errorf("have=%s", written);
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/lib/sort_test.go b/src/lib/sort_test.go
new file mode 100644
index 000000000..5afced699
--- /dev/null
+++ b/src/lib/sort_test.go
@@ -0,0 +1,238 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sort
+
+import (
+ "fmt";
+ "rand";
+ "sort";
+ "testing";
+)
+
+func BentleyMcIlroyTests();
+
+
+var ints = []int{74, 59, 238, -784, 9845, 959, 905, 0, 0, 42, 7586, -5467984, 7586}
+var floats = []float{74.3, 59.0, 238.2, -784.0, 2.3, 9845.768, -959.7485, 905, 7.8, 7.8}
+var strings = []string{"", "Hello", "foo", "bar", "foo", "f00", "%*&^*&^&", "***"}
+
+export func TestSortIntArray(t *testing.T) {
+ data := ints;
+ a := sort.IntArray{&data};
+ sort.Sort(&a);
+ if !sort.IsSorted(&a) {
+ t.Errorf("sorted %v", ints);
+ t.Errorf(" got %v", data);
+ }
+}
+
+export func TestSortFloatArray(t *testing.T) {
+ data := floats;
+ a := sort.FloatArray{&data};
+ sort.Sort(&a);
+ if !sort.IsSorted(&a) {
+ t.Errorf("sorted %v", floats);
+ t.Errorf(" got %v", data);
+ }
+}
+
+export func TestSortStringArray(t *testing.T) {
+ data := strings;
+ a := sort.StringArray{&data};
+ sort.Sort(&a);
+ if !sort.IsSorted(&a) {
+ t.Errorf("sorted %v", strings);
+ t.Errorf(" got %v", data);
+ }
+}
+
+export func TestSortInts(t *testing.T) {
+ data := ints;
+ sort.SortInts(&data);
+ if !sort.IntsAreSorted(&data) {
+ t.Errorf("sorted %v", ints);
+ t.Errorf(" got %v", data);
+ }
+}
+
+export func TestSortFloats(t *testing.T) {
+ data := floats;
+ sort.SortFloats(&data);
+ if !sort.FloatsAreSorted(&data) {
+ t.Errorf("sorted %v", floats);
+ t.Errorf(" got %v", data);
+ }
+}
+
+export func TestSortStrings(t *testing.T) {
+ data := strings;
+ sort.SortStrings(&data);
+ if !sort.StringsAreSorted(&data) {
+ t.Errorf("sorted %v", strings);
+ t.Errorf(" got %v", data);
+ }
+}
+
+export func TestSortLargeRandom(t *testing.T) {
+ data := new([]int, 1000000);
+ for i := 0; i < len(data); i++ {
+ data[i] = rand.rand() % 100;
+ }
+ if sort.IntsAreSorted(data) {
+ t.Fatalf("terrible rand.rand");
+ }
+ sort.SortInts(data);
+ if !sort.IntsAreSorted(data) {
+ t.Errorf("sort didn't sort - 1M ints");
+ }
+}
+
+const (
+ Sawtooth = iota;
+ Rand;
+ Stagger;
+ Plateau;
+ Shuffle;
+ NDist;
+)
+
+const (
+ Copy = iota;
+ Reverse;
+ ReverseFirstHalf;
+ ReverseSecondHalf;
+ Sorted;
+ Dither;
+ NMode;
+);
+
+type TestingData struct {
+ desc string;
+ t *testing.T;
+ data *[]int;
+ maxswap int; // number of swaps allowed
+ nswap int;
+}
+
+func (d *TestingData) Len() int { return len(d.data); }
+func (d *TestingData) Less(i, j int) bool { return d.data[i] < d.data[j]; }
+func (d *TestingData) Swap(i, j int) {
+ if d.nswap >= d.maxswap {
+ d.t.Errorf("%s: used %d swaps sorting array of %d", d.desc, d.nswap, len(d.data));
+ d.t.FailNow();
+ }
+ d.nswap++;
+ d.data[i], d.data[j] = d.data[j], d.data[i];
+}
+
+func Lg(n int) int {
+ i := 0;
+ for 1<<uint(i) < n {
+ i++;
+ }
+ return i;
+}
+
+func Min(a, b int) int {
+ if a < b {
+ return a;
+ }
+ return b;
+}
+
+export func TestBentleyMcIlroy(t *testing.T) {
+ sizes := []int{100, 1023, 1024, 1025};
+ dists := []string{"sawtooth", "rand", "stagger", "plateau", "shuffle"};
+ modes := []string{"copy", "reverse", "reverse1", "reverse2", "sort", "dither"};
+ var tmp1, tmp2 [1025]int;
+ for ni := 0; ni < len(sizes); ni++ {
+ n := sizes[ni];
+ for m := 1; m < 2*n; m *= 2 {
+ for dist := 0; dist < NDist; dist++ {
+ j := 0;
+ k := 1;
+ data := (&tmp1)[0:n];
+ for i := 0; i < n; i++ {
+ switch dist {
+ case Sawtooth:
+ data[i] = i % m;
+ case Rand:
+ data[i] = rand.rand() % m;
+ case Stagger:
+ data[i] = (i*m + i) % n;
+ case Plateau:
+ data[i] = Min(i, m);
+ case Shuffle:
+ if rand.rand() % m != 0 {
+ j += 2;
+ data[i] = j;
+ } else {
+ k += 2;
+ data[i] = k;
+ }
+ }
+ }
+
+ mdata := (&tmp2)[0:n];
+ for mode := 0; mode < NMode; mode++ {
+ switch mode {
+ case Copy:
+ for i := 0; i < n; i++ {
+ mdata[i] = data[i];
+ }
+ case Reverse:
+ for i := 0; i < n; i++ {
+ mdata[i] = data[n-i-1];
+ }
+ case ReverseFirstHalf:
+ for i := 0; i < n/2; i++ {
+ mdata[i] = data[n/2-i-1];
+ }
+ for i := n/2; i < n; i++ {
+ mdata[i] = data[i];
+ }
+ case ReverseSecondHalf:
+ for i := 0; i < n/2; i++ {
+ mdata[i] = data[i];
+ }
+ for i := n/2; i < n; i++ {
+ mdata[i] = data[n-(i-n/2)-1];
+ }
+ case Sorted:
+ for i := 0; i < n; i++ {
+ mdata[i] = data[i];
+ }
+ // sort.SortInts is known to be correct
+ // because mode Sort runs after mode Copy.
+ sort.SortInts(mdata);
+ case Dither:
+ for i := 0; i < n; i++ {
+ mdata[i] = data[i] + i%5;
+ }
+ }
+
+ desc := fmt.sprintf("n=%d m=%d dist=%s mode=%s", n, m, dists[dist], modes[mode]);
+ d := &TestingData{desc, t, mdata[0:n], n*Lg(n)*12/10, 0};
+ sort.Sort(d);
+
+ // If we were testing C qsort, we'd have to make a copy
+ // of the array and sort it ourselves and then compare
+ // x against it, to ensure that qsort was only permuting
+ // the data, not (for example) overwriting it with zeros.
+ //
+ // In go, we don't have to be so paranoid: since the only
+ // mutating method sort.Sort can call is TestingData.swap,
+ // it suffices here just to check that the final array is sorted.
+ if !sort.IntsAreSorted(mdata) {
+ t.Errorf("%s: ints not sorted", desc);
+ t.Errorf("\t%v", mdata);
+ t.FailNow();
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/lib/strings_test.go b/src/lib/strings_test.go
new file mode 100644
index 000000000..a7b63738b
--- /dev/null
+++ b/src/lib/strings_test.go
@@ -0,0 +1,99 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strings
+
+import (
+ "strings";
+ "testing";
+)
+
+func eq(a, b *[]string) bool {
+ if len(a) != len(b) {
+ return false;
+ }
+ for i := 0; i < len(a); i++ {
+ if a[i] != b[i] {
+ return false;
+ }
+ }
+ return true;
+}
+
+var abcd = "abcd";
+var faces = "☺☻☹";
+var commas = "1,2,3,4";
+var dots = "1....2....3....4";
+
+type ExplodeTest struct {
+ s string;
+ a *[]string;
+}
+var explodetests = []ExplodeTest {
+ ExplodeTest{ abcd, &[]string{"a", "b", "c", "d"} },
+ ExplodeTest{ faces, &[]string{"☺", "☻", "☹" } },
+}
+export func TestExplode(t *testing.T) {
+ for i := 0; i < len(explodetests); i++ {
+ tt := explodetests[i];
+ a := explode(tt.s);
+ if !eq(a, tt.a) {
+ t.Errorf("Explode(%q) = %v; want %v", tt.s, a, tt.a);
+ continue;
+ }
+ s := join(a, "");
+ if s != tt.s {
+ t.Errorf(`Join(Explode(%q), "") = %q`, tt.s, s);
+ }
+ }
+}
+
+type SplitTest struct {
+ s string;
+ sep string;
+ a *[]string;
+}
+var splittests = []SplitTest {
+ SplitTest{ abcd, "a", &[]string{"", "bcd"} },
+ SplitTest{ abcd, "z", &[]string{"abcd"} },
+ SplitTest{ abcd, "", &[]string{"a", "b", "c", "d"} },
+ SplitTest{ commas, ",", &[]string{"1", "2", "3", "4"} },
+ SplitTest{ dots, "...", &[]string{"1", ".2", ".3", ".4"} },
+ SplitTest{ faces, "☹", &[]string{"☺☻", ""} },
+ SplitTest{ faces, "~", &[]string{faces} },
+ SplitTest{ faces, "", &[]string{"☺", "☻", "☹"} },
+}
+export func TestSplit(t *testing.T) {
+ for i := 0; i < len(splittests); i++ {
+ tt := splittests[i];
+ a := split(tt.s, tt.sep);
+ if !eq(a, tt.a) {
+ t.Errorf("Split(%q, %q) = %v; want %v", tt.s, tt.sep, a, tt.a);
+ continue;
+ }
+ s := join(a, tt.sep);
+ if s != tt.s {
+ t.Errorf("Join(Split(%q, %q), %q) = %q", tt.s, tt.sep, tt.sep, s);
+ }
+ }
+}
+
+// TODO: utflen shouldn't even be in strings.
+type UtflenTest struct {
+ in string;
+ out int;
+}
+var utflentests = []UtflenTest {
+ UtflenTest{ abcd, 4 },
+ UtflenTest{ faces, 3 },
+ UtflenTest{ commas, 7 },
+}
+export func TestUtflen(t *testing.T) {
+ for i := 0; i < len(utflentests); i++ {
+ tt := utflentests[i];
+ if out := strings.utflen(tt.in); out != tt.out {
+ t.Errorf("utflen(%q) = %d, want %d", tt.in, out, tt.out);
+ }
+ }
+}
diff --git a/src/lib/time/time_test.go b/src/lib/time/time_test.go
new file mode 100644
index 000000000..f771ec03c
--- /dev/null
+++ b/src/lib/time/time_test.go
@@ -0,0 +1,79 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// $G $F.go && $L $F.$A && ./$A.out
+
+package time
+
+import (
+ "testing";
+ "time";
+)
+
+type TimeTest struct {
+ seconds int64;
+ golden Time;
+}
+
+var utctests = []TimeTest {
+ TimeTest{0, Time{1970, 1, 1, 0, 0, 0, Thursday, 0, "GMT"}},
+ TimeTest{1221681866, Time{2008, 9, 17, 20, 4, 26, Wednesday, 0, "GMT"}},
+ TimeTest{-1221681866, Time{1931, 4, 16, 3, 55, 34, Thursday, 0, "GMT"}},
+ TimeTest{1e18, Time{31688740476, 10, 23, 1, 46, 40, Friday, 0, "GMT"}},
+ TimeTest{-1e18, Time{-31688736537, 3, 10, 22, 13, 20, Tuesday, 0, "GMT"}},
+ TimeTest{0x7fffffffffffffff, Time{292277026596, 12, 4, 15, 30, 7, Sunday, 0, "GMT"}},
+ TimeTest{-0x8000000000000000, Time{-292277022657, 1, 27, 8, 29, 52, Sunday, 0, "GMT"}}
+}
+
+var localtests = []TimeTest {
+ TimeTest{0, Time{1969, 12, 31, 16, 0, 0, Wednesday, -8*60*60, "PST"}},
+ TimeTest{1221681866, Time{2008, 9, 17, 13, 4, 26, Wednesday, -7*60*60, "PDT"}}
+}
+
+func Same(t, u *Time) bool {
+ return t.year == u.year
+ && t.month == u.month
+ && t.day == u.day
+ && t.hour == u.hour
+ && t.minute == u.minute
+ && t.second == u.second
+ && t.weekday == u.weekday
+ && t.zoneoffset == u.zoneoffset
+ && t.zone == u.zone
+}
+
+export func TestSecondsToUTC(t *testing.T) {
+ for i := 0; i < len(utctests); i++ {
+ sec := utctests[i].seconds;
+ golden := &utctests[i].golden;
+ tm := SecondsToUTC(sec);
+ newsec := tm.Seconds();
+ if newsec != sec {
+ t.Errorf("SecondsToUTC(%d).Seconds() = %d", sec, newsec);
+ }
+ if !Same(tm, golden) {
+ t.Errorf("SecondsToUTC(%d):", sec);
+ t.Errorf(" want=%v", *golden);
+ t.Errorf(" have=%v", *tm);
+ }
+ }
+}
+
+export func TestSecondsToLocalTime(t *testing.T) {
+ for i := 0; i < len(localtests); i++ {
+ sec := localtests[i].seconds;
+ golden := &localtests[i].golden;
+ tm := SecondsToLocalTime(sec);
+ newsec := tm.Seconds();
+ if newsec != sec {
+ t.Errorf("SecondsToLocalTime(%d).Seconds() = %d", sec, newsec);
+ }
+ if !Same(tm, golden) {
+ t.Errorf("SecondsToLocalTime(%d):", sec);
+ t.Errorf(" want=%v", *golden);
+ t.Errorf(" have=%v", *tm);
+ }
+ }
+}
+