Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/rules/code-coverage.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Code Coverage Measurement

- Use `make coverage` to measure code coverage. This is the authoritative source.

2 changes: 0 additions & 2 deletions .claude/rules/github-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ paths:

- Actions must represent a single purpose and a single concern.
- Compose actions if they need to provide a more complex functionality.
- GitHub actions must be named after their purpose and intent. Avoid names like "setup", "ci", and such. They need to describe the intention, and purpose behind them.

4 changes: 1 addition & 3 deletions .claude/rules/github-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ paths:

- Always use Makefile targets in the workflow to avoid code duplication (if they need to run something that is already present in a Makefile).
- Never add the tests that use LLMs to GitHub workflows, because the default GitHub worker does not have the capacity to run them.
- Only add unit tests or linters to GitHub workflows.
- Only add unit tests to GitHub workflows.
- Keep GitHub workflows responsible for only a single concern. For example, run linter, and tests in parallel.
- Treat GitHub workflows as a coding project. Use composable actions, factor similar concerns into actions.
- Encapsulate functionalities in composable actions.
- Keep the workflows clean and purposeful.
- GitHub workflows must be named after their purpose and intent. Avoid names like "setup", "ci", and such. They need to describe the intention, and purpose behind them.

2 changes: 2 additions & 0 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[profile.default]
slow-timeout = { period = "100ms", terminate-after = 3 }
Comment thread
mcharytoniuk marked this conversation as resolved.
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,22 @@ clippy:
.PHONY: coverage
coverage: node_modules
cargo llvm-cov clean --workspace
cargo llvm-cov --workspace --no-report
cargo llvm-cov nextest --workspace --no-report
cargo llvm-cov report --json --output-path target/llvm-cov.json
cargo llvm-cov report
npx rust-coverage-check target/llvm-cov.json \
--workspace-root $(CURDIR) \
--gated rhai_components \
--required-percent 100
--gated poet=80 \
--gated rhai_components=100

.PHONY: coverage-clean
coverage-clean:
cargo llvm-cov clean --workspace
rm -f target/llvm-cov.json

.PHONY: coverage-report
coverage-report:
cargo llvm-cov nextest --workspace --html

.PHONY: fmt
fmt: node_modules
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"type": "module",
"version": "0.1.0",
"devDependencies": {
"@intentee/rust-coverage-check": "0.1.0",
"@intentee/rust-coverage-check": "0.3.1",
"@types/hotwired__turbo": "^8.0.4",
"@types/react": "^19.1.10",
"@types/react-dom": "^19.1.7",
Expand Down
34 changes: 34 additions & 0 deletions poet/src/anyhow_error_aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,37 @@ impl fmt::Display for AnyhowErrorAggregate {
Ok(())
}
}

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

use super::*;

#[test]
fn display_lists_every_aggregated_error() {
let aggregate = AnyhowErrorAggregate::default();

aggregate
.errors
.insert("first".to_string(), anyhow!("boom one"));
aggregate
.errors
.insert("second".to_string(), anyhow!("boom two"));

let rendered = aggregate.to_string();

assert!(rendered.contains("(2 total)"));
assert!(rendered.contains("[first]"));
assert!(rendered.contains("[second]"));
}

#[test]
fn display_reports_zero_when_empty() {
assert!(
AnyhowErrorAggregate::default()
.to_string()
.contains("(0 total)")
);
}
}
80 changes: 80 additions & 0 deletions poet/src/app_dir_desktop_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,83 @@ impl Display for AppDirDesktopEntry {
)
}
}

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

use super::*;

#[test]
fn parses_all_fields_from_desktop_entry() -> Result<()> {
let entry = AppDirDesktopEntry::parse(indoc! {r#"
[Desktop Entry]
Name=mysite
X-PoetVersion=0.6.2
X-SiteVersion=1.2.3
X-ImplementationTitle=My Site
"#})?;

assert_eq!(entry.name, "mysite");
assert_eq!(entry.poet_version, "0.6.2");
assert_eq!(entry.site_version, "1.2.3");
assert_eq!(entry.title, "My Site");

Ok(())
}

#[test]
fn errors_when_required_field_is_missing() {
assert!(
AppDirDesktopEntry::parse(indoc! {r#"
[Desktop Entry]
Name=mysite
X-SiteVersion=1.2.3
X-ImplementationTitle=My Site
"#})
.is_err()
);
}

#[test]
fn errors_when_field_is_defined_more_than_once() {
assert!(
AppDirDesktopEntry::parse(indoc! {r#"
[Desktop Entry]
Name=mysite
Name=othersite
X-PoetVersion=0.6.2
X-SiteVersion=1.2.3
X-ImplementationTitle=My Site
"#})
.is_err()
);
}

#[test]
fn errors_when_primary_section_is_missing() {
assert!(
AppDirDesktopEntry::parse(indoc! {r#"
[Other Section]
Name=mysite
"#})
.is_err()
);
}

#[test]
fn renders_desktop_entry_with_all_fields() {
let rendered = AppDirDesktopEntry {
name: "mysite".to_string(),
poet_version: "0.6.2".to_string(),
site_version: "1.2.3".to_string(),
title: "My Site".to_string(),
}
.to_string();

assert!(rendered.contains("Name=mysite"));
assert!(rendered.contains("X-PoetVersion=0.6.2"));
assert!(rendered.contains("X-SiteVersion=1.2.3"));
assert!(rendered.contains("X-ImplementationTitle=My Site"));
}
}
20 changes: 20 additions & 0 deletions poet/src/assert_valid_desktop_entry_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,23 @@ pub fn assert_valid_desktop_entry_string(input: &str) -> Result<String> {
))
}
}

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

#[test]
fn returns_string_when_valid() -> Result<()> {
assert_eq!(
assert_valid_desktop_entry_string("My Site")?,
"My Site".to_string()
);

Ok(())
}

#[test]
fn errors_when_string_contains_control_character() {
assert!(assert_valid_desktop_entry_string("line\nbreak").is_err());
}
}
Loading
Loading