Skip to content

Commit

Permalink
Merge pull request #1 from aquilax/calculate-expressions
Browse files Browse the repository at this point in the history
Calculate expressions
  • Loading branch information
howeyc committed Nov 15, 2015
2 parents 2c34d73 + d3d9925 commit 40bfc96
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 3 deletions.
22 changes: 19 additions & 3 deletions parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ package ledger
import (
"bufio"
"fmt"
"github.com/marcmak/calc/calc"
"io"
"math/big"
"sort"
"strings"
"time"
)

const (
WHITESPACE = " \t"
)

// Parses a ledger file and returns a list of Transactions.
//
// Transactions are sorted by date.
Expand Down Expand Up @@ -46,16 +51,17 @@ func ParseLedger(ledgerReader io.Reader) (generalLedger []*Transaction, err erro
trans = &Transaction{Payee: payeeString, Date: transDate}
} else {
var accChange Account
lineSplit := strings.Split(line, " ")
// remove heading and tailing space from the line
line = strings.Trim(line, WHITESPACE)
lineSplit := strings.Split(line, " ")
nonEmptyWords := []string{}
for _, word := range lineSplit {
if len(word) > 0 {
nonEmptyWords = append(nonEmptyWords, word)
}
}
lastIndex := len(nonEmptyWords) - 1
rationalNum := new(big.Rat)
_, balErr := rationalNum.SetString(nonEmptyWords[lastIndex])
balErr, rationalNum := getBalance(strings.Trim(nonEmptyWords[lastIndex], WHITESPACE))
if balErr == false {
// Assuming no balance and whole line is account name
accChange.Name = strings.Join(nonEmptyWords, " ")
Expand All @@ -80,6 +86,16 @@ func ParseLedger(ledgerReader io.Reader) (generalLedger []*Transaction, err erro
return generalLedger, scanner.Err()
}

func getBalance(balance string) (bool, *big.Rat) {
rationalNum := new(big.Rat)
if strings.Contains(balance, "(") {
rationalNum.SetFloat64(calc.Solve(balance))
return true, rationalNum
}
_, isValid := rationalNum.SetString(balance)
return isValid, rationalNum
}

// Takes a transaction and balances it. This is mainly to fill in the empty part
// with the remaining balance.
func balanceTransaction(input *Transaction) error {
Expand Down
56 changes: 56 additions & 0 deletions parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package ledger

import (
"bytes"
"encoding/json"
"math/big"
"testing"
"time"
)

type testCase struct {
data string
transactions []*Transaction
err error
}

var testCases = []testCase{
testCase{
`1970/01/01 Payee
Expense/test (123 * 3)
Assets
`,
[]*Transaction{
&Transaction{
Payee: "Payee",
Date: time.Unix(0, 0).UTC(),
AccountChanges: []Account{
Account{
"Expense/test",
big.NewRat(369.0, 1),
},
Account{
"Assets",
big.NewRat(-369.0, 1),
},
},
},
},
nil,
},
}

func TestParseLedger(t *testing.T) {
for _, tc := range testCases {
b := bytes.NewBufferString(tc.data)
transactions, err := ParseLedger(b)
if err != tc.err {
t.Errorf("Error: expected `%s`, got `%s`", tc.err, err)
}
exp, _ := json.Marshal(tc.transactions)
got, _ := json.Marshal(transactions)
if string(exp) != string(got) {
t.Errorf("Error: expected \n`%s`, \ngot \n`%s`", exp, got)
}
}
}

0 comments on commit 40bfc96

Please sign in to comment.