UT: Lots of improvements and fixes.

- Parse negative amounts.
- Make Amount.negate() return a new value.
- Add Amount.equals().
- Rename Remote.trace() to set_trace().
- Fix request_ripple_balnce.
- Add more tests to send-test.js.
- Add more tests to amount-test.js.
- Add helper functions create_accounts and credit_limits to
  testutils.js.
This commit is contained in:
Arthur Britto
2012-10-21 20:04:25 -07:00
parent cc3c640322
commit fff39797c0
6 changed files with 275 additions and 58 deletions

View File

@@ -38,6 +38,10 @@ UInt160.prototype.copyTo = function(d) {
return d; return d;
}; };
UInt160.prototype.equals = function(d) {
return this.value === d.value;
};
// value = NaN on error. // value = NaN on error.
UInt160.prototype.parse_json = function (j) { UInt160.prototype.parse_json = function (j) {
// Canonicalize and validate // Canonicalize and validate
@@ -166,6 +170,12 @@ var Amount = function () {
this.issuer = new UInt160(); this.issuer = new UInt160();
}; };
// Given "100/USD/mtgox" return the a string with mtgox remapped.
Amount.text_full_rewrite = function (j) {
return Amount.from_json(j).to_text_full();
}
// Given "100/USD/mtgox" return the json.
Amount.json_rewrite = function(j) { Amount.json_rewrite = function(j) {
return Amount.from_json(j).to_json(); return Amount.from_json(j).to_json();
}; };
@@ -174,15 +184,18 @@ Amount.from_json = function(j) {
return (new Amount()).parse_json(j); return (new Amount()).parse_json(j);
}; };
Amount.prototype.clone = function() { Amount.prototype.clone = function(negate) {
return this.copyTo(new Amount()); return this.copyTo(new Amount(), negate);
}; };
// Returns copy. // Returns copy.
Amount.prototype.copyTo = function(d) { Amount.prototype.copyTo = function(d, negate) {
if ('object' === typeof this.value) if ('object' === typeof this.value)
{ {
this.value.copyTo(d.value); if (this.is_native && negate)
this.value.negate.copyTo(d.value);
else
this.value.copyTo(d.value);
} }
else else
{ {
@@ -191,7 +204,7 @@ Amount.prototype.copyTo = function(d) {
d.offset = this.offset; d.offset = this.offset;
d.is_native = this.is_native; d.is_native = this.is_native;
d.is_negative = this.is_negative; d.is_negative = this.is_negative ? undefined : !this.is_negative;
this.currency.copyTo(d.currency); this.currency.copyTo(d.currency);
this.issuer.copyTo(d.issuer); this.issuer.copyTo(d.issuer);
@@ -266,15 +279,13 @@ Amount.prototype.canonicalize = function() {
this.offset += 1; this.offset += 1;
} }
} }
return this;
}; };
// Return a new value.
Amount.prototype.negate = function () { Amount.prototype.negate = function () {
if (this.is_native) { return this.clone('NEGATE');
this.value.negate();
}
else {
this.is_negative = !this.is_negative;
}
}; };
Amount.prototype.to_json = function() { Amount.prototype.to_json = function() {
@@ -307,23 +318,26 @@ Amount.prototype.parse_native = function(j) {
var m; var m;
if ('string' === typeof j) if ('string' === typeof j)
m = j.match(/^(\d+)(\.\d{1,6})?$/); m = j.match(/^(-?)(\d+)(\.\d{1,6})?$/);
if (m) { if (m) {
if (undefined === m[2]) { if (undefined === m[3]) {
// Integer notation // Integer notation
this.value = new BigInteger(m[1]); this.value = new BigInteger(m[2]);
} }
else { else {
// Decimal notation // Decimal notation
var int_part = (new BigInteger(m[1])).multiply(exports.consts.bi_xns_unit); var int_part = (new BigInteger(m[2])).multiply(exports.consts.bi_xns_unit);
var fraction_part = (new BigInteger(m[2])).multiply(new BigInteger(String(Math.pow(10, 1+exports.consts.xns_precision-m[2].length)))); var fraction_part = (new BigInteger(m[3])).multiply(new BigInteger(String(Math.pow(10, 1+exports.consts.xns_precision-m[3].length))));
this.value = int_part.add(fraction_part); this.value = int_part.add(fraction_part);
} }
if (m[1])
this.value = this.value.negate();
this.is_native = true; this.is_native = true;
this.offset = undefined; this.offset = undefined;
this.is_negative = undefined; this.is_negative = undefined;
@@ -442,6 +456,20 @@ Amount.prototype.parse_issuer = function (issuer) {
return this; return this;
}; };
// Check BigInteger NaN
Amount.prototype.equals = function (d) {
return 'string' === typeof (d)
? this.equals(Amount.from_json(d))
: this === d
|| (d.constructor === Amount
&& this.is_native === d.is_native
&& (this.is_native
? this.value.equals(d.value)
: this.is_negative === d.is_negative
? this.value.equals(d.value)
: this.value.equals(BigInteger.ZERO) && d.value.equals(BigInteger.ZERO)));
};
exports.Amount = Amount; exports.Amount = Amount;
exports.Currency = Currency; exports.Currency = Currency;
exports.UInt160 = UInt160; exports.UInt160 = UInt160;

View File

@@ -244,8 +244,8 @@ Remote.prototype._set_state = function (state) {
} }
}; };
Remote.prototype.trace = function () { Remote.prototype.set_trace = function (trace) {
this.trace = true; this.trace = undefined === trace || trace;
return this; return this;
}; };
@@ -731,6 +731,8 @@ Remote.prototype.dirty_account_root = function (account) {
// --> issuer: String // --> issuer: String
// --> currency: String // --> currency: String
// --> current: bool : true = current ledger // --> current: bool : true = current ledger
//
// If does not exist: emit('error', 'error' : 'remoteError', 'remote' : { 'error' : 'entryNotFound' })
Remote.prototype.request_ripple_balance = function (account, issuer, currency, current) { Remote.prototype.request_ripple_balance = function (account, issuer, currency, current) {
var request = this.request_ledger_entry('ripple_state'); // YYY Could be cached per ledger. var request = this.request_ledger_entry('ripple_state'); // YYY Could be cached per ledger.
@@ -739,20 +741,25 @@ Remote.prototype.request_ripple_balance = function (account, issuer, currency, c
.ledger_choose(current) .ledger_choose(current)
.on('success', function (message) { .on('success', function (message) {
var node = message.node; var node = message.node;
var lowLimit = Amount.from_json(node.LowLimit); var lowLimit = Amount.from_json(node.LowLimit);
var highLimit = Amount.from_json(node.HighLimit); var highLimit = Amount.from_json(node.HighLimit);
// The amount account holds of issuer (after negation if needed).
var balance = Amount.from_json(node.Balance); var balance = Amount.from_json(node.Balance);
var flip = UInt160.from_json(account) == highLimit.issuer; // accountHigh implies: for account: balance is negated, highLimit is the limit set by account.
var issuerLimit = flip ? lowLimit : highLimit; var accountHigh = UInt160.from_json(account).equals(highLimit.issuer);
var accountLimit = flip ? highLimit : lowLimit; // The limit set by issuer.
var issuerBalance = (flip ? balance.negate() : balance).parse_issuer(issuer); var issuerLimit = (accountHigh ? lowLimit : highLimit).parse_issuer(issuer);
var accountBalance = issuerBalance.clone().parse_issuer(issuer); // The limit set by account.
var accountLimit = (accountHigh ? highLimit : lowLimit).parse_issuer(account);
var issuerBalance = (accountHigh ? balance.negate() : balance).parse_issuer(issuer);
var accountBalance = issuerBalance.clone().negate().parse_issuer(account);
request.emit('ripple_state', { request.emit('ripple_state', {
'issuer_balance' : issuerBalance, // Balance with dst as issuer. 'issuer_balance' : issuerBalance, // Balance with dst as issuer.
'account_balance' : accountBalance, // Balance with account as issuer. 'account_balance' : accountBalance, // Balance with account as issuer.
'issuer_limit' : issuerLimit.clone().parse_issuer(account), // Limit set by issuer with src as issuer. 'issuer_limit' : issuerLimit, // Limit set by issuer with src as issuer.
'account_limit' : accountLimit.clone().parse_issuer(issuer) // Limit set by account with dst as issuer. 'account_limit' : accountLimit // Limit set by account with dst as issuer.
}); });
}); });
} }
@@ -774,7 +781,7 @@ Remote.prototype.transaction = function () {
// Events: // Events:
// 'success' : Transaction submitted without error. // 'success' : Transaction submitted without error.
// 'error' : Error submitting transaction. // 'error' : Error submitting transaction.
// 'proposed: Advisory proposed status transaction. // 'proposed' : Advisory proposed status transaction.
// - A client should expect 0 to multiple results. // - A client should expect 0 to multiple results.
// - Might not get back. The remote might just forward the transaction. // - Might not get back. The remote might just forward the transaction.
// - A success could be reverted in final. // - A success could be reverted in final.
@@ -1115,7 +1122,7 @@ Transaction.prototype.ripple_line_set = function (src, limit, quality_in, qualit
// Allow limit of 0 through. // Allow limit of 0 through.
if (undefined !== limit) if (undefined !== limit)
this.transaction.LimitAmount = limit.to_json(); this.transaction.LimitAmount = Amount.json_rewrite(limit);
if (quality_in) if (quality_in)
this.transaction.QualityIn = quality_in; this.transaction.QualityIn = quality_in;

View File

@@ -10,12 +10,29 @@ buster.testCase("Amount", {
"Parse 0 export" : function () { "Parse 0 export" : function () {
buster.assert.equals(amount.consts.hex_xns, amount.UInt160.from_json("0").to_json()); buster.assert.equals(amount.consts.hex_xns, amount.UInt160.from_json("0").to_json());
}, },
"Parse native 123" : function () { },
buster.assert.equals("123/XNS", amount.Amount.from_json("123").to_text_full()); "Amount" : {
"Parse native 0" : function () {
buster.assert.equals("0/XNS", amount.Amount.from_json("0").to_text_full());
},
"Parse native 0.0" : function () {
buster.assert.equals("0/XNS", amount.Amount.from_json("0.0").to_text_full());
},
"Parse native -0" : function () {
buster.assert.equals("0/XNS", amount.Amount.from_json("-0").to_text_full());
},
"Parse native -0.0" : function () {
buster.assert.equals("0/XNS", amount.Amount.from_json("-0.0").to_text_full());
},
"Parse native 1000" : function () {
buster.assert.equals("1000/XNS", amount.Amount.from_json("1000").to_text_full());
}, },
"Parse native 12.3" : function () { "Parse native 12.3" : function () {
buster.assert.equals("12300000/XNS", amount.Amount.from_json("12.3").to_text_full()); buster.assert.equals("12300000/XNS", amount.Amount.from_json("12.3").to_text_full());
}, },
"Parse native -12.3" : function () {
buster.assert.equals("-12300000/XNS", amount.Amount.from_json("-12.3").to_text_full());
},
"Parse 123./USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () { "Parse 123./USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
buster.assert.equals("123/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", amount.Amount.from_json("123./USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh").to_text_full()); buster.assert.equals("123/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", amount.Amount.from_json("123./USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh").to_text_full());
}, },
@@ -28,6 +45,12 @@ buster.testCase("Amount", {
"Parse 1.2300/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () { "Parse 1.2300/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
buster.assert.equals("1.23/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", amount.Amount.from_json("1.2300/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh").to_text_full()); buster.assert.equals("1.23/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", amount.Amount.from_json("1.2300/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh").to_text_full());
}, },
"Parse -0/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
buster.assert.equals("0/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", amount.Amount.from_json("-0/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh").to_text_full());
},
"Parse -0.0/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh" : function () {
buster.assert.equals("0/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", amount.Amount.from_json("-0.0/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh").to_text_full());
},
} }
}); });

View File

@@ -23,11 +23,11 @@ buster.testCase("Offer tests", {
function (callback) { function (callback) {
self.remote.transaction() self.remote.transaction()
.offer_create("root", "500", "100/USD/root") .offer_create("root", "500", "100/USD/root")
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_create: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_create: %s", JSON.stringify(m));
callback(m.result != 'tesSUCCESS', m); callback(m.result != 'tesSUCCESS', m);
}) })
.on("final", function (m) { .on('final', function (m) {
// console.log("FINAL: offer_create: %s", JSON.stringify(m)); // console.log("FINAL: offer_create: %s", JSON.stringify(m));
buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult);
@@ -39,11 +39,11 @@ buster.testCase("Offer tests", {
function (m, callback) { function (m, callback) {
self.remote.transaction() self.remote.transaction()
.offer_cancel("root", m.transaction.Sequence) .offer_cancel("root", m.transaction.Sequence)
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_cancel: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_cancel: %s", JSON.stringify(m));
callback(m.result != 'tesSUCCESS', m); callback(m.result != 'tesSUCCESS', m);
}) })
.on("final", function (m) { .on('final', function (m) {
// console.log("FINAL: offer_cancel: %s", JSON.stringify(m)); // console.log("FINAL: offer_cancel: %s", JSON.stringify(m));
buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult);
@@ -54,7 +54,7 @@ buster.testCase("Offer tests", {
}, },
function (m, callback) { function (m, callback) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: %d: %s", ledger_closed_index, ledger_closed);
}) })
.ledger_accept(); .ledger_accept();
@@ -77,14 +77,14 @@ buster.testCase("Offer tests", {
function (callback) { function (callback) {
self.remote.transaction() self.remote.transaction()
.offer_create("root", "500", "100/USD/root") .offer_create("root", "500", "100/USD/root")
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_create: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_create: %s", JSON.stringify(m));
offer_seq = m.transaction.Sequence; offer_seq = m.transaction.Sequence;
callback(m.result != 'tesSUCCESS'); callback(m.result != 'tesSUCCESS');
}) })
.on("final", function (m) { .on('final', function (m) {
// console.log("FINAL: offer_create: %s", JSON.stringify(m)); // console.log("FINAL: offer_create: %s", JSON.stringify(m));
buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult);
@@ -98,7 +98,7 @@ buster.testCase("Offer tests", {
function (callback) { function (callback) {
if (!final_create) { if (!final_create) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: %d: %s", ledger_closed_index, ledger_closed);
}) })
@@ -113,11 +113,11 @@ buster.testCase("Offer tests", {
self.remote.transaction() self.remote.transaction()
.offer_cancel("root", offer_seq) .offer_cancel("root", offer_seq)
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_cancel: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_cancel: %s", JSON.stringify(m));
callback(m.result != 'tesSUCCESS'); callback(m.result != 'tesSUCCESS');
}) })
.on("final", function (m) { .on('final', function (m) {
// console.log("FINAL: offer_cancel: %s", JSON.stringify(m)); // console.log("FINAL: offer_cancel: %s", JSON.stringify(m));
buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult);
@@ -130,7 +130,7 @@ buster.testCase("Offer tests", {
// See if ledger_accept will crash. // See if ledger_accept will crash.
function (callback) { function (callback) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: A: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: A: %d: %s", ledger_closed_index, ledger_closed);
callback(); callback();
}) })
@@ -138,7 +138,7 @@ buster.testCase("Offer tests", {
}, },
function (callback) { function (callback) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: B: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: B: %d: %s", ledger_closed_index, ledger_closed);
callback(); callback();
}) })
@@ -174,14 +174,14 @@ buster.testCase("Offer tests", {
function (callback) { function (callback) {
self.remote.transaction() self.remote.transaction()
.offer_create("alice", "500", "100/USD/alice") .offer_create("alice", "500", "100/USD/alice")
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_create: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_create: %s", JSON.stringify(m));
offer_seq = m.transaction.Sequence; offer_seq = m.transaction.Sequence;
callback(m.result != 'tesSUCCESS'); callback(m.result != 'tesSUCCESS');
}) })
.on("final", function (m) { .on('final', function (m) {
// console.log("FINAL: offer_create: %s", JSON.stringify(m)); // console.log("FINAL: offer_create: %s", JSON.stringify(m));
buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult);
@@ -195,7 +195,7 @@ buster.testCase("Offer tests", {
function (callback) { function (callback) {
if (!final_create) { if (!final_create) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: %d: %s", ledger_closed_index, ledger_closed);
}) })
@@ -210,11 +210,11 @@ buster.testCase("Offer tests", {
self.remote.transaction() self.remote.transaction()
.offer_cancel("alice", offer_seq) .offer_cancel("alice", offer_seq)
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_cancel: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_cancel: %s", JSON.stringify(m));
callback(m.result != 'tesSUCCESS'); callback(m.result != 'tesSUCCESS');
}) })
.on("final", function (m) { .on('final', function (m) {
// console.log("FINAL: offer_cancel: %s", JSON.stringify(m)); // console.log("FINAL: offer_cancel: %s", JSON.stringify(m));
buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult); buster.assert.equals('tesSUCCESS', m.metadata.TransactionResult);
@@ -227,7 +227,7 @@ buster.testCase("Offer tests", {
// See if ledger_accept will crash. // See if ledger_accept will crash.
function (callback) { function (callback) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: A: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: A: %d: %s", ledger_closed_index, ledger_closed);
callback(); callback();
}) })
@@ -235,7 +235,7 @@ buster.testCase("Offer tests", {
}, },
function (callback) { function (callback) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: B: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: B: %d: %s", ledger_closed_index, ledger_closed);
callback(); callback();
}) })
@@ -258,7 +258,7 @@ buster.testCase("Offer tests", {
self.remote.transaction() self.remote.transaction()
.payment('root', 'alice', Amount.from_json("10000")) .payment('root', 'alice', Amount.from_json("10000"))
.set_flags('CreateAccount') .set_flags('CreateAccount')
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: CreateAccount: %s", JSON.stringify(m)); // console.log("PROPOSED: CreateAccount: %s", JSON.stringify(m));
callback(m.result != 'tesSUCCESS', m); callback(m.result != 'tesSUCCESS', m);
}) })
@@ -274,7 +274,7 @@ buster.testCase("Offer tests", {
function (m, callback) { function (m, callback) {
self.remote.transaction() self.remote.transaction()
.offer_cancel("root", m.transaction.Sequence) .offer_cancel("root", m.transaction.Sequence)
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_cancel past: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_cancel past: %s", JSON.stringify(m));
callback(m.result != 'tesSUCCESS', m); callback(m.result != 'tesSUCCESS', m);
}) })
@@ -284,7 +284,7 @@ buster.testCase("Offer tests", {
function (m, callback) { function (m, callback) {
self.remote.transaction() self.remote.transaction()
.offer_cancel("root", m.transaction.Sequence+1) .offer_cancel("root", m.transaction.Sequence+1)
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("PROPOSED: offer_cancel same: %s", JSON.stringify(m)); // console.log("PROPOSED: offer_cancel same: %s", JSON.stringify(m));
callback(m.result != 'temBAD_SEQUENCE', m); callback(m.result != 'temBAD_SEQUENCE', m);
}) })
@@ -297,7 +297,7 @@ buster.testCase("Offer tests", {
self.remote.transaction() self.remote.transaction()
.offer_cancel("root", m.transaction.Sequence+2) .offer_cancel("root", m.transaction.Sequence+2)
.on("proposed", function (m) { .on('proposed', function (m) {
// console.log("ERROR: offer_cancel future: %s", JSON.stringify(m)); // console.log("ERROR: offer_cancel future: %s", JSON.stringify(m));
callback(m.result != 'temBAD_SEQUENCE'); callback(m.result != 'temBAD_SEQUENCE');
}) })
@@ -306,7 +306,7 @@ buster.testCase("Offer tests", {
// See if ledger_accept will crash. // See if ledger_accept will crash.
function (callback) { function (callback) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: A: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: A: %d: %s", ledger_closed_index, ledger_closed);
callback(); callback();
}) })
@@ -314,7 +314,7 @@ buster.testCase("Offer tests", {
}, },
function (callback) { function (callback) {
self.remote self.remote
.once("ledger_closed", function (ledger_closed, ledger_closed_index) { .once('ledger_closed', function (ledger_closed, ledger_closed_index) {
// console.log("LEDGER_CLOSED: B: %d: %s", ledger_closed_index, ledger_closed); // console.log("LEDGER_CLOSED: B: %d: %s", ledger_closed_index, ledger_closed);
callback(); callback();
}) })

View File

@@ -1,3 +1,4 @@
var async = require("async");
var buster = require("buster"); var buster = require("buster");
var Amount = require("../js/amount.js").Amount; var Amount = require("../js/amount.js").Amount;
@@ -9,13 +10,13 @@ var testutils = require("./testutils.js");
// How long to wait for server to start. // How long to wait for server to start.
var serverDelay = 1500; var serverDelay = 1500;
buster.testRunner.timeout = 5000; buster.testRunner.timeout = 2000;
buster.testCase("Sending", { buster.testCase("Sending", {
'setUp' : testutils.test_setup, 'setUp' : testutils.test_setup,
'tearDown' : testutils.test_teardown, 'tearDown' : testutils.test_teardown,
"send to non-existant account without create." : "send XNS to non-existant account without create." :
function (done) { function (done) {
var self = this; var self = this;
var ledgers = 20; var ledgers = 20;
@@ -71,6 +72,118 @@ buster.testCase("Sending", {
}) })
.submit(); .submit();
}, },
// Also test transaction becomes lost after terNO_DST.
"credit_limit to non-existant account = terNO_DST" :
function (done) {
this.remote.transaction()
.ripple_line_set("root", "100/USD/alice")
.on('proposed', function (m) {
// console.log("proposed: %s", JSON.stringify(m));
buster.assert.equals(m.result, 'terNO_DST');
done();
})
.submit();
},
"credit_limit" :
function (done) {
var self = this;
//this.remote.set_trace();
async.waterfall([
function (callback) {
this.what = "Create account.";
testutils.create_accounts(self.remote, "root", "10000", ["alice", "bob", "mtgox"], callback);
},
function (callback) {
this.what = "Check a non-existant credit limit.";
self.remote.request_ripple_balance("alice", "mtgox", "USD", 'CURRENT')
.on('ripple_state', function (m) {
buster.assert(false);
callback();
})
.on('error', function(m) {
// console.log("error: %s", JSON.stringify(m));
buster.assert.equals('remoteError', m.error);
buster.assert.equals('entryNotFound', m.remote.error);
callback();
})
.request();
},
function (callback) {
this.what = "Create a credit limit.";
testutils.credit_limit(self.remote, "alice", "800/USD/mtgox", callback);
},
function (callback) {
self.remote.request_ripple_balance("alice", "mtgox", "USD", 'CURRENT')
.on('ripple_state', function (m) {
// console.log("BALANCE: %s", JSON.stringify(m));
// console.log("account_balance: %s", m.account_balance.to_text_full());
// console.log("account_limit: %s", m.account_limit.to_text_full());
// console.log("issuer_balance: %s", m.issuer_balance.to_text_full());
// console.log("issuer_limit: %s", m.issuer_limit.to_text_full());
buster.assert(m.account_balance.equals("0/USD/alice"));
buster.assert(m.account_limit.equals("800/USD/alice"));
buster.assert(m.issuer_balance.equals("0/USD/mtgox"));
buster.assert(m.issuer_limit.equals("0/USD/mtgox"));
callback();
})
.request();
},
function (callback) {
this.what = "Modify a credit limit.";
testutils.credit_limit(self.remote, "alice", "700/USD/mtgox", callback);
},
function (callback) {
self.remote.request_ripple_balance("alice", "mtgox", "USD", 'CURRENT')
.on('ripple_state', function (m) {
buster.assert(m.account_balance.equals("0/USD/alice"));
buster.assert(m.account_limit.equals("700/USD/alice"));
buster.assert(m.issuer_balance.equals("0/USD/mtgox"));
buster.assert(m.issuer_limit.equals("0/USD/mtgox"));
callback();
})
.request();
},
function (callback) {
this.what = "Zero a credit limit.";
testutils.credit_limit(self.remote, "alice", "0/USD/mtgox", callback);
},
function (callback) {
this.what = "Make sure still exists.";
self.remote.request_ripple_balance("alice", "mtgox", "USD", 'CURRENT')
.on('ripple_state', function (m) {
buster.assert(m.account_balance.equals("0/USD/alice"));
buster.assert(m.account_limit.equals("0/USD/alice"));
buster.assert(m.issuer_balance.equals("0/USD/mtgox"));
buster.assert(m.issuer_limit.equals("0/USD/mtgox"));
callback();
})
.request();
},
// Check in both owner books.
// Set limit on other side.
// Set negative limit.
//function (callback) {
// testutils.credit_limit(self.remote, "alice", "-1/USD/mtgox", callback);
//},
], function (error) {
buster.refute(error, this.what);
done();
});
}
}); });
// vim:sw=2:sts=2:ts=8 // vim:sw=2:sts=2:ts=8

View File

@@ -1,3 +1,6 @@
var async = require("async");
// var buster = require("buster");
var Remote = require("../js/remote.js").Remote; var Remote = require("../js/remote.js").Remote;
var Server = require("./server.js").Server; var Server = require("./server.js").Server;
@@ -28,6 +31,49 @@ var test_teardown = function (done, host) {
.connect(false); .connect(false);
}; };
var create_accounts = function (remote, src, amount, accounts, callback) {
assert(5 === arguments.length);
async.forEachSeries(accounts, function (account, callback) {
remote.transaction()
.payment(src, account, amount)
.set_flags('CreateAccount')
.on('proposed', function (m) {
// console.log("proposed: %s", JSON.stringify(m));
callback(m.result != 'tesSUCCESS');
})
.on('error', function (m) {
// console.log("error: %s", JSON.stringify(m));
callback(m);
})
.submit();
}, callback);
};
var credit_limit = function (remote, src, amount, callback) {
assert(4 === arguments.length);
remote.transaction()
.ripple_line_set(src, amount)
.on('proposed', function (m) {
// console.log("proposed: %s", JSON.stringify(m));
// buster.assert.equals(m.result, 'tesSUCCESS');
callback(m.result != 'tesSUCCESS');
})
.on('error', function (m) {
// console.log("error: %s", JSON.stringify(m));
callback(m);
})
.submit();
};
exports.create_accounts = create_accounts;
exports.credit_limit = credit_limit;
exports.test_setup = test_setup; exports.test_setup = test_setup;
exports.test_teardown = test_teardown; exports.test_teardown = test_teardown;