Switch Amount to contain big.Rat instead of being a typedef

This commit is contained in:
Aaron Lindsay 2017-04-03 21:15:08 -04:00
parent 9b03829645
commit 7f5ef5751d
6 changed files with 80 additions and 90 deletions

View File

@ -2,7 +2,6 @@ package ofxgo_test
import ( import (
"github.com/aclindsa/ofxgo" "github.com/aclindsa/ofxgo"
"math/big"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -153,7 +152,7 @@ func TestUnmarshalBankStatementResponse(t *testing.T) {
expected.Signon.Org = "BNK" expected.Signon.Org = "BNK"
expected.Signon.Fid = "1987" expected.Signon.Fid = "1987"
var trnamt1, trnamt2 big.Rat var trnamt1, trnamt2 ofxgo.Amount
trnamt1.SetFrac64(-20000, 100) trnamt1.SetFrac64(-20000, 100)
trnamt2.SetFrac64(-30000, 100) trnamt2.SetFrac64(-30000, 100)
dtuser2 := ofxgo.Date(time.Date(2006, 1, 12, 0, 0, 0, 0, GMT)) dtuser2 := ofxgo.Date(time.Date(2006, 1, 12, 0, 0, 0, 0, GMT))
@ -165,7 +164,7 @@ func TestUnmarshalBankStatementResponse(t *testing.T) {
{ {
TrnType: "CHECK", TrnType: "CHECK",
DtPosted: ofxgo.Date(time.Date(2006, 1, 4, 0, 0, 0, 0, GMT)), DtPosted: ofxgo.Date(time.Date(2006, 1, 4, 0, 0, 0, 0, GMT)),
TrnAmt: ofxgo.Amount(trnamt1), TrnAmt: trnamt1,
FiTId: "00592", FiTId: "00592",
CheckNum: "2002", CheckNum: "2002",
}, },
@ -173,13 +172,13 @@ func TestUnmarshalBankStatementResponse(t *testing.T) {
TrnType: "ATM", TrnType: "ATM",
DtPosted: ofxgo.Date(time.Date(2006, 1, 12, 0, 0, 0, 0, GMT)), DtPosted: ofxgo.Date(time.Date(2006, 1, 12, 0, 0, 0, 0, GMT)),
DtUser: &dtuser2, DtUser: &dtuser2,
TrnAmt: ofxgo.Amount(trnamt2), TrnAmt: trnamt2,
FiTId: "00679", FiTId: "00679",
}, },
}, },
} }
var balamt, availbalamt big.Rat var balamt, availbalamt ofxgo.Amount
balamt.SetFrac64(20029, 100) balamt.SetFrac64(20029, 100)
availbalamt.SetFrac64(20029, 100) availbalamt.SetFrac64(20029, 100)
@ -198,9 +197,9 @@ func TestUnmarshalBankStatementResponse(t *testing.T) {
AcctType: "CHECKING", AcctType: "CHECKING",
}, },
BankTranList: &banktranlist, BankTranList: &banktranlist,
BalAmt: ofxgo.Amount(balamt), BalAmt: balamt,
DtAsOf: ofxgo.Date(time.Date(2006, 1, 14, 16, 0, 0, 0, GMT)), DtAsOf: ofxgo.Date(time.Date(2006, 1, 14, 16, 0, 0, 0, GMT)),
AvailBalAmt: (*ofxgo.Amount)(&availbalamt), AvailBalAmt: &availbalamt,
AvailDtAsOf: &availdtasof, AvailDtAsOf: &availdtasof,
} }
expected.Bank = append(expected.Bank, &statementResponse) expected.Bank = append(expected.Bank, &statementResponse)

View File

@ -4,7 +4,6 @@ import (
"flag" "flag"
"fmt" "fmt"
"github.com/aclindsa/ofxgo" "github.com/aclindsa/ofxgo"
"math/big"
"os" "os"
) )
@ -65,7 +64,7 @@ func invTransactions() {
} }
if stmt, ok := response.InvStmt[0].(*ofxgo.InvStatementResponse); ok { if stmt, ok := response.InvStmt[0].(*ofxgo.InvStatementResponse); ok {
availCash := big.Rat(stmt.InvBal.AvailCash) availCash := stmt.InvBal.AvailCash
if availCash.IsInt() && availCash.Num().Int64() != 0 { if availCash.IsInt() && availCash.Num().Int64() != 0 {
fmt.Printf("Balance: %s %s (as of %s)\n", stmt.InvBal.AvailCash, stmt.CurDef, stmt.DtAsOf) fmt.Printf("Balance: %s %s (as of %s)\n", stmt.InvBal.AvailCash, stmt.CurDef, stmt.DtAsOf)
} }

View File

@ -2,7 +2,6 @@ package ofxgo_test
import ( import (
"github.com/aclindsa/ofxgo" "github.com/aclindsa/ofxgo"
"math/big"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -99,7 +98,7 @@ NEWFILEUID:NONE
expected.Signon.Org = "01" expected.Signon.Org = "01"
expected.Signon.Fid = "81729" expected.Signon.Fid = "81729"
var trnamt1, trnamt2, trnamt3 big.Rat var trnamt1, trnamt2, trnamt3 ofxgo.Amount
trnamt1.SetFrac64(-796, 100) trnamt1.SetFrac64(-796, 100)
trnamt2.SetFrac64(383046, 100) trnamt2.SetFrac64(383046, 100)
trnamt3.SetFrac64(-1770, 100) trnamt3.SetFrac64(-1770, 100)
@ -111,28 +110,28 @@ NEWFILEUID:NONE
{ {
TrnType: "DEBIT", TrnType: "DEBIT",
DtPosted: ofxgo.Date(time.Date(2017, 2, 9, 12, 0, 0, 0, GMT)), DtPosted: ofxgo.Date(time.Date(2017, 2, 9, 12, 0, 0, 0, GMT)),
TrnAmt: ofxgo.Amount(trnamt1), TrnAmt: trnamt1,
FiTId: "2017020924435657040207171600195", FiTId: "2017020924435657040207171600195",
Name: "SLICE OF NY", Name: "SLICE OF NY",
}, },
{ {
TrnType: "CREDIT", TrnType: "CREDIT",
DtPosted: ofxgo.Date(time.Date(2016, 12, 28, 12, 0, 0, 0, GMT)), DtPosted: ofxgo.Date(time.Date(2016, 12, 28, 12, 0, 0, 0, GMT)),
TrnAmt: ofxgo.Amount(trnamt2), TrnAmt: trnamt2,
FiTId: "2016122823633637200000258482730", FiTId: "2016122823633637200000258482730",
Name: "Payment Thank You Electro", Name: "Payment Thank You Electro",
}, },
{ {
TrnType: "DEBIT", TrnType: "DEBIT",
DtPosted: ofxgo.Date(time.Date(2017, 3, 27, 12, 0, 0, 0, GMT)), DtPosted: ofxgo.Date(time.Date(2017, 3, 27, 12, 0, 0, 0, GMT)),
TrnAmt: ofxgo.Amount(trnamt3), TrnAmt: trnamt3,
FiTId: "2017032724445727085300442885680", FiTId: "2017032724445727085300442885680",
Name: "KROGER FUEL #9999", Name: "KROGER FUEL #9999",
}, },
}, },
} }
var balamt, availbalamt big.Rat var balamt, availbalamt ofxgo.Amount
balamt.SetFrac64(-933400, 100) balamt.SetFrac64(-933400, 100)
availbalamt.SetFrac64(763017, 100) availbalamt.SetFrac64(763017, 100)
@ -149,9 +148,9 @@ NEWFILEUID:NONE
AcctId: "9283744488463775", AcctId: "9283744488463775",
}, },
BankTranList: &banktranlist, BankTranList: &banktranlist,
BalAmt: ofxgo.Amount(balamt), BalAmt: balamt,
DtAsOf: ofxgo.Date(time.Date(2017, 3, 31, 8, 0, 0, 0, EDT)), DtAsOf: ofxgo.Date(time.Date(2017, 3, 31, 8, 0, 0, 0, EDT)),
AvailBalAmt: (*ofxgo.Amount)(&availbalamt), AvailBalAmt: &availbalamt,
AvailDtAsOf: &availdtasof, AvailDtAsOf: &availdtasof,
} }
expected.CreditCard = append(expected.CreditCard, &statementResponse) expected.CreditCard = append(expected.CreditCard, &statementResponse)

View File

@ -2,7 +2,6 @@ package ofxgo_test
import ( import (
"github.com/aclindsa/ofxgo" "github.com/aclindsa/ofxgo"
"math/big"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -308,7 +307,7 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
expected.Signon.Org = "INVSTRUS" expected.Signon.Org = "INVSTRUS"
expected.Signon.Fid = "9999" expected.Signon.Fid = "9999"
var units1, unitprice1, commission1, total1, amount2 big.Rat var units1, unitprice1, commission1, total1, amount2 ofxgo.Amount
units1.SetFrac64(100, 1) units1.SetFrac64(100, 1)
unitprice1.SetFrac64(229, 1) unitprice1.SetFrac64(229, 1)
commission1.SetFrac64(9, 1) commission1.SetFrac64(9, 1)
@ -334,10 +333,10 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
UniqueId: "78462F103", UniqueId: "78462F103",
UniqueIdType: "CUSIP", UniqueIdType: "CUSIP",
}, },
Units: ofxgo.Amount(units1), Units: units1,
UnitPrice: ofxgo.Amount(unitprice1), UnitPrice: unitprice1,
Commission: ofxgo.Amount(commission1), Commission: commission1,
Total: ofxgo.Amount(total1), Total: total1,
SubAcctSec: "CASH", SubAcctSec: "CASH",
SubAcctFund: "CASH", SubAcctFund: "CASH",
}, },
@ -352,7 +351,7 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
DtPosted: ofxgo.Date(time.Date(2017, 1, 20, 0, 0, 0, 0, GMT)), DtPosted: ofxgo.Date(time.Date(2017, 1, 20, 0, 0, 0, 0, GMT)),
DtUser: &dtuser, DtUser: &dtuser,
DtAvail: &dtavail, DtAvail: &dtavail,
TrnAmt: ofxgo.Amount(amount2), TrnAmt: amount2,
FiTId: "993838", FiTId: "993838",
Name: "DEPOSIT", Name: "DEPOSIT",
Memo: "CHECK 19980", Memo: "CHECK 19980",
@ -363,7 +362,7 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
}, },
} }
var availcash, marginbalance, shortbalance, balvalue big.Rat var availcash, marginbalance, shortbalance, balvalue ofxgo.Amount
availcash.SetFrac64(1673, 100) availcash.SetFrac64(1673, 100)
marginbalance.SetFrac64(-8192, 10) marginbalance.SetFrac64(-8192, 10)
shortbalance.SetFrac64(0, 1) shortbalance.SetFrac64(0, 1)
@ -372,21 +371,21 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
baldtasof := ofxgo.Date(time.Date(2017, 4, 1, 0, 0, 0, 0, GMT)) baldtasof := ofxgo.Date(time.Date(2017, 4, 1, 0, 0, 0, 0, GMT))
invbalance := ofxgo.InvBalance{ invbalance := ofxgo.InvBalance{
AvailCash: ofxgo.Amount(availcash), AvailCash: availcash,
MarginBalance: ofxgo.Amount(marginbalance), MarginBalance: marginbalance,
ShortBalance: ofxgo.Amount(shortbalance), ShortBalance: shortbalance,
BalList: []ofxgo.Balance{ BalList: []ofxgo.Balance{
ofxgo.Balance{ ofxgo.Balance{
Name: "Sweep Int Rate", Name: "Sweep Int Rate",
Desc: "Current interest rate for sweep account balances", Desc: "Current interest rate for sweep account balances",
BalType: "PERCENT", BalType: "PERCENT",
Value: ofxgo.Amount(balvalue), Value: balvalue,
DtAsOf: &baldtasof, DtAsOf: &baldtasof,
}, },
}, },
} }
var balamt, availbalamt, posunits1, posunitprice1, posmktval1, posunits2, posunitprice2, posmktval2, oounits1, oolimitprice1, oounits2, oolimitprice2 big.Rat var balamt, availbalamt, posunits1, posunitprice1, posmktval1, posunits2, posunitprice2, posmktval2, oounits1, oolimitprice1, oounits2, oolimitprice2 ofxgo.Amount
balamt.SetFrac64(20029, 100) balamt.SetFrac64(20029, 100)
availbalamt.SetFrac64(20029, 100) availbalamt.SetFrac64(20029, 100)
posunits1.SetFrac64(200, 1) posunits1.SetFrac64(200, 1)
@ -422,9 +421,9 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
}, },
HeldInAcct: "CASH", HeldInAcct: "CASH",
PosType: "LONG", PosType: "LONG",
Units: ofxgo.Amount(posunits1), Units: posunits1,
UnitPrice: ofxgo.Amount(posunitprice1), UnitPrice: posunitprice1,
MktVal: ofxgo.Amount(posmktval1), MktVal: posmktval1,
DtPriceAsOf: ofxgo.Date(time.Date(2017, 3, 31, 16, 0, 0, 0, GMT)), DtPriceAsOf: ofxgo.Date(time.Date(2017, 3, 31, 16, 0, 0, 0, GMT)),
Memo: "Price as of previous close", Memo: "Price as of previous close",
}, },
@ -437,9 +436,9 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
}, },
HeldInAcct: "CASH", HeldInAcct: "CASH",
PosType: "LONG", PosType: "LONG",
Units: ofxgo.Amount(posunits2), Units: posunits2,
UnitPrice: ofxgo.Amount(posunitprice2), UnitPrice: posunitprice2,
MktVal: ofxgo.Amount(posmktval2), MktVal: posmktval2,
DtPriceAsOf: ofxgo.Date(time.Date(2017, 3, 31, 16, 0, 0, 0, GMT)), DtPriceAsOf: ofxgo.Date(time.Date(2017, 3, 31, 16, 0, 0, 0, GMT)),
}, },
}, },
@ -454,11 +453,11 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
UniqueIdType: "CUSIP", UniqueIdType: "CUSIP",
}, },
DtPlaced: ofxgo.Date(time.Date(2017, 3, 10, 12, 44, 45, 0, GMT)), DtPlaced: ofxgo.Date(time.Date(2017, 3, 10, 12, 44, 45, 0, GMT)),
Units: ofxgo.Amount(oounits1), Units: oounits1,
SubAcct: "CASH", SubAcct: "CASH",
Duration: "GOODTILCANCEL", Duration: "GOODTILCANCEL",
Restriction: "NONE", Restriction: "NONE",
LimitPrice: ofxgo.Amount(oolimitprice1), LimitPrice: oolimitprice1,
}, },
BuyType: "BUY", BuyType: "BUY",
UnitType: "SHARES", UnitType: "SHARES",
@ -471,11 +470,11 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
UniqueIdType: "CUSIP", UniqueIdType: "CUSIP",
}, },
DtPlaced: ofxgo.Date(time.Date(2017, 3, 24, 3, 19, 0, 0, GMT)), DtPlaced: ofxgo.Date(time.Date(2017, 3, 24, 3, 19, 0, 0, GMT)),
Units: ofxgo.Amount(oounits2), Units: oounits2,
SubAcct: "CASH", SubAcct: "CASH",
Duration: "GOODTILCANCEL", Duration: "GOODTILCANCEL",
Restriction: "ALLORNONE", Restriction: "ALLORNONE",
LimitPrice: ofxgo.Amount(oolimitprice2), LimitPrice: oolimitprice2,
}, },
BuyType: "BUY", BuyType: "BUY",
}, },
@ -483,7 +482,7 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
} }
expected.InvStmt = append(expected.InvStmt, &statementResponse) expected.InvStmt = append(expected.InvStmt, &statementResponse)
var yield1, yield2, strikeprice big.Rat var yield1, yield2, strikeprice ofxgo.Amount
yield1.SetFrac64(192, 100) yield1.SetFrac64(192, 100)
yield2.SetFrac64(17, 1) yield2.SetFrac64(17, 1)
strikeprice.SetFrac64(79, 1) strikeprice.SetFrac64(79, 1)
@ -500,7 +499,7 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
Ticker: "SPY", Ticker: "SPY",
FiId: "99184", FiId: "99184",
}, },
Yield: ofxgo.Amount(yield1), Yield: yield1,
AssetClass: "OTHER", AssetClass: "OTHER",
}, },
ofxgo.OptInfo{ ofxgo.OptInfo{
@ -514,7 +513,7 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
FiId: "882919", FiId: "882919",
}, },
OptType: "PUT", OptType: "PUT",
StrikePrice: ofxgo.Amount(strikeprice), StrikePrice: strikeprice,
DtExpire: ofxgo.Date(time.Date(2017, 9, 1, 0, 0, 0, 0, GMT)), DtExpire: ofxgo.Date(time.Date(2017, 9, 1, 0, 0, 0, 0, GMT)),
ShPerCtrct: 100, ShPerCtrct: 100,
SecId: &ofxgo.SecurityId{ SecId: &ofxgo.SecurityId{
@ -533,7 +532,7 @@ func TestUnmarshalInvStatementResponse(t *testing.T) {
Ticker: "WHAT", Ticker: "WHAT",
FiId: "883897", FiId: "883897",
}, },
Yield: ofxgo.Amount(yield2), Yield: yield2,
AssetClass: "SMALLSTOCK", AssetClass: "SMALLSTOCK",
}, },
ofxgo.MFInfo{ ofxgo.MFInfo{
@ -734,7 +733,7 @@ NEWFILEUID: NONE
expected.Signon.Fid = "1000" expected.Signon.Fid = "1000"
// Ignored <INTU.BID>1000 // Ignored <INTU.BID>1000
var units1, unitprice1, commission1, fees1, total1, units2, units3 big.Rat var units1, unitprice1, commission1, fees1, total1, units2, units3 ofxgo.Amount
units1.SetFrac64(-1, 1) units1.SetFrac64(-1, 1)
unitprice1.SetFrac64(35, 100) unitprice1.SetFrac64(35, 100)
commission1.SetFrac64(885, 100) commission1.SetFrac64(885, 100)
@ -762,11 +761,11 @@ NEWFILEUID: NONE
UniqueId: "SPY161216C00226000", UniqueId: "SPY161216C00226000",
UniqueIdType: "CUSIP", UniqueIdType: "CUSIP",
}, },
Units: ofxgo.Amount(units1), Units: units1,
UnitPrice: ofxgo.Amount(unitprice1), UnitPrice: unitprice1,
Commission: ofxgo.Amount(commission1), Commission: commission1,
Fees: ofxgo.Amount(fees1), Fees: fees1,
Total: ofxgo.Amount(total1), Total: total1,
SubAcctSec: "CASH", SubAcctSec: "CASH",
SubAcctFund: "CASH", SubAcctFund: "CASH",
}, },
@ -784,7 +783,7 @@ NEWFILEUID: NONE
UniqueIdType: "CUSIP", UniqueIdType: "CUSIP",
}, },
OptAction: "ASSIGN", OptAction: "ASSIGN",
Units: ofxgo.Amount(units2), Units: units2,
ShPerCtrct: 100, ShPerCtrct: 100,
SubAcctSec: "CASH", SubAcctSec: "CASH",
}, },
@ -799,25 +798,25 @@ NEWFILEUID: NONE
UniqueIdType: "CUSIP", UniqueIdType: "CUSIP",
}, },
OptAction: "ASSIGN", OptAction: "ASSIGN",
Units: ofxgo.Amount(units3), Units: units3,
ShPerCtrct: 100, ShPerCtrct: 100,
SubAcctSec: "CASH", SubAcctSec: "CASH",
}, },
}, },
} }
var availcash, marginbalance, shortbalance big.Rat var availcash, marginbalance, shortbalance ofxgo.Amount
availcash.SetFrac64(0, 1) availcash.SetFrac64(0, 1)
marginbalance.SetFrac64(-0, 1) marginbalance.SetFrac64(-0, 1)
shortbalance.SetFrac64(0, 1) shortbalance.SetFrac64(0, 1)
invbalance := ofxgo.InvBalance{ invbalance := ofxgo.InvBalance{
AvailCash: ofxgo.Amount(availcash), AvailCash: availcash,
MarginBalance: ofxgo.Amount(marginbalance), MarginBalance: marginbalance,
ShortBalance: ofxgo.Amount(shortbalance), ShortBalance: shortbalance,
} }
var posunits1, posunitprice1, posmktval1, posunits2, posunitprice2, posmktval2 big.Rat var posunits1, posunitprice1, posmktval1, posunits2, posunitprice2, posmktval2 ofxgo.Amount
posunits1.SetFrac64(100, 1) posunits1.SetFrac64(100, 1)
posunitprice1.SetFrac64(79, 1) posunitprice1.SetFrac64(79, 1)
posmktval1.SetFrac64(79000, 1) posmktval1.SetFrac64(79000, 1)
@ -847,9 +846,9 @@ NEWFILEUID: NONE
}, },
HeldInAcct: "CASH", HeldInAcct: "CASH",
PosType: "LONG", PosType: "LONG",
Units: ofxgo.Amount(posunits1), Units: posunits1,
UnitPrice: ofxgo.Amount(posunitprice1), UnitPrice: posunitprice1,
MktVal: ofxgo.Amount(posmktval1), MktVal: posmktval1,
DtPriceAsOf: ofxgo.Date(time.Date(2017, 4, 3, 12, 0, 0, 0, GMT)), DtPriceAsOf: ofxgo.Date(time.Date(2017, 4, 3, 12, 0, 0, 0, GMT)),
}, },
}, },
@ -861,9 +860,9 @@ NEWFILEUID: NONE
}, },
HeldInAcct: "CASH", HeldInAcct: "CASH",
PosType: "LONG", PosType: "LONG",
Units: ofxgo.Amount(posunits2), Units: posunits2,
UnitPrice: ofxgo.Amount(posunitprice2), UnitPrice: posunitprice2,
MktVal: ofxgo.Amount(posmktval2), MktVal: posmktval2,
DtPriceAsOf: ofxgo.Date(time.Date(2017, 4, 3, 12, 0, 0, 0, GMT)), DtPriceAsOf: ofxgo.Date(time.Date(2017, 4, 3, 12, 0, 0, 0, GMT)),
}, },
}, },
@ -872,7 +871,7 @@ NEWFILEUID: NONE
} }
expected.InvStmt = append(expected.InvStmt, &statementResponse) expected.InvStmt = append(expected.InvStmt, &statementResponse)
var strikeprice big.Rat var strikeprice ofxgo.Amount
strikeprice.SetFrac64(226, 1) strikeprice.SetFrac64(226, 1)
seclist := ofxgo.SecurityList{ seclist := ofxgo.SecurityList{
@ -897,7 +896,7 @@ NEWFILEUID: NONE
Ticker: "SPY 161216C00226000", Ticker: "SPY 161216C00226000",
}, },
OptType: "CALL", OptType: "CALL",
StrikePrice: ofxgo.Amount(strikeprice), StrikePrice: strikeprice,
DtExpire: ofxgo.Date(time.Date(2016, 12, 16, 12, 0, 0, 0, GMT)), DtExpire: ofxgo.Date(time.Date(2016, 12, 16, 12, 0, 0, 0, GMT)),
ShPerCtrct: 100, ShPerCtrct: 100,
}, },

View File

@ -37,11 +37,12 @@ func (i Int) Equal(o Int) bool {
return i == o return i == o
} }
type Amount big.Rat type Amount struct {
big.Rat
}
func (a *Amount) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { func (a *Amount) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var value string var value string
var b big.Rat
err := d.DecodeElement(&value, &start) err := d.DecodeElement(&value, &start)
if err != nil { if err != nil {
@ -54,16 +55,14 @@ func (a *Amount) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// by a comma, so fix that up before attempting to parse it into big.Rat // by a comma, so fix that up before attempting to parse it into big.Rat
value = strings.Replace(value, ",", ".", 1) value = strings.Replace(value, ",", ".", 1)
if _, ok := b.SetString(value); !ok { if _, ok := a.SetString(value); !ok {
return errors.New("Failed to parse OFX amount into big.Rat") return errors.New("Failed to parse OFX amount")
} }
*a = Amount(b)
return nil return nil
} }
func (a Amount) String() string { func (a Amount) String() string {
var b big.Rat = big.Rat(a) return strings.TrimRight(strings.TrimRight(a.FloatString(100), "0"), ".")
return strings.TrimRight(strings.TrimRight(b.FloatString(100), "0"), ".")
} }
func (a *Amount) MarshalXML(e *xml.Encoder, start xml.StartElement) error { func (a *Amount) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
@ -71,8 +70,7 @@ func (a *Amount) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
} }
func (a Amount) Equal(o Amount) bool { func (a Amount) Equal(o Amount) bool {
ratA := (*big.Rat)(&a) return (&a).Cmp(&o.Rat) == 0
return ratA.Cmp((*big.Rat)(&o)) == 0
} }
type Date time.Time type Date time.Time

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"github.com/aclindsa/go/src/encoding/xml" "github.com/aclindsa/go/src/encoding/xml"
"github.com/aclindsa/ofxgo" "github.com/aclindsa/ofxgo"
"math/big"
"reflect" "reflect"
"testing" "testing"
"time" "time"
@ -76,50 +75,47 @@ func TestUnmarshalInt(t *testing.T) {
func TestMarshalAmount(t *testing.T) { func TestMarshalAmount(t *testing.T) {
var a ofxgo.Amount var a ofxgo.Amount
var b *big.Rat = (*big.Rat)(&a)
b.SetFrac64(8, 1) a.SetFrac64(8, 1)
marshalHelper(t, "8", &a) marshalHelper(t, "8", &a)
b.SetFrac64(1, 8) a.SetFrac64(1, 8)
marshalHelper(t, "0.125", &a) marshalHelper(t, "0.125", &a)
b.SetFrac64(-1, 200) a.SetFrac64(-1, 200)
marshalHelper(t, "-0.005", &a) marshalHelper(t, "-0.005", &a)
b.SetInt64(0) a.SetInt64(0)
marshalHelper(t, "0", &a) marshalHelper(t, "0", &a)
b.SetInt64(-768276587425) a.SetInt64(-768276587425)
marshalHelper(t, "-768276587425", &a) marshalHelper(t, "-768276587425", &a)
b.SetFrac64(1, 12) a.SetFrac64(1, 12)
marshalHelper(t, "0.0833333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333", &a) marshalHelper(t, "0.0833333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333", &a)
} }
func TestUnmarshalAmount(t *testing.T) { func TestUnmarshalAmount(t *testing.T) {
var a, overwritten ofxgo.Amount var a, overwritten ofxgo.Amount
var b *big.Rat = (*big.Rat)(&a)
// Amount/big.Rat needs a special equality test because reflect.DeepEqual // Amount/big.Rat needs a special equality test because reflect.DeepEqual
// doesn't always return equal for two values that big.Rat.Cmp() does // doesn't always return equal for two values that big.Rat.Cmp() does
eq := func(a, b interface{}) bool { eq := func(a, b interface{}) bool {
if amountA, ok := a.(*ofxgo.Amount); ok { if amountA, ok := a.(*ofxgo.Amount); ok {
if amountB, ok2 := b.(*ofxgo.Amount); ok2 { if amountB, ok2 := b.(*ofxgo.Amount); ok2 {
ratA := (*big.Rat)(amountA) return amountA.Cmp(&amountB.Rat) == 0
return ratA.Cmp((*big.Rat)(amountB)) == 0
} }
} }
return false return false
} }
b.SetFrac64(12, 1) a.SetFrac64(12, 1)
unmarshalHelper2(t, "12", &a, &overwritten, eq) unmarshalHelper2(t, "12", &a, &overwritten, eq)
b.SetFrac64(-21309, 100) a.SetFrac64(-21309, 100)
unmarshalHelper2(t, "-213.09", &a, &overwritten, eq) unmarshalHelper2(t, "-213.09", &a, &overwritten, eq)
b.SetFrac64(8192, 1000) a.SetFrac64(8192, 1000)
unmarshalHelper2(t, "8.192", &a, &overwritten, eq) unmarshalHelper2(t, "8.192", &a, &overwritten, eq)
unmarshalHelper2(t, "+8.192", &a, &overwritten, eq) unmarshalHelper2(t, "+8.192", &a, &overwritten, eq)
b.SetInt64(0) a.SetInt64(0)
unmarshalHelper2(t, "0", &a, &overwritten, eq) unmarshalHelper2(t, "0", &a, &overwritten, eq)
unmarshalHelper2(t, "+0", &a, &overwritten, eq) unmarshalHelper2(t, "+0", &a, &overwritten, eq)
unmarshalHelper2(t, "-0", &a, &overwritten, eq) unmarshalHelper2(t, "-0", &a, &overwritten, eq)
b.SetInt64(-19487135) a.SetInt64(-19487135)
unmarshalHelper2(t, "-19487135", &a, &overwritten, eq) unmarshalHelper2(t, "-19487135", &a, &overwritten, eq)
// Make sure stray newlines are handled properly // Make sure stray newlines are handled properly
unmarshalHelper2(t, "-19487135\n", &a, &overwritten, eq) unmarshalHelper2(t, "-19487135\n", &a, &overwritten, eq)