Skip to content

Commit

Permalink
Merge pull request #2 from TennyZhuang/uitest
Browse files Browse the repository at this point in the history
add a bunch of ui tests
  • Loading branch information
TennyZhuang committed Feb 1, 2024
2 parents 3ccca2e + 9d3cb84 commit 1a5e55b
Show file tree
Hide file tree
Showing 14 changed files with 554 additions and 1 deletion.
280 changes: 280 additions & 0 deletions Cargo.lock

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

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ license = "MIT OR Apache-2.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[[test]]
name = "ui-tests"
path = "tests/ui/test.rs"

[dependencies]

[dev-dependencies]
trybuild = "1"
futures = { version = "0.3", features = ["executor"] }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The main codes are copy from [lru-rs](https://github.com/jeromefroe/lru-rs), ver

The main motivation for implementing this project is that `LRUCache` should allow multiple immutable references obtained through `get` method.

The main idea is separating the value operating permissions from the data structure itself. I'll give an elaboration in my blog post later.
The main idea is separating the value operating permissions from the data structure itself. I'll give an elaboration in my blog post later. You can also take a look at [uitest](./tests/ui/test.rs), which explains the API design goals.

## Example

Expand Down
31 changes: 31 additions & 0 deletions tests/ui/concurrent-use-refs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use ref_stable_lru::LruCache;
use std::num::NonZeroUsize;

fn main() {
let mut cache: LruCache<&'static str, String> = LruCache::new(NonZeroUsize::new(3).unwrap());

let out = cache.scope(|mut handle, mut perm| {
handle.put("a", "bb".to_string(), &mut perm);
handle.put("b", "cc".to_string(), &mut perm);
handle.put("c", "dd".to_string(), &mut perm);

let futs = ["a", "b", "c"].iter().map(|k| {
let v = handle.get(k, &perm).unwrap();

async {
// Assert v is a reference.
let v: &String = v;
v.get(..1).unwrap().to_string()
}
});

let fut = async {
let out = futures::future::join_all(futs).await;
out.join(" ")
};

futures::executor::block_on(fut)
});

assert_eq!(out, "b c d".to_string());
}
20 changes: 20 additions & 0 deletions tests/ui/double-get-in-scope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use ref_stable_lru::LruCache;
use std::num::NonZeroUsize;

fn main() {
let mut cache: LruCache<&'static str, String> = LruCache::new(NonZeroUsize::new(3).unwrap());

let out = cache.scope(|mut handle, mut perm| {
handle.put("a", "b".to_string(), &mut perm);
handle.put("b", "c".to_string(), &mut perm);
handle.put("c", "d".to_string(), &mut perm);

// Success here, since `x`, `y` and `z` actually borrowed `perm` instead of `handle`.
let x = handle.get(&"a", &perm).unwrap().as_str();
let y = handle.get(&"b", &perm).unwrap().as_str();
let z = handle.get(&"c", &perm).unwrap().as_str();
[x, y, z].join(" ")
});

assert_eq!(out, "b c d".to_string());
}
12 changes: 12 additions & 0 deletions tests/ui/double-get-without-scope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use ref_stable_lru::LruCache;
use std::num::NonZeroUsize;

fn main() {
let mut cache: LruCache<&'static str, String> = LruCache::new(NonZeroUsize::new(2).unwrap());

let x = cache.get(&"a").unwrap().as_str();
// Should failed here, since `x` already mutually borrowed cache.
let y = cache.get(&"b").unwrap().as_str();
let z = cache.get(&"c").unwrap().as_str();
[x, y, z].join(" ");
}
22 changes: 22 additions & 0 deletions tests/ui/double-get-without-scope.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
error[E0499]: cannot borrow `cache` as mutable more than once at a time
--> tests/ui/double-get-without-scope.rs:9:13
|
7 | let x = cache.get(&"a").unwrap().as_str();
| ----- first mutable borrow occurs here
8 | // Should failed here, since `x` already mutually borrowed cache.
9 | let y = cache.get(&"b").unwrap().as_str();
| ^^^^^ second mutable borrow occurs here
10 | let z = cache.get(&"c").unwrap().as_str();
11 | [x, y, z].join(" ");
| - first borrow later used here

error[E0499]: cannot borrow `cache` as mutable more than once at a time
--> tests/ui/double-get-without-scope.rs:10:13
|
7 | let x = cache.get(&"a").unwrap().as_str();
| ----- first mutable borrow occurs here
...
10 | let z = cache.get(&"c").unwrap().as_str();
| ^^^^^ second mutable borrow occurs here
11 | [x, y, z].join(" ");
| - first borrow later used here

0 comments on commit 1a5e55b

Please sign in to comment.