Skip to content

Commit

Permalink
Merge pull request #22 from persevie/chore/test-coverage
Browse files Browse the repository at this point in the history
Add more tests for Grimoire CSS
  • Loading branch information
dmtrshat authored Nov 1, 2024
2 parents 8051f16 + dc7f723 commit af2b8be
Show file tree
Hide file tree
Showing 7 changed files with 280 additions and 10 deletions.
56 changes: 56 additions & 0 deletions .github/workflows/build_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,62 @@ jobs:
echo "NEW_TAG=v$CURRENT_VERSION" >> $GITHUB_OUTPUT
fi
test_coverage:
name: Lint and test
runs-on: ubuntu-latest
needs: determine_release
if: needs.determine_release.outputs.SHOULD_RELEASE == 'true'

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable

- name: Install llvm-tools-preview
run: rustup component add llvm-tools-preview

- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-registry-
- name: Cache Cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-git-
- name: Cache Cargo build
uses: actions/cache@v4
with:
path: target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-build-
- name: Install grcov
run: cargo install grcov

- name: Run tests with coverage
run: ./scripts/coverage.sh

- name: Codecov upload lcov.info
uses: codecov/codecov-action@v4
with:
files: lcov.info
token: ${{ secrets.CODECOV_TOKEN }}

build:
name: Build
runs-on: ${{ matrix.runs-on }}
Expand Down
11 changes: 7 additions & 4 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Rust
uses: actions-rs/toolchain@v1
Expand Down Expand Up @@ -44,13 +46,14 @@ jobs:
restore-keys: |
${{ runner.os }}-cargo-build-
- name: Install grcov
run: cargo install grcov

- name: Check formatting with rustfmt
run: cargo fmt -- --check

- name: Run clippy
run: cargo clippy -- -D warnings

- name: Run tests with coverage
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
run: ./scripts/coverage.sh --upload
- name: Run tests
run: cargo test
64 changes: 61 additions & 3 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ include = [
name = "grimoire_css_lib"
crate-type = ["lib"]

[language.rust]
lsp = { command = "rust-analyzer", args = [] }

[profile.release]
lto = true
codegen-units = 1
Expand All @@ -40,3 +37,6 @@ rayon = "1.10.0"
regex = "1.11.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[dev-dependencies]
tempfile = "3.13.0"
12 changes: 12 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
coverage:
status:
project:
default:
informational: true
target: 80%
patch:
default:
informational: true
target: 80%
github_checks:
annotations: false
38 changes: 38 additions & 0 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,41 @@ pub fn read_messages() -> Vec<String> {
let buffer = MESSAGE_BUFFER.lock().unwrap();
buffer.clone()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_add_and_read_messages() {
// Clear any existing messages in the buffer
{
let mut buffer = MESSAGE_BUFFER.lock().unwrap();
buffer.clear();
}

// Add messages to the buffer
add_message("Message 1".to_string());
add_message("Message 2".to_string());

// Read messages and verify content
let messages = read_messages();
assert_eq!(
messages,
vec!["Message 1".to_string(), "Message 2".to_string()]
);
}

#[test]
fn test_empty_buffer() {
// Clear any existing messages in the buffer
{
let mut buffer = MESSAGE_BUFFER.lock().unwrap();
buffer.clear();
}

// Read messages from an empty buffer and check if it's empty
let messages = read_messages();
assert!(messages.is_empty());
}
}
103 changes: 103 additions & 0 deletions src/core/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -591,3 +591,106 @@ impl Config {
paths
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::Write;
use tempfile::tempdir;

#[test]
fn test_default_config() {
let config = Config::default();
assert!(config.variables.is_none());
assert!(config.scrolls.is_none());
assert!(config.shared.is_none());
assert!(config.critical.is_none());
assert_eq!(config.projects.len(), 1);
assert_eq!(config.projects[0].project_name, "main");
}

#[test]
fn test_load_nonexistent_config() {
let dir = tempdir().unwrap();
let result = Config::load(dir.path());
assert!(result.is_err());
}

#[test]
fn test_save_and_load_config() {
let dir = tempdir().unwrap();
let config = Config::default();
config.save(dir.path()).expect("Failed to save config");

let loaded_config = Config::load(dir.path()).expect("Failed to load config");
assert_eq!(
config.projects[0].project_name,
loaded_config.projects[0].project_name
);
}

#[test]
fn test_expand_glob_patterns() {
let dir = tempdir().unwrap();
let file_path = dir.path().join("test.txt");
File::create(&file_path).unwrap();

let patterns = vec![format!("{}/**/*.txt", dir.path().to_str().unwrap())];
let expanded = Config::expand_glob_patterns(patterns);
assert_eq!(expanded.len(), 1);
assert!(expanded[0].ends_with("test.txt"));
}

#[test]
fn test_find_custom_animations_empty() {
let dir = tempdir().unwrap();
let animations = Config::find_custom_animations(dir.path()).unwrap();
assert!(animations.is_empty());
}

#[test]
fn test_find_custom_animations_with_files() {
let dir = tempdir().unwrap();
let animations_dir = dir.path().join("grimoire").join("animations");
fs::create_dir_all(&animations_dir).unwrap();

let animation_file = animations_dir.join("fade_in.css");
let mut file = File::create(&animation_file).unwrap();
writeln!(
file,
"@keyframes fade_in {{ from {{ opacity: 0; }} to {{ opacity: 1; }} }}"
)
.unwrap();

let animations = Config::find_custom_animations(dir.path()).unwrap();
assert_eq!(animations.len(), 1);
assert!(animations.contains_key("fade_in"));
}

#[test]
fn test_get_common_spells_set() {
let json = ConfigJSON {
schema: None,
variables: None,
scrolls: None,
projects: vec![],
shared: Some(vec![ConfigSharedJSON {
output_path: "styles.css".to_string(),
styles: Some(vec!["spell1".to_string(), "spell2".to_string()]),
css_custom_properties: None,
}]),
critical: Some(vec![ConfigCriticalJSON {
file_to_inline_paths: vec!["index.html".to_string()],
styles: Some(vec!["spell3".to_string()]),
css_custom_properties: None,
}]),
};

let common_spells = Config::get_common_spells_set(&json);
assert_eq!(common_spells.len(), 3);
assert!(common_spells.contains("spell1"));
assert!(common_spells.contains("spell2"));
assert!(common_spells.contains("spell3"));
}
}

0 comments on commit af2b8be

Please sign in to comment.