<commit_before>var async   = require("async");
// var buster  = require("buster");

var Amount  = require("../src/js/amount.js").Amount;
var Remote  = require("../src/js/remote.js").Remote;
var Server  = require("./server.js").Server;

require("../src/js/amount.js").config = require("./config.js");
require("../src/js/remote.js").config = require("./config.js");

var config  = require("./config.js");

/**
 * Helper called by test cases to generate a setUp routine.
 *
 * By default you would call this without options, but it is useful to
 * be able to plug options in during development for quick and easy
 * debugging.
 *
 * @example
 *   buster.testCase("Foobar", {
 *     setUp: testutils.build_setup({verbose: true}),
 *     // ...
 *   });
 *
 * @param opts {Object} These options allow quick-and-dirty test-specific
 *   customizations of your test environment.
 * @param opts.verbose {Bool} Enable all debug output (then cover your ears
 *   and run)
 * @param opts.verbose_ws {Bool} Enable tracing in the Remote class. Prints
 *   websocket traffic.
 * @param opts.verbose_server {Bool} Set the -v option when running rippled.
 * @param opts.no_server {Bool} Don't auto-run rippled.
 * @param host {String} Identifier for the host configuration to be used.
 */
var build_setup = function (opts, host) {
  opts = opts || {};

  // Normalize options
  if (opts.verbose) {
    opts.verbose_ws = true;
    opts.verbose_server = true;
  };

  return function (done) {
    var self = this;

    host = host || config.server_default;

    this.store = this.store || {};

    var data = this.store[host] = this.store[host] || {};

    data.opts = opts;

    async.series([
      function runServerStep(callback) {
        if (opts.no_server) return callback();

        data.server = Server.from_config(host, !!opts.verbose_server).on('started', callback).start();
      },
      function connectWebsocketStep(callback) {
        self.remote = data.remote = Remote.from_config(host, !!opts.verbose_ws).once('ledger_closed', callback).connect();
      }
    ], done);
  };
};

/**
 * Generate tearDown routine.
 *
 * @param host {String} Identifier for the host configuration to be used.
 */
var build_teardown = function (host) {
  return function (done) {
    host = host || config.server_default;

    var data = this.store[host];
    var opts = data.opts;

    async.series([
      function disconnectWebsocketStep(callback) {
        data.remote
          .on('disconnected', callback)
          .connect(false);
      },
      function stopServerStep(callback) {
        if (opts.no_server) return callback();

        data.server.on('stopped', callback).stop();
      }
    ], done);
  };
};

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));

	callback(m.result != 'tesSUCCESS');
      })
    .on('error', function (m) {
	// console.log("error: %s", JSON.stringify(m));

	callback(m);
      })
    .submit();
};

var credit_limits = function (remote, balances, callback) {
  assert(3 === arguments.length);

  var limits = [];

  for (var src in balances) {
    var	values_src  = balances[src];
    var values	    = 'string' === typeof values_src ? [ values_src ] : values_src;

    for (var index in values) {
      limits.push( { "source" : src, "amount" : values[index] } );
    }
  }

  async.every(limits,
    function (limit, callback) {
      credit_limit(remote, limit.source, limit.amount,
	function (mismatch) { callback(!mismatch); });
    },
    function (every) {
      callback(!every);
    });
};

var payment = function (remote, src, dst, amount, callback) {
  assert(5 === arguments.length);

  remote.transaction()
    .payment(src, dst, amount)
    .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();
};

var payments = function (remote, balances, callback) {
  assert(3 === arguments.length);

  var sends = [];

  for (var src in balances) {
    var	values_src  = balances[src];
    var values	    = 'string' === typeof values_src ? [ values_src ] : values_src;

    for (var index in values) {
      var amount_json = values[index];
      var amount      = Amount.from_json(amount_json);

      sends.push( { "source" : src, "destination" : amount.issuer().to_json(), "amount" : amount_json } );
    }
  }

  async.every(sends,
    function (send, callback) {
      payment(remote, send.source, send.destination, send.amount,
	function (mismatch) { callback(!mismatch); });
    },
    function (every) {
      callback(!every);
    });
};

var transfer_rate = function (remote, src, billionths, callback) {
  assert(4 === arguments.length);

  remote.transaction()
    .account_set(src)
    .transfer_rate(billionths)
    .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();
};

var verify_balance = function (remote, src, amount_json, callback) {
  assert(4 === arguments.length);
  var amount  = Amount.from_json(amount_json);

  if (amount.is_native()) {
    // XXX Not implemented.
    callback();
  }
  else {
    remote.request_ripple_balance(src, amount.issuer().to_json(), amount.currency().to_json(), 'CURRENT')
      .once('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());

	  var account_balance = Amount.from_json(m.account_balance);

	  if (!account_balance.equals(amount)) {
	    console.log("verify_balance: failed: %s vs %s is %s", src, amount_json, amount.to_text_full());
	  }

	  callback(!account_balance.equals(amount));
	})
      .request();
  }
};

var verify_balances = function (remote, balances, callback) {
  var tests = [];

  for (var src in balances) {
    var	values_src  = balances[src];
    var values	    = 'string' === typeof values_src ? [ values_src ] : values_src;

    for (var index in values) {
      tests.push( { "source" : src, "amount" : values[index] } );
    }
  }

  async.every(tests,
    function (check, callback) {
      verify_balance(remote, check.source, check.amount,
	function (mismatch) { callback(!mismatch); });
    },
    function (every) {
      callback(!every);
    });
};

// --> owner: account
// --> seq: sequence number of creating transaction.
// --> taker_gets: json amount
// --> taker_pays: json amount
var verify_offer = function (remote, owner, seq, taker_gets, taker_pays, callback) {
  assert(6 === arguments.length);

  remote.request_ledger_entry('offer')
    .offer_id(owner, seq)
    .on('success', function (m) {
	var wrong   = (!Amount.from_json(m.node.TakerGets).equals(Amount.from_json(taker_gets))
	  || !Amount.from_json(m.node.TakerPays).equals(Amount.from_json(taker_pays)));

	if (wrong)
	  console.log("verify_offer: failed: %s", JSON.stringify(m));

	callback(wrong);
      })
    .request();
};

var verify_offer_not_found = function (remote, owner, seq, callback) {
  assert(4 === arguments.length);

  remote.request_ledger_entry('offer')
    .offer_id(owner, seq)
    .on('success', function (m) {
	console.log("verify_no_offer: found offer: %s", JSON.stringify(m));

	callback('entryFound');
      })
    .on('error', function (m) {
	// console.log("verify_no_offer: success: %s", JSON.stringify(m));

	callback('remoteError' !== m.error
	  || 'entryNotFound' !== m.remote.error);
      })
    .request();
};

exports.build_setup		= build_setup;
exports.create_accounts	      	= create_accounts;
exports.credit_limit	      	= credit_limit;
exports.credit_limits	      	= credit_limits;
exports.payment		      	= payment;
exports.payments	      	= payments;
exports.build_teardown	      	= build_teardown;
exports.transfer_rate	      	= transfer_rate;
exports.verify_balance	      	= verify_balance;
exports.verify_balances	      	= verify_balances;
exports.verify_offer	      	= verify_offer;<commit_msg>UT: Work toward dumping an account's history.<commit_after>var async   = require("async");
// var buster  = require("buster");

var Amount  = require("../src/js/amount.js").Amount;
var Remote  = require("../src/js/remote.js").Remote;
var Server  = require("./server.js").Server;

require("../src/js/amount.js").config = require("./config.js");
require("../src/js/remote.js").config = require("./config.js");

var config  = require("./config.js");

var account_dump = function (remote, account, callback) {
  var self = this;

  async.waterfall([
      function (callback) {
	self.what = "Get latest account_root";

	remote
	  .request_ledger_entry('account_root')
	  .ledger_hash(remote.ledger_hash())
	  .account_root("root")
	  .on('success', function (r) {
	      console.log("account_root: %s", JSON.stringify(r, undefined, 2));

	      callback();
	    })
	  .on('error', function(m) {
	      console.log("error: %s", m);

	      buster.assert(false);
	      callback();
	    })
	  .request();
      },
    ], function (error) {
      callback(error);
    });

  // get closed ledger hash
  // get account root
  // construct a json result
  //
};

/**
 * Helper called by test cases to generate a setUp routine.
 *
 * By default you would call this without options, but it is useful to
 * be able to plug options in during development for quick and easy
 * debugging.
 *
 * @example
 *   buster.testCase("Foobar", {
 *     setUp: testutils.build_setup({verbose: true}),
 *     // ...
 *   });
 *
 * @param opts {Object} These options allow quick-and-dirty test-specific
 *   customizations of your test environment.
 * @param opts.verbose {Bool} Enable all debug output (then cover your ears
 *   and run)
 * @param opts.verbose_ws {Bool} Enable tracing in the Remote class. Prints
 *   websocket traffic.
 * @param opts.verbose_server {Bool} Set the -v option when running rippled.
 * @param opts.no_server {Bool} Don't auto-run rippled.
 * @param host {String} Identifier for the host configuration to be used.
 */
var build_setup = function (opts, host) {
  opts = opts || {};

  // Normalize options
  if (opts.verbose) {
    opts.verbose_ws = true;
    opts.verbose_server = true;
  };

  return function (done) {
    var self = this;

    host = host || config.server_default;

    this.store = this.store || {};

    var data = this.store[host] = this.store[host] || {};

    data.opts = opts;

    async.series([
      function runServerStep(callback) {
        if (opts.no_server) return callback();

        data.server = Server.from_config(host, !!opts.verbose_server).on('started', callback).start();
      },
      function connectWebsocketStep(callback) {
        self.remote = data.remote = Remote.from_config(host, !!opts.verbose_ws).once('ledger_closed', callback).connect();
      }
    ], done);
  };
};

/**
 * Generate tearDown routine.
 *
 * @param host {String} Identifier for the host configuration to be used.
 */
var build_teardown = function (host) {
  return function (done) {
    host = host || config.server_default;

    var data = this.store[host];
    var opts = data.opts;

    async.series([
      function disconnectWebsocketStep(callback) {
        data.remote
          .on('disconnected', callback)
          .connect(false);
      },
      function stopServerStep(callback) {
        if (opts.no_server) return callback();

        data.server.on('stopped', callback).stop();
      }
    ], done);
  };
};

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));

	callback(m.result != 'tesSUCCESS');
      })
    .on('error', function (m) {
	// console.log("error: %s", JSON.stringify(m));

	callback(m);
      })
    .submit();
};

var credit_limits = function (remote, balances, callback) {
  assert(3 === arguments.length);

  var limits = [];

  for (var src in balances) {
    var	values_src  = balances[src];
    var values	    = 'string' === typeof values_src ? [ values_src ] : values_src;

    for (var index in values) {
      limits.push( { "source" : src, "amount" : values[index] } );
    }
  }

  async.every(limits,
    function (limit, callback) {
      credit_limit(remote, limit.source, limit.amount,
	function (mismatch) { callback(!mismatch); });
    },
    function (every) {
      callback(!every);
    });
};

var payment = function (remote, src, dst, amount, callback) {
  assert(5 === arguments.length);

  remote.transaction()
    .payment(src, dst, amount)
    .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();
};

var payments = function (remote, balances, callback) {
  assert(3 === arguments.length);

  var sends = [];

  for (var src in balances) {
    var	values_src  = balances[src];
    var values	    = 'string' === typeof values_src ? [ values_src ] : values_src;

    for (var index in values) {
      var amount_json = values[index];
      var amount      = Amount.from_json(amount_json);

      sends.push( { "source" : src, "destination" : amount.issuer().to_json(), "amount" : amount_json } );
    }
  }

  async.every(sends,
    function (send, callback) {
      payment(remote, send.source, send.destination, send.amount,
	function (mismatch) { callback(!mismatch); });
    },
    function (every) {
      callback(!every);
    });
};

var transfer_rate = function (remote, src, billionths, callback) {
  assert(4 === arguments.length);

  remote.transaction()
    .account_set(src)
    .transfer_rate(billionths)
    .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();
};

var verify_balance = function (remote, src, amount_json, callback) {
  assert(4 === arguments.length);
  var amount  = Amount.from_json(amount_json);

  if (amount.is_native()) {
    // XXX Not implemented.
    callback();
  }
  else {
    remote.request_ripple_balance(src, amount.issuer().to_json(), amount.currency().to_json(), 'CURRENT')
      .once('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());

	  var account_balance = Amount.from_json(m.account_balance);

	  if (!account_balance.equals(amount)) {
	    console.log("verify_balance: failed: %s vs %s is %s", src, amount_json, amount.to_text_full());
	  }

	  callback(!account_balance.equals(amount));
	})
      .request();
  }
};

var verify_balances = function (remote, balances, callback) {
  var tests = [];

  for (var src in balances) {
    var	values_src  = balances[src];
    var values	    = 'string' === typeof values_src ? [ values_src ] : values_src;

    for (var index in values) {
      tests.push( { "source" : src, "amount" : values[index] } );
    }
  }

  async.every(tests,
    function (check, callback) {
      verify_balance(remote, check.source, check.amount,
	function (mismatch) { callback(!mismatch); });
    },
    function (every) {
      callback(!every);
    });
};

// --> owner: account
// --> seq: sequence number of creating transaction.
// --> taker_gets: json amount
// --> taker_pays: json amount
var verify_offer = function (remote, owner, seq, taker_gets, taker_pays, callback) {
  assert(6 === arguments.length);

  remote.request_ledger_entry('offer')
    .offer_id(owner, seq)
    .on('success', function (m) {
	var wrong   = (!Amount.from_json(m.node.TakerGets).equals(Amount.from_json(taker_gets))
	  || !Amount.from_json(m.node.TakerPays).equals(Amount.from_json(taker_pays)));

	if (wrong)
	  console.log("verify_offer: failed: %s", JSON.stringify(m));

	callback(wrong);
      })
    .request();
};

var verify_offer_not_found = function (remote, owner, seq, callback) {
  assert(4 === arguments.length);

  remote.request_ledger_entry('offer')
    .offer_id(owner, seq)
    .on('success', function (m) {
	console.log("verify_no_offer: found offer: %s", JSON.stringify(m));

	callback('entryFound');
      })
    .on('error', function (m) {
	// console.log("verify_no_offer: success: %s", JSON.stringify(m));

	callback('remoteError' !== m.error
	  || 'entryNotFound' !== m.remote.error);
      })
    .request();
};

exports.account_dump	      	= account_dump;

exports.build_setup		= build_setup;
exports.create_accounts	      	= create_accounts;
exports.credit_limit	      	= credit_limit;
exports.credit_limits	      	= credit_limits;
exports.payment		      	= payment;
exports.payments	      	= payments;
exports.build_teardown	      	= build_teardown;
exports.transfer_rate	      	= transfer_rate;
exports.verify_balance	      	= verify_balance;
exports.verify_balances	      	= verify_balances;
exports.verify_offer	      	= verify_offer;
{'fraction_non_alphanumeric': 0.16238595010811666, 'fraction_numerical': 0.00100205685354148, 'mean_word_length': 3.2659167604049495, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1257393', 'n_tokens_mistral': 6278, 'n_tokens_neox': 6071, 'n_words': 1366}