diff --git a/doc/images/segmentdisplaydemo.gif b/doc/images/segmentdisplaydemo.gif index 31f55b5..d0b1cce 100644 Binary files a/doc/images/segmentdisplaydemo.gif and b/doc/images/segmentdisplaydemo.gif differ diff --git a/internal/segdisp/dotseg/attributes_test.go b/internal/segdisp/dotseg/attributes_test.go new file mode 100644 index 0000000..807cdda --- /dev/null +++ b/internal/segdisp/dotseg/attributes_test.go @@ -0,0 +1,56 @@ +// Copyright 2019 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dotseg + +import ( + "image" + "testing" + + "github.com/kylelemons/godebug/pretty" +) + +func TestAttributes(t *testing.T) { + tests := []struct { + desc string + brailleAr image.Rectangle + seg Segment + want image.Rectangle + wantErr bool + }{ + { + desc: "fails on unsupported segment", + brailleAr: image.Rect(0, 0, 1, 1), + seg: Segment(-1), + wantErr: true, + }, + } + + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + attr := newAttributes(tc.brailleAr) + got, err := attr.segArea(tc.seg) + if (err != nil) != tc.wantErr { + t.Errorf("segArea => unexpected error: %v, wantErr: %v", err, tc.wantErr) + } + if err != nil { + return + } + + if diff := pretty.Compare(tc.want, got); diff != "" { + t.Errorf("segArea => unexpected diff (-want, +got):\n%s", diff) + } + }) + } +} diff --git a/internal/segdisp/dotseg/dotseg_test.go b/internal/segdisp/dotseg/dotseg_test.go index 47d1b2d..2537e77 100644 --- a/internal/segdisp/dotseg/dotseg_test.go +++ b/internal/segdisp/dotseg/dotseg_test.go @@ -31,6 +31,34 @@ import ( "github.com/mum4k/termdash/internal/segdisp/segment/testsegment" ) +func TestSegmentString(t *testing.T) { + tests := []struct { + desc string + seg Segment + want string + }{ + { + desc: "known segment", + seg: D1, + want: "D1", + }, + { + desc: "unknown segment", + seg: Segment(-1), + want: "SegmentUnknown", + }, + } + + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + got := tc.seg.String() + if got != tc.want { + t.Errorf("String => %q, want %q", got, tc.want) + } + }) + } +} + func TestDraw(t *testing.T) { tests := []struct { desc string @@ -129,7 +157,7 @@ func TestDraw(t *testing.T) { }, }, { - desc: "smallest valid display 6x5, all segments, sets cell options", + desc: "smallest valid display 6x5, all segments, New sets cell options", opts: []Option{ CellOpts( cell.FgColor(cell.ColorRed), @@ -162,6 +190,40 @@ func TestDraw(t *testing.T) { return ft }, }, + { + desc: "smallest valid display 6x5, all segments, Draw sets cell options", + drawOpts: []Option{ + CellOpts( + cell.FgColor(cell.ColorRed), + cell.BgColor(cell.ColorGreen), + ), + }, + cellCanvas: image.Rect(0, 0, segdisp.MinCols, segdisp.MinRows), + update: func(d *Display) error { + for _, seg := range AllSegments() { + if err := d.SetSegment(seg); err != nil { + return err + } + } + return nil + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + opts := []segment.Option{ + segment.CellOpts( + cell.FgColor(cell.ColorRed), + cell.BgColor(cell.ColorGreen), + ), + } + testsegment.MustHV(bc, image.Rect(5, 6, 7, 8), segment.Horizontal, opts...) // D1 + testsegment.MustHV(bc, image.Rect(5, 12, 7, 14), segment.Horizontal, opts...) // D2 + testsegment.MustHV(bc, image.Rect(5, 15, 7, 17), segment.Horizontal, opts...) // D5 + testbraille.MustApply(bc, ft) + return ft + }, + }, { desc: "smallest valid display 6x5, D1", cellCanvas: image.Rect(0, 0, segdisp.MinCols, segdisp.MinRows), @@ -207,6 +269,145 @@ func TestDraw(t *testing.T) { return ft }, }, + { + desc: "clears segment", + cellCanvas: image.Rect(0, 0, segdisp.MinCols, segdisp.MinRows), + update: func(d *Display) error { + for _, seg := range AllSegments() { + if err := d.SetSegment(seg); err != nil { + return err + } + } + return d.ClearSegment(D1) + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + testsegment.MustHV(bc, image.Rect(5, 12, 7, 14), segment.Horizontal) // D2 + testsegment.MustHV(bc, image.Rect(5, 15, 7, 17), segment.Horizontal) // D3 + testbraille.MustApply(bc, ft) + return ft + }, + }, + { + desc: "clears the display", + cellCanvas: image.Rect(0, 0, segdisp.MinCols, segdisp.MinRows), + update: func(d *Display) error { + for _, seg := range AllSegments() { + if err := d.SetSegment(seg); err != nil { + return err + } + } + d.Clear() + return nil + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + return ft + }, + }, + { + desc: "clear sets new cell options", + cellCanvas: image.Rect(0, 0, segdisp.MinCols, segdisp.MinRows), + update: func(d *Display) error { + d.Clear(CellOpts( + cell.FgColor(cell.ColorRed), + cell.BgColor(cell.ColorGreen), + )) + for _, seg := range AllSegments() { + if err := d.SetSegment(seg); err != nil { + return err + } + } + return nil + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + opts := []segment.Option{ + segment.CellOpts( + cell.FgColor(cell.ColorRed), + cell.BgColor(cell.ColorGreen), + ), + } + testsegment.MustHV(bc, image.Rect(5, 6, 7, 8), segment.Horizontal, opts...) // D1 + testsegment.MustHV(bc, image.Rect(5, 12, 7, 14), segment.Horizontal, opts...) // D2 + testsegment.MustHV(bc, image.Rect(5, 15, 7, 17), segment.Horizontal, opts...) // D5 + testbraille.MustApply(bc, ft) + return ft + }, + }, + { + desc: "toggles segment off", + cellCanvas: image.Rect(0, 0, segdisp.MinCols, segdisp.MinRows), + update: func(d *Display) error { + for _, seg := range AllSegments() { + if err := d.SetSegment(seg); err != nil { + return err + } + } + return d.ToggleSegment(D1) + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + testsegment.MustHV(bc, image.Rect(5, 12, 7, 14), segment.Horizontal) // D2 + testsegment.MustHV(bc, image.Rect(5, 15, 7, 17), segment.Horizontal) // D3 + testbraille.MustApply(bc, ft) + return ft + }, + }, + { + desc: "toggles segment on", + cellCanvas: image.Rect(0, 0, segdisp.MinCols, segdisp.MinRows), + update: func(d *Display) error { + for _, seg := range AllSegments() { + if err := d.SetSegment(seg); err != nil { + return err + } + } + if err := d.ToggleSegment(D1); err != nil { + return err + } + return d.ToggleSegment(D1) + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + testsegment.MustHV(bc, image.Rect(5, 6, 7, 8), segment.Horizontal) // D1 + testsegment.MustHV(bc, image.Rect(5, 12, 7, 14), segment.Horizontal) // D2 + testsegment.MustHV(bc, image.Rect(5, 15, 7, 17), segment.Horizontal) // D3 + testbraille.MustApply(bc, ft) + return ft + }, + }, + + { + desc: "larger display 18x15, all segments", + cellCanvas: image.Rect(0, 0, 3*segdisp.MinCols, 3*segdisp.MinRows), + update: func(d *Display) error { + for _, seg := range AllSegments() { + if err := d.SetSegment(seg); err != nil { + return err + } + } + return nil + }, + want: func(size image.Point) *faketerm.Terminal { + ft := faketerm.MustNew(size) + bc := testbraille.MustNew(ft.Area()) + + testsegment.MustHV(bc, image.Rect(15, 18, 21, 24), segment.Horizontal) // D1 + testsegment.MustHV(bc, image.Rect(15, 36, 21, 42), segment.Horizontal) // D2 + testsegment.MustHV(bc, image.Rect(15, 51, 21, 57), segment.Horizontal) // D3 + testbraille.MustApply(bc, ft) + return ft + }, + }, } for _, tc := range tests { diff --git a/widgets/segmentdisplay/segmentdisplaydemo/segmentdisplaydemo.go b/widgets/segmentdisplay/segmentdisplaydemo/segmentdisplaydemo.go index d8162e1..7b69cbd 100644 --- a/widgets/segmentdisplay/segmentdisplaydemo/segmentdisplaydemo.go +++ b/widgets/segmentdisplay/segmentdisplaydemo/segmentdisplaydemo.go @@ -43,7 +43,7 @@ func clock(ctx context.Context, sd *segmentdisplay.SegmentDisplay) { spacer := " " if now.Second()%2 == 0 { - spacer = "_" + spacer = ":" } chunks := []*segmentdisplay.TextChunk{ segmentdisplay.NewChunk(parts[0], segmentdisplay.WriteCellOpts(cell.FgColor(cell.ColorBlue))),