Skip to content

Commit

Permalink
chore: Add tests (#2)
Browse files Browse the repository at this point in the history
* chore: Add tests

* fix clippy

* Update src/client.rs

Co-authored-by: Maciej Zwoliński <[email protected]>

* Apply suggestions from code review

* fix test

---------

Co-authored-by: Maciej Zwoliński <[email protected]>
  • Loading branch information
oblique and zvolin authored Jan 16, 2024
1 parent 40598a1 commit e8f664a
Show file tree
Hide file tree
Showing 8 changed files with 1,049 additions and 37 deletions.
83 changes: 83 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ void = "1.0.2"

[dev-dependencies]
hex = "0.4.3"
multihash-codetable = { version = "0.1.1", features = ["digest", "sha2"] }
tokio = { version = "1.35.1", features = ["rt", "macros", "time"] }
159 changes: 159 additions & 0 deletions src/cid_prefix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const DAG_PB: u64 = 0x70;
const SHA2_256: u64 = 0x12;
const SHA2_256_SIZE: usize = 0x20;

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct CidPrefix {
version: Version,
codec: u64,
Expand All @@ -15,6 +16,16 @@ pub(crate) struct CidPrefix {
}

impl CidPrefix {
#[allow(dead_code)]
pub(crate) fn from_cid<const S: usize>(cid: &CidGeneric<S>) -> CidPrefix {
CidPrefix {
version: cid.version(),
codec: cid.codec(),
multihash_code: cid.hash().code(),
multihash_size: cid.hash().size().into(),
}
}

pub(crate) fn from_bytes(bytes: &[u8]) -> Option<CidPrefix> {
let (raw_version, rest) = unsigned_varint::decode::u64(bytes).ok()?;
let (codec, rest) = unsigned_varint::decode::u64(rest).ok()?;
Expand All @@ -41,6 +52,37 @@ impl CidPrefix {
})
}

#[allow(dead_code)]
pub(crate) fn to_bytes(&self) -> Vec<u8> {
match self.version {
// CIDv0 is a naked multihash that with fixed code and size
Version::V0 => {
let mut buf = unsigned_varint::encode::u64_buffer();
let bytes1 = unsigned_varint::encode::u64(SHA2_256, &mut buf);

let mut buf = unsigned_varint::encode::u64_buffer();
let bytes2 = unsigned_varint::encode::u64(SHA2_256_SIZE as u64, &mut buf);

[bytes1, bytes2].concat()
}
Version::V1 => {
let mut buf = unsigned_varint::encode::u64_buffer();
let version = unsigned_varint::encode::u64(self.version as u64, &mut buf);

let mut buf = unsigned_varint::encode::u64_buffer();
let codec = unsigned_varint::encode::u64(self.codec, &mut buf);

let mut buf = unsigned_varint::encode::u64_buffer();
let multihash_code = unsigned_varint::encode::u64(self.multihash_code, &mut buf);

let mut buf = unsigned_varint::encode::usize_buffer();
let multihash_size = unsigned_varint::encode::usize(self.multihash_size, &mut buf);

[version, codec, multihash_code, multihash_size].concat()
}
}
}

pub(crate) fn to_cid<const S: usize>(&self, data: &[u8]) -> Option<CidGeneric<S>> {
if self.multihash_size > S {
return None;
Expand All @@ -53,3 +95,120 @@ impl CidPrefix {
CidGeneric::new(self.version, self.codec, hash).ok()
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::RAW_CODEC;
use cid::Cid;

#[test]
fn cid_v1_to_cid_prefix() {
let cid = "bafkreigjh3xc2dnqf4ikzr2gbwkxnyjc3t4m2u6ex6g7zlq3hz2oxt77li"
.parse::<Cid>()
.unwrap();
let cid_prefix = CidPrefix::from_cid(&cid);

assert_eq!(
cid_prefix,
CidPrefix {
version: Version::V1,
codec: RAW_CODEC,
multihash_code: SHA2_256,
multihash_size: SHA2_256_SIZE,
}
);
}

#[test]
fn cid_v1_bytes_to_cid_prefix() {
let cid = "bafkreigjh3xc2dnqf4ikzr2gbwkxnyjc3t4m2u6ex6g7zlq3hz2oxt77li"
.parse::<Cid>()
.unwrap();
let cid_prefix = CidPrefix::from_bytes(&cid.to_bytes()).unwrap();

assert_eq!(
cid_prefix,
CidPrefix {
version: Version::V1,
codec: RAW_CODEC,
multihash_code: SHA2_256,
multihash_size: SHA2_256_SIZE,
}
);
}

#[test]
fn cid_prefix_v1_to_bytes() {
assert_eq!(
CidPrefix {
version: Version::V1,
codec: RAW_CODEC,
multihash_code: SHA2_256,
multihash_size: SHA2_256_SIZE,
}
.to_bytes(),
[1, 0x55, SHA2_256 as u8, SHA2_256_SIZE as u8],
);
}

#[test]
fn cid_v0_to_cid_prefix() {
let cid = "QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB"
.parse::<Cid>()
.unwrap();
let cid_prefix = CidPrefix::from_cid(&cid);

assert_eq!(
cid_prefix,
CidPrefix {
version: Version::V0,
codec: DAG_PB,
multihash_code: SHA2_256,
multihash_size: SHA2_256_SIZE,
}
);
}

#[test]
fn cid_v0_bytes_to_cid_prefix() {
let cid = "QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB"
.parse::<Cid>()
.unwrap();
let cid_prefix = CidPrefix::from_bytes(&cid.to_bytes()).unwrap();

assert_eq!(
cid_prefix,
CidPrefix {
version: Version::V0,
codec: DAG_PB,
multihash_code: SHA2_256,
multihash_size: SHA2_256_SIZE,
}
);
}

#[test]
fn cid_prefix_v0_to_bytes() {
assert_eq!(
CidPrefix {
version: Version::V0,
codec: DAG_PB,
multihash_code: SHA2_256,
multihash_size: SHA2_256_SIZE,
}
.to_bytes(),
[SHA2_256 as u8, SHA2_256_SIZE as u8],
);
}

#[test]
fn invalid_bytes() {
assert!(CidPrefix::from_bytes(&[]).is_none());
assert!(CidPrefix::from_bytes(&[1, 0x55]).is_none());
assert!(CidPrefix::from_bytes(&[1, 0x55, 0x12]).is_none());
assert!(CidPrefix::from_bytes(&[66, 0x55, 0x12, 32]).is_none());
assert!(CidPrefix::from_bytes(&[0x12, 33]).is_none());
assert!(CidPrefix::from_bytes(&[0x13, 32]).is_none());
}
}
Loading

0 comments on commit e8f664a

Please sign in to comment.