initial commit

- Added basic structure so tests won't error
This commit is contained in:
2025-09-21 17:00:51 -04:00
commit 75a5e06077
7 changed files with 461 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/target

14
.glimpse Normal file
View File

@@ -0,0 +1,14 @@
exclude = [
"**/.git/**",
"**/.svn/**",
"**/.hg/**",
"**/target/**",
"**/node_modules/**",
"**/dist/**",
"**/build/**",
]
max_size = 10485760
max_depth = 20
output = "both"
hidden = false
no_ignore = false

245
Cargo.lock generated Normal file
View File

@@ -0,0 +1,245 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "assert_cmd"
version = "2.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66"
dependencies = [
"anstyle",
"bstr",
"doc-comment",
"libc",
"predicates",
"predicates-core",
"predicates-tree",
"wait-timeout",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bstr"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
dependencies = [
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "difflib"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "float-cmp"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
dependencies = [
"num-traits",
]
[[package]]
name = "kvs"
version = "0.1.0"
dependencies = [
"assert_cmd",
"predicates",
]
[[package]]
name = "libc"
version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "predicates"
version = "3.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"
dependencies = [
"anstyle",
"difflib",
"float-cmp",
"normalize-line-endings",
"predicates-core",
"regex",
]
[[package]]
name = "predicates-core"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"
[[package]]
name = "predicates-tree"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"
dependencies = [
"predicates-core",
"termtree",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "serde"
version = "1.0.226"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.226"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.226"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termtree"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "wait-timeout"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
dependencies = [
"libc",
]

9
Cargo.toml Normal file
View File

@@ -0,0 +1,9 @@
[package]
name = "kvs"
version = "0.1.0"
authors = ["Minh Tran <minh@minhtrannhat.com>"]
edition = "2024"
[dependencies]
assert_cmd = "2.0.17"
predicates = "3.1.3"

3
src/bin/kvs.rs Normal file
View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, wolrld");
}

34
src/lib.rs Normal file
View File

@@ -0,0 +1,34 @@
pub struct KvStore {}
impl KvStore {
pub fn new() -> Self {
unimplemented!()
}
pub fn set(&mut self, key: String, value: String) {
unimplemented!()
}
pub fn get(&mut self, key: String) -> Option<String> {
unimplemented!()
}
pub fn remove(&mut self, key: String) {
unimplemented!()
}
}
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}

155
tests/tests.rs Normal file
View File

@@ -0,0 +1,155 @@
use assert_cmd::prelude::*;
use kvs::KvStore;
use predicates::str::contains;
use std::process::Command;
// `kvs` with no args should exit with a non-zero code.
#[test]
fn cli_no_args() {
Command::cargo_bin("kvs").unwrap().assert().failure();
}
// `kvs -V` should print the version
#[test]
fn cli_version() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["-V"])
.assert()
.stdout(contains(env!("CARGO_PKG_VERSION")));
}
// `kvs get <KEY>` should print "unimplemented" to stderr and exit with non-zero code
#[test]
fn cli_get() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["get", "key1"])
.assert()
.failure()
.stderr(contains("unimplemented"));
}
// `kvs set <KEY> <VALUE>` should print "unimplemented" to stderr and exit with non-zero code
#[test]
fn cli_set() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["set", "key1", "value1"])
.assert()
.failure()
.stderr(contains("unimplemented"));
}
// `kvs rm <KEY>` should print "unimplemented" to stderr and exit with non-zero code
#[test]
fn cli_rm() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["rm", "key1"])
.assert()
.failure()
.stderr(contains("unimplemented"));
}
#[test]
fn cli_invalid_get() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["get"])
.assert()
.failure();
Command::cargo_bin("kvs")
.unwrap()
.args(&["get", "extra", "field"])
.assert()
.failure();
}
#[test]
fn cli_invalid_set() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["set"])
.assert()
.failure();
Command::cargo_bin("kvs")
.unwrap()
.args(&["set", "missing_field"])
.assert()
.failure();
Command::cargo_bin("kvs")
.unwrap()
.args(&["set", "extra", "extra", "field"])
.assert()
.failure();
}
#[test]
fn cli_invalid_rm() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["rm"])
.assert()
.failure();
Command::cargo_bin("kvs")
.unwrap()
.args(&["rm", "extra", "field"])
.assert()
.failure();
}
#[test]
fn cli_invalid_subcommand() {
Command::cargo_bin("kvs")
.unwrap()
.args(&["unknown", "subcommand"])
.assert()
.failure();
}
// Should get previously stored value
#[test]
fn get_stored_value() {
let mut store = KvStore::new();
store.set("key1".to_owned(), "value1".to_owned());
store.set("key2".to_owned(), "value2".to_owned());
assert_eq!(store.get("key1".to_owned()), Some("value1".to_owned()));
assert_eq!(store.get("key2".to_owned()), Some("value2".to_owned()));
}
// Should overwrite existent value
#[test]
fn overwrite_value() {
let mut store = KvStore::new();
store.set("key1".to_owned(), "value1".to_owned());
assert_eq!(store.get("key1".to_owned()), Some("value1".to_owned()));
store.set("key1".to_owned(), "value2".to_owned());
assert_eq!(store.get("key1".to_owned()), Some("value2".to_owned()));
}
// Should get `None` when getting a non-existent key
#[test]
fn get_non_existent_value() {
let mut store = KvStore::new();
store.set("key1".to_owned(), "value1".to_owned());
assert_eq!(store.get("key2".to_owned()), None);
}
#[test]
fn remove_key() {
let mut store = KvStore::new();
store.set("key1".to_owned(), "value1".to_owned());
store.remove("key1".to_owned());
assert_eq!(store.get("key1".to_owned()), None);
}