diff --git a/.gitignore b/.gitignore
index 085f9fd..8f46153 100644
--- a/.gitignore
+++ b/.gitignore
@@ -93,7 +93,6 @@ $RECYCLE.BIN/
*.msix
*.msm
*.msp
-
# Windows shortcuts
*.lnk
@@ -102,4 +101,6 @@ $RECYCLE.BIN/
# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option)
.vscode/*
-.idea
\ No newline at end of file
+.idea
+/clockface/clockface
+*.svg
diff --git a/clockface.go b/clockface.go
index b3bbe2c..642b645 100644
--- a/clockface.go
+++ b/clockface.go
@@ -5,23 +5,11 @@ import (
"time"
)
-const secondHandLength = 90
-const clockCentreX = 150
-const clockCentreY = 150
-
type Point struct {
X float64
Y float64
}
-func SecondHand(t time.Time) Point {
- p := secondHandPoint(t)
- p = Point{p.X * secondHandLength, p.Y * secondHandLength} //scale
- p = Point{p.X, -p.Y} //flip
- p = Point{p.X + clockCentreX, p.Y + clockCentreY} //translate
- return p
-}
-
func secondsInRadians(t time.Time) float64 {
return math.Pi / (30 / (float64(t.Second())))
}
diff --git a/clockface/main.go b/clockface/main.go
index 1600381..9ab799d 100644
--- a/clockface/main.go
+++ b/clockface/main.go
@@ -1,34 +1,12 @@
package main
import (
- "fmt"
"git.nerdfortress.dev/mitch/clockface"
- "io"
"os"
"time"
)
func main() {
t := time.Now()
- sh := clockface.SecondHand(t)
- io.WriteString(os.Stdout, svgStart)
- io.WriteString(os.Stdout, bezel)
- io.WriteString(os.Stdout, secondHandTag(sh))
- io.WriteString(os.Stdout, svgEnd)
+ clockface.SVGWriter(os.Stdout, t)
}
-
-func secondHandTag(p clockface.Point) string {
- return fmt.Sprintf(``, p.X, p.Y)
-}
-
-const svgStart = `
-
-`
diff --git a/clockface_acceptance_test.go b/clockface_acceptance_test.go
index a47d890..24e804b 100644
--- a/clockface_acceptance_test.go
+++ b/clockface_acceptance_test.go
@@ -1,28 +1,55 @@
package clockface
import (
+ "bytes"
+ "encoding/xml"
"testing"
"time"
)
-func TestSecondHandAtMidnight(t *testing.T) {
+type Svg struct {
+ XMLName xml.Name `xml:"svg"`
+ Text string `xml:",chardata"`
+ Xmlns string `xml:"xmlns,attr"`
+ Width string `xml:"width,attr"`
+ Height string `xml:"height,attr"`
+ ViewBox string `xml:"viewBox,attr"`
+ Version string `xml:"version,attr"`
+ Circle struct {
+ Text string `xml:",chardata"`
+ Cx string `xml:"cx,attr"`
+ Cy string `xml:"cy,attr"`
+ R string `xml:"r,attr"`
+ Style string `xml:"style,attr"`
+ } `xml:"circle"`
+ Line []struct {
+ Text string `xml:",chardata"`
+ X1 string `xml:"x1,attr"`
+ Y1 string `xml:"y1,attr"`
+ X2 string `xml:"x2,attr"`
+ Y2 string `xml:"y2,attr"`
+ Style string `xml:"style,attr"`
+ } `xml:"line"`
+}
+
+func TestSVGWriterAtMidnight(t *testing.T) {
tm := time.Date(1337, time.January, 1, 0, 0, 0, 0, time.UTC)
+ b := bytes.Buffer{}
- want := Point{X: 150, Y: 150 - 90}
- got := SecondHand(tm)
+ SVGWriter(&b, tm)
- if got != want {
- t.Errorf("Got %v, want %v", got, want)
- }
-}
-
-func TestSecondHandAt30Seconds(t *testing.T) {
- tm := time.Date(1337, time.January, 1, 0, 0, 30, 0, time.UTC)
-
- want := Point{X: 150, Y: 150 + 90}
- got := SecondHand(tm)
-
- if got != want {
- t.Errorf("Got %v, wanted %v", got, want)
+ svg := Svg{}
+
+ xml.Unmarshal(b.Bytes(), &svg)
+
+ x2 := "150.000"
+ y2 := "60.000"
+
+ for _, line := range svg.Line {
+ if line.X2 == x2 && line.Y2 == y2 {
+ return
+ }
}
+
+ t.Errorf("Expected to find the second hand with x2 of %v and y2 of %v, in the SVG output %v", x2, y2, b.String())
}
diff --git a/clockface_test.go b/clockface_test.go
index 7104169..6bed993 100644
--- a/clockface_test.go
+++ b/clockface_test.go
@@ -6,14 +6,6 @@ import (
"time"
)
-func simpleTime(hours, minutes, seconds int) time.Time {
- return time.Date(312, time.October, 28, hours, minutes, seconds, 0, time.UTC)
-}
-
-func testName(t time.Time) string {
- return t.Format("15:04:05")
-}
-
func TestSecondsInRadians(t *testing.T) {
cases := []struct {
time time.Time
@@ -28,14 +20,14 @@ func TestSecondsInRadians(t *testing.T) {
for _, c := range cases {
t.Run(testName(c.time), func(t *testing.T) {
got := secondsInRadians(c.time)
- if !roughlyEqualFloat64(got, c.angle) {
+ if got != c.angle {
t.Fatalf("Wanted %v radians, but got %v", c.angle, got)
}
})
}
}
-func TestSecondHandVector(t *testing.T) {
+func TestSecondHandPoint(t *testing.T) {
cases := []struct {
time time.Time
point Point
@@ -63,3 +55,11 @@ func roughlyEqualPoint(a, b Point) bool {
return roughlyEqualFloat64(a.X, b.X) &&
roughlyEqualFloat64(a.Y, b.Y)
}
+
+func simpleTime(hours, minutes, seconds int) time.Time {
+ return time.Date(312, time.October, 28, hours, minutes, seconds, 0, time.UTC)
+}
+
+func testName(t time.Time) string {
+ return t.Format("15:04:05")
+}
diff --git a/svgWriter.go b/svgWriter.go
new file mode 100644
index 0000000..5143bf6
--- /dev/null
+++ b/svgWriter.go
@@ -0,0 +1,39 @@
+package clockface
+
+import (
+ "fmt"
+ "io"
+ "time"
+)
+
+const secondHandLength = 90
+const clockCentreX = 150
+const clockCentreY = 150
+
+const svgStart = `
+
+`
+
+//SVGWriter writes an SVG representation of an analog clock, showing the time t, to the writer w
+func SVGWriter(w io.Writer, t time.Time) {
+ io.WriteString(w, svgStart)
+ io.WriteString(w, bezel)
+ SecondHand(w, t)
+ io.WriteString(w, svgEnd)
+}
+
+func SecondHand(w io.Writer, t time.Time) {
+ p := secondHandPoint(t)
+ p = Point{p.X * secondHandLength, p.Y * secondHandLength} //scale
+ p = Point{p.X, -p.Y} //flip
+ p = Point{p.X + clockCentreX, p.Y + clockCentreY} //translate
+ fmt.Fprintf(w, ``, p.X, p.Y)
+}