Skip to content

Commit

Permalink
File Tests. Project builds.
Browse files Browse the repository at this point in the history
I finally redid the file tests. Files were taking in a deck before, but
now they don't and they return lists. This is a much better approach,
because the deck object has a lot of extra information.

This commit builds, but doesn't run. There is a problem with the deck
filter logic. I need to add tests for that next and fix the problem.
  • Loading branch information
alanxoc3 committed Sep 28, 2020
1 parent 89390d0 commit 4d35955
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 142 deletions.
12 changes: 6 additions & 6 deletions internal/deck/deck.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func (d *Deck) RemoveDone() {
})
}

type CardsFunc func(string) (card.CardMap, error)
type CardsFunc func(string) ([]*card.Card, error)

// TODO: Concurrency locks for thread safety?
func (d *Deck) Edit(rf CardsFunc, ef CardsFunc) error {
Expand All @@ -199,24 +199,24 @@ func (d *Deck) Edit(rf CardsFunc, ef CardsFunc) error {
filename := curCard.File()

// Step 3: Get the current state of the file before editing it.
beforeMap, e := rf(filename)
if e != nil {
return e
}
beforeList, e := rf(filename)
if e != nil { return e }

// Step 4: Execute the edit function.
afterMap, e := ef(filename)
afterList, e := ef(filename)
if e != nil {
return e
}

// Step 5: Remove cards that no longer exist.
afterMap := cardListToMap(afterList)
d.filter(func(i int, h internal.Hash) bool {
_, contains := afterMap[h]
return afterMap[h].File() != filename || contains
})

// Step 6: Add all the cards new after editing.
beforeMap := cardListToMap(beforeList)
for k, v := range afterMap {
if _, exist := beforeMap[k]; !exist {
if _, exist := d.predictMap[k]; !exist {
Expand Down
13 changes: 11 additions & 2 deletions internal/deck/deck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestAddCardsPredictSameNext(t *testing.T) {
d := deck.NewDeck(ONE_DATE)
c1, _ := card.NewCards(".", "hi : yo")
d.AddCards(c1...)
p := meta.NewPredictFromStrings(c1[0].Hash().String(), "", "2020-01-01T00:00:00Z")
p := meta.NewPredictFromStrings(c1[0].Hash().String(), "2020-01-01T00:00:00Z")
d.AddPredicts(p)
assert.Equal(t, 2, d.ReviewLen())
assert.Equal(t, 0, d.FutureLen())
Expand All @@ -51,7 +51,16 @@ func TestCardList(t *testing.T) {
func TestPredictList(t *testing.T) {
d := deck.NewDeck(ONE_DATE)
h := internal.NewHash("fad")
p := meta.NewPredictFromStrings(h.String(), "", "2020-01-01T00:00:00Z")
p := meta.NewPredictFromStrings(h.String(), "2020-01-01T00:00:00Z")
d.AddPredicts(p)
assert.Equal(t, []meta.Predict{*p}, d.PredictList())
}

// TODO! Do this!
func TestFilterMemorize(t *testing.T) {
d := deck.NewDeck(ONE_DATE)
h := internal.NewHash("fad")
p := meta.NewPredictFromStrings(h.String(), "2020-01-01T00:00:00Z")
d.AddPredicts(p)
assert.Equal(t, []meta.Predict{*p}, d.PredictList())
}
14 changes: 13 additions & 1 deletion internal/deck/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import (
"time"

"github.com/alanxoc3/concards/internal"
"github.com/alanxoc3/concards/internal/card"
"github.com/alanxoc3/concards/internal/meta"
)

type predicate func(int, internal.Hash) bool

func (d *Deck) cloneInfo(o *Deck) {
d.stack.SetTime(o.stack.Time())
d.stack.SetTime(o.stack.Time())
d.predictMap = map[internal.Hash]*meta.Predict{}
for k, v := range o.predictMap {
d.predictMap[k] = v
Expand Down Expand Up @@ -38,3 +39,14 @@ func (d *Deck) filter(p predicate) {
func beforeOrEqual(t1 time.Time, t2 time.Time) bool {
return t1.Before(t2) || t1.Equal(t2)
}

func cardListToMap(cl []*card.Card) card.CardMap {
cm := card.CardMap{}
for _, c := range cl {
h := c.Hash()
if _, exist := cm[h]; !exist {
cm[h] = c
}
}
return cm
}
4 changes: 2 additions & 2 deletions internal/file/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/alanxoc3/concards/internal/card"
)

func EditCards(filename string, cfg *Config) (card.CardMap, error) {
func EditCards(filename string, cfg *Config) ([]*card.Card, error) {
internal.AssertLogic(cfg != nil, "config was nil when passed to edit function")

// Load the file with your favorite editor.
Expand All @@ -21,5 +21,5 @@ func EditCards(filename string, cfg *Config) (card.CardMap, error) {
return nil, fmt.Errorf("Error: The editor returned an error code.")
}

return ReadCards(filename)
return ReadCardsFromFile(filename)
}
117 changes: 29 additions & 88 deletions internal/file/file_test.go
Original file line number Diff line number Diff line change
@@ -1,92 +1,33 @@
package file

import "testing"
import "strings"
import "github.com/alanxoc3/concards/core"

const f1 = "@> hello there | i'm a beard <@"
const c1 = "c435597dd9718c64b135087e944fd614 2020-01-01T00:00:00Z 3 sm2 2.5"

const f2 = " @> hi | hello @> yoyo man go <@"
const c2 = "19d480d8751e75494e70e65c18cc7fac 2020-01-11T00:00:00Z 2 sm2 .00001"

const c3 = `19d480d8751e75494e70e65c18cc7fac 2020-01-01T00:00:00Z 2 sm2 .00001
c435597dd9718c64b135087e944fd614 2020-01-11T00:00:00Z 3 sm2 .05
b718c81a83d82bb83f82b0a8b18bb82b 2020-01-11T00:00:00Z 27 sm2 .05
`

func TestReadMetasToDeck(t *testing.T) {
d := core.NewDeck()
ReadCardsToDeckHelper(strings.NewReader(f1+f2), d, "")
ReadMetasToDeckHelper(strings.NewReader(c1), d)

for i := 0; i < d.Len(); i++ {
_, c, m := d.Get(i)
switch i {
case 0:
if c.GetFactRaw(0) != "hello there" {
t.Fail()
}
if m.NextStr() != "2020-01-01T00:00:00Z" {
t.Fail()
}
if m.Streak != 3 {
t.Fail()
}
case 1:
}
}
}

func TestReadCardsToDeck(t *testing.T) {
d := core.NewDeck()
ReadCardsToDeckHelper(strings.NewReader(f2), d, "nihao")

for i := 0; i < d.Len(); i++ {
_, c, _ := d.Get(i)
switch i {
case 0:
if c.GetFactRaw(0) != "hi" {
t.Fail()
}
if c.GetFile() != "nihao" {
t.Fail()
}
case 1:
if c.GetFactRaw(0) != "yoyo man go" {
t.Fail()
}
}
}
}

func TestWriteMetasToString(t *testing.T) {
d := core.NewDeck()
ReadMetasToDeckHelper(strings.NewReader(c3), d)
str := WriteMetasToString(d)
a := strings.Split(str, "\n")
b := strings.Split(c3, "\n")

if a[0] != b[0] {
t.Fail()
}
if a[1] != b[2] {
t.Fail()
}
if a[2] != b[1] {
t.Fail()
}
package file_test

import (
"strings"
"testing"

"github.com/alanxoc3/concards/internal/card"
"github.com/alanxoc3/concards/internal/file"
"github.com/alanxoc3/concards/internal/meta"
"github.com/stretchr/testify/assert"
)

func TestReadCards(t *testing.T) {
fstr := " hello ye as \n @> hi | hello <@ asoe @> yoyo man go <@"
cards := file.ReadCardsFromReader(strings.NewReader(fstr), "file")
hi, _ := card.NewCards("file", "hi | hello")
yo, _ := card.NewCards("file", "yoyo man go")

assert.Equal(t, hi[0], cards[0])
assert.Equal(t, yo[0], cards[1])
}

/*
// This is a manual test.
func TestFile(t *testing.T) {
d := core.NewDeck()
ReadCardsToDeck(d, "../")
func TestReadPredicts(t *testing.T) {
fstr := `a 2020-02-01T00:00:00Z 2020-01-01T00:00:00Z 1 2 0 sm2
b 2020-02-01T00:00:00Z 2020-01-01T00:00:00Z 2 1 0 sm2
c 2020-02-01T00:00:00Z 2020-01-01T00:00:00Z 3 3 3 sm2`

for i := 0; i < d.Len(); i++ {
_, c, _ := d.Get(i)
println(c.String())
}
predicts := file.ReadPredictsFromReader(strings.NewReader(fstr))
assert.Len(t, predicts, 3)
assert.Equal(t, predicts[0], meta.NewPredictFromStrings("a", "2020-02-01T00:00:00Z", "2020-01-01T00:00:00Z", "1", "2", "0", "sm2"))
assert.Equal(t, predicts[1], meta.NewPredictFromStrings("b", "2020-02-01T00:00:00Z", "2020-01-01T00:00:00Z", "2", "1", "0", "sm2"))
assert.Equal(t, predicts[2], meta.NewPredictFromStrings("c", "2020-02-01T00:00:00Z", "2020-01-01T00:00:00Z", "3", "3", "3", "sm2"))
}
*/
38 changes: 20 additions & 18 deletions internal/file/metafile.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,45 @@ import (
"github.com/alanxoc3/concards/internal/meta"
)

// Open opens filename and loads cards into new deck
func ReadMetasToDeck(filename string, d *deck.Deck) error {
// Open filename and loads cards into new deck
func ReadPredictsFromFile(filename string) ([]*meta.Predict, error) {
if f, err := os.Open(filename); err != nil {
return fmt.Errorf("Error: Unable to open meta file \"%s\"", filename)
return nil, fmt.Errorf("Error: Unable to open meta file \"%s\".", filename)
} else {
defer f.Close()
ReadMetasToDeckHelper(f, d)
return nil
return ReadPredictsFromReader(f), nil
}
}

func ReadMetasToDeckHelper(r io.Reader, d *deck.Deck) {
func ReadPredictsFromReader(r io.Reader) []*meta.Predict {
// Scan by words.
lineScanner := bufio.NewScanner(r)
lineScanner.Split(bufio.ScanLines)
list := []*meta.Predict{}

for lineScanner.Scan() {
strs := strings.Fields(lineScanner.Text())

// Only add if there is something on the line.
if len(strs) > 0 {
d.AddPredicts(meta.NewPredictFromStrings(strs...))
list = append(list, meta.NewPredictFromStrings(strs...))
}
}

return list
}

func WritePredictsToFile(d *deck.Deck, filename string) error {
str := []byte(WritePredictsToString(d))
err := ioutil.WriteFile(filename, str, 0644)
if err != nil {
return fmt.Errorf("Error: Writing to \"%s\" failed.", filename)
}

return nil
}

func WriteMetasToString(d *deck.Deck) string {
func WritePredictsToString(d *deck.Deck) string {
predicts := d.PredictList()
predictStrings := make([]string, len(predicts))
for _, v := range predicts {
Expand All @@ -49,13 +61,3 @@ func WriteMetasToString(d *deck.Deck) string {
sort.Strings(predictStrings)
return strings.Join(predictStrings, "\n")
}

func WriteMetasToFile(d *deck.Deck, filename string) error {
str := []byte(WriteMetasToString(d))
err := ioutil.WriteFile(filename, str, 0644)
if err != nil {
return fmt.Errorf("Error: Writing to \"%s\" failed.", filename)
}

return nil
}
23 changes: 5 additions & 18 deletions internal/file/txtfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,9 @@ import (
"github.com/alanxoc3/concards/internal/card"
)

type cardList []*card.Card

func cardListToMap(cl cardList) card.CardMap {
cm := card.CardMap{}
for _, c := range cl {
h := c.Hash()
if _, exist := cm[h]; !exist {
cm[h] = c
}
}
return cm
}

// Open opens filename and loads cards into new deck
func ReadCards(filename string) (card.CardMap, error) {
cl := cardList{}
func ReadCardsFromFile(filename string) ([]*card.Card, error) {
cl := []*card.Card{}
err := filepath.Walk(filename, func(path string, info os.FileInfo, e error) error {
if e != nil {
return e
Expand All @@ -48,16 +35,16 @@ func ReadCards(filename string) (card.CardMap, error) {
return fmt.Errorf("Error: Unable to open file \"%s\"", filename)
} else {
defer f.Close()
cl = append(cl, readCardsFromReader(f, absPath)...)
cl = append(cl, ReadCardsFromReader(f, absPath)...)
}

return nil
})

return cardListToMap(cl), err
return cl, err
}

func readCardsFromReader(r io.Reader, f string) []*card.Card {
func ReadCardsFromReader(r io.Reader, f string) []*card.Card {
// Initialization.
cl := []*card.Card{}
facts := []string{}
Expand Down
4 changes: 2 additions & 2 deletions internal/termboxgui/tboxapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TermBoxRun(d *deck.Deck, cfg *file.Config) error {
} else if inp == "h" {
helpMode = !helpMode
} else if inp == "w" {
err = file.WriteMetasToFile(d, cfg.MetaFile)
err = file.WritePredictsToFile(d, cfg.MetaFile)
if err != nil {
updateStatMsg(err.Error(), termbox.ColorRed)
} else {
Expand All @@ -65,7 +65,7 @@ func TermBoxRun(d *deck.Deck, cfg *file.Config) error {
d.DropTop()
save(d)
} else if inp == "e" {
err := d.Edit(file.ReadCards, func(filename string) (card.CardMap, error) {
err := d.Edit(file.ReadCardsFromFile, func(filename string) ([]*card.Card, error) {
return file.EditCards(filename, cfg)
})

Expand Down
15 changes: 10 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@ func main() {
d := deck.NewDeck(time.Now())

// We don't care if there is no meta data.
file.ReadMetasToDeck(c.MetaFile, d)
if predicts, err := file.ReadPredictsFromFile(c.MetaFile); err != nil {
fmt.Fprintf(os.Stderr, "Error: Unable to open meta file \"%s\".", c.MetaFile)
os.Exit(1)
} else {
d.AddPredicts(predicts...)
}

if len(c.Files) == 0 {
fmt.Printf("Error: You didn't provide any files to parse.\n")
fmt.Fprintf(os.Stderr, "Error: You didn't provide any files to parse.\n")
os.Exit(1)
}

for _, f := range c.Files {
if cm, err := file.ReadCards(f); err != nil {
fmt.Printf("Error: File \"%s\" does not exist!\n", f)
if cm, err := file.ReadCardsFromFile(f); err != nil {
fmt.Fprintf(os.Stderr, "Error: File \"%s\" does not exist!\n", f)
os.Exit(1)
} else {
for _, c := range cm {
Expand Down Expand Up @@ -69,5 +74,5 @@ func main() {

rand.Seed(time.Now().UTC().UnixNano()) // Used for algorithms.
termboxgui.TermBoxRun(d, c)
_ = file.WriteMetasToFile(d, c.MetaFile)
_ = file.WritePredictsToFile(d, c.MetaFile)
}

0 comments on commit 4d35955

Please sign in to comment.