Updated testing
Added svgWriter Refactored
This commit is contained in:
parent
09ccafb97b
commit
9a21ca4d26
3
.gitignore
vendored
3
.gitignore
vendored
@ -93,7 +93,6 @@ $RECYCLE.BIN/
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
@ -103,3 +102,5 @@ $RECYCLE.BIN/
|
||||
.vscode/*
|
||||
|
||||
.idea
|
||||
/clockface/clockface
|
||||
*.svg
|
||||
|
12
clockface.go
12
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())))
|
||||
}
|
||||
|
@ -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(`<line x1="150" y1="150" x2="%f" y2="%f" style="fill:none;stroke:#f00;stroke-width:3px;"/>`, p.X, p.Y)
|
||||
}
|
||||
|
||||
const svgStart = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 300 300"
|
||||
version="2.0">`
|
||||
|
||||
const bezel = `<circle cx="150" cy="150" r="100" style="fill:#fff;stroke:#000;stroke-width:5px;"/>`
|
||||
|
||||
const svgEnd = `</svg>`
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
39
svgWriter.go
Normal file
39
svgWriter.go
Normal file
@ -0,0 +1,39 @@
|
||||
package clockface
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
const secondHandLength = 90
|
||||
const clockCentreX = 150
|
||||
const clockCentreY = 150
|
||||
|
||||
const svgStart = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 300 300"
|
||||
version="2.0">`
|
||||
|
||||
const bezel = `<circle cx="150" cy="150" r="100" style="fill:#fff;stroke:#000;stroke-width:5px;"/>`
|
||||
|
||||
const svgEnd = `</svg>`
|
||||
|
||||
//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, `<line x1="150" y1="150" x2="%.3f" y2="%.3f" style="fill:none;stroke:#f00;stroke-width:3px;"/>`, p.X, p.Y)
|
||||
}
|
Loading…
Reference in New Issue
Block a user