Skip to content

Commit

Permalink
Convert some find integration tests to unit tests (#571)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Sep 28, 2022
1 parent 31955c3 commit 2eb8727
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 105 deletions.
168 changes: 93 additions & 75 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,8 @@ impl Index {
self.client.get_raw_transaction(&txid, None).into_option()
}

pub(crate) fn find(&self, ordinal: Ordinal) -> Result<Option<SatPoint>> {
if self.height()? < ordinal.height() {
pub(crate) fn find(&self, ordinal: u64) -> Result<Option<SatPoint>> {
if self.height()? < Ordinal(ordinal).height() {
return Ok(None);
}

Expand All @@ -462,11 +462,11 @@ impl Index {
let mut offset = 0;
for chunk in value.chunks_exact(11) {
let (start, end) = Index::decode_ordinal_range(chunk.try_into().unwrap());
if start <= ordinal.0 && ordinal.0 < end {
if start <= ordinal && ordinal < end {
let outpoint: OutPoint = Decodable::consensus_decode(key.as_slice())?;
return Ok(Some(SatPoint {
outpoint,
offset: offset + ordinal.0 - start,
offset: offset + ordinal - start,
}));
}
offset += end - start;
Expand Down Expand Up @@ -544,107 +544,75 @@ impl Index {
mod tests {
use super::*;

#[test]
fn height_limit() {
let bitcoin_rpc_server = test_bitcoincore_rpc::spawn();

bitcoin_rpc_server.mine_blocks(1);

let tempdir = TempDir::new().unwrap();
struct Context {
rpc_server: test_bitcoincore_rpc::Handle,
#[allow(unused)]
tempdir: TempDir,
index: Index,
}

let cookie_file = tempdir.path().join("cookie");
impl Context {
fn new() -> Self {
Self::with_args("")
}

fs::write(&cookie_file, "username:password").unwrap();
fn with_args(args: &str) -> Self {
let rpc_server = test_bitcoincore_rpc::spawn();

{
let tempdir = TempDir::new().unwrap();
let cookie_file = tempdir.path().join("cookie");
fs::write(&cookie_file, "username:password").unwrap();
let options = Options::try_parse_from(
format!(
"
ord
--rpc-url {}
--data-dir {}
--cookie-file {}
--height-limit 0
--chain regtest
{args}
",
bitcoin_rpc_server.url(),
rpc_server.url(),
tempdir.path().display(),
cookie_file.display(),
)
.split_whitespace(),
)
.unwrap();

let index = Index::open(&options).unwrap();

index.index().unwrap();

assert_eq!(index.height().unwrap(), 0);
Self {
rpc_server,
tempdir,
index,
}
}
}

#[test]
fn height_limit() {
{
let options = Options::try_parse_from(
format!(
"
ord
--rpc-url {}
--data-dir {}
--cookie-file {}
--height-limit 1
--chain regtest
",
bitcoin_rpc_server.url(),
tempdir.path().display(),
cookie_file.display(),
)
.split_whitespace(),
)
.unwrap();

let index = Index::open(&options).unwrap();

index.index().unwrap();
let context = Context::with_args("--height-limit 0");
context.rpc_server.mine_blocks(1);
context.index.index().unwrap();
assert_eq!(context.index.height().unwrap(), 0);
}

assert_eq!(index.height().unwrap(), 1);
{
let context = Context::with_args("--height-limit 1");
context.rpc_server.mine_blocks(1);
context.index.index().unwrap();
assert_eq!(context.index.height().unwrap(), 1);
}
}

#[test]
fn first_coinbase_transaction() {
let bitcoin_rpc_server = test_bitcoincore_rpc::spawn();

bitcoin_rpc_server.mine_blocks(1);

let tempdir = TempDir::new().unwrap();

let cookie_file = tempdir.path().join("cookie");

fs::write(&cookie_file, "username:password").unwrap();

let options = Options::try_parse_from(
format!(
"
ord
--rpc-url {}
--data-dir {}
--cookie-file {}
--height-limit 0
--chain regtest
",
bitcoin_rpc_server.url(),
tempdir.path().display(),
cookie_file.display(),
)
.split_whitespace(),
)
.unwrap();

let index = Index::open(&options).unwrap();

index.index().unwrap();

fn list_first_coinbase_transaction() {
let context = Context::new();
assert_eq!(
index
context
.index
.list(
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0"
.parse()
Expand All @@ -655,4 +623,54 @@ mod tests {
List::Unspent(vec![(0, 5000000000)])
)
}

#[test]
fn find_first_ordinal() {
let context = Context::new();
assert_eq!(
context.index.find(0).unwrap().unwrap(),
SatPoint {
outpoint: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0"
.parse()
.unwrap(),
offset: 0,
}
)
}

#[test]
fn find_second_ordinal() {
let context = Context::new();
assert_eq!(
context.index.find(1).unwrap().unwrap(),
SatPoint {
outpoint: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0"
.parse()
.unwrap(),
offset: 1,
}
)
}

#[test]
fn find_first_ordinal_of_second_block() {
let context = Context::new();
context.rpc_server.mine_blocks(1);
context.index.index().unwrap();
assert_eq!(
context.index.find(50 * COIN_VALUE).unwrap().unwrap(),
SatPoint {
outpoint: "9068a11b8769174363376b606af9a4b8b29dd7b13d013f4b0cbbd457db3c3ce5:0"
.parse()
.unwrap(),
offset: 0,
}
)
}

#[test]
fn find_unmined_ordinal() {
let context = Context::new();
assert_eq!(context.index.find(50 * COIN_VALUE).unwrap(), None);
}
}
1 change: 1 addition & 0 deletions src/sat_point.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;

#[derive(Debug, PartialEq)]
pub(crate) struct SatPoint {
pub(crate) outpoint: OutPoint,
pub(crate) offset: u64,
Expand Down
2 changes: 1 addition & 1 deletion src/subcommand/find.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl Find {

index.index()?;

match index.find(self.ordinal)? {
match index.find(self.ordinal.0)? {
Some(satpoint) => {
println!("{satpoint}");
Ok(())
Expand Down
13 changes: 8 additions & 5 deletions tests/command_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ impl CommandBuilder {
}
}

pub(crate) fn expected_stderr(self, expected_stderr: impl AsRef<str>) -> Self {
Self {
expected_stderr: Expected::String(expected_stderr.as_ref().to_owned()),
..self
}
}

pub(crate) fn stderr_regex(self, expected_stderr: impl AsRef<str>) -> Self {
Self {
expected_stderr: Expected::regex(expected_stderr.as_ref()),
Expand Down Expand Up @@ -73,11 +80,7 @@ impl CommandBuilder {
let output = command
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(if !matches!(self.expected_stderr, Expected::Ignore) {
Stdio::piped()
} else {
Stdio::inherit()
})
.stderr(Stdio::piped())
.env("HOME", self.tempdir.path())
.current_dir(&self.tempdir)
.args(self.args.split_whitespace())
Expand Down
31 changes: 7 additions & 24 deletions tests/find.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
use super::*;

#[test]
fn first_satoshi_new() {
fn find_command_returns_satpoint_for_ordinal() {
let rpc_server = test_bitcoincore_rpc::spawn();

CommandBuilder::new("find 0")
.rpc_server(&rpc_server)
.expected_stdout("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0:0\n")
.run();
}

#[test]
fn second_satoshi() {
SlowTest::new()
.command("find 1")
.expected_stdout("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0:1\n")
.run();
}

#[test]
fn first_satoshi_of_second_block() {
SlowTest::new()
.command("find 5000000000")
.blocks(1)
.expected_stdout("150ba822b458a19615e70a604d8dd9d3482fc165fa4e9cc150d74e11916ce8ae:0:0\n")
fn unmined_ordinal() {
let rpc_server = test_bitcoincore_rpc::spawn();
CommandBuilder::new("find 5000000000")
.rpc_server(&rpc_server)
.expected_stderr("error: Ordinal has not been mined as of index height\n")
.expected_status(1)
.run();
}

Expand All @@ -42,12 +34,3 @@ fn first_satoshi_spent_in_second_block() {
.expected_stdout("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0:0\n")
.run();
}

#[test]
fn unmined_satoshi_in_second_block() {
SlowTest::new()
.expected_stderr("error: Ordinal has not been mined as of index height\n")
.expected_status(1)
.command("find 5000000000")
.run();
}

0 comments on commit 2eb8727

Please sign in to comment.