Skip to content

Add Code Coverage GH action #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
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
46 changes: 14 additions & 32 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1045,8 +1045,8 @@ primary_field_guide_add_document_primary_key: |-
], Some("reference_number"))
.await
.unwrap();
getting_started_add_documents_md: |-
```toml
getting_started_add_documents: |-
// In your .toml file:
[dependencies]
meilisearch-sdk = "0.28.0"
# futures: because we want to block on futures
Expand All @@ -1057,9 +1057,8 @@ getting_started_add_documents_md: |-
serde_json = "1.0"
```

Documents in the Rust library are strongly typed.

```rust
// In your .rs file:
// Documents in the Rust library are strongly typed
#[derive(Serialize, Deserialize)]
struct Movie {
id: i64,
Expand All @@ -1069,23 +1068,17 @@ getting_started_add_documents_md: |-
release_date: i64,
genres: Vec<String>
}
```

You will often need this `Movie` struct in other parts of this documentation. (you will have to change it a bit sometimes)
You can also use schemaless values, by putting a `serde_json::Value` inside your own struct like this:

```rust
// You will often need this `Movie` struct in other parts of this documentation. (you will have to change it a bit sometimes)
// You can also use schemaless values, by putting a `serde_json::Value` inside your own struct like this:
#[derive(Serialize, Deserialize)]
struct Movie {
id: i64,
#[serde(flatten)]
value: serde_json::Value,
}
```

Then, add documents into the index:

```rust
// Then, add documents into the index:
use meilisearch_sdk::{
indexes::*,
client::*,
Expand All @@ -1099,7 +1092,7 @@ getting_started_add_documents_md: |-
fn main() { block_on(async move {
let client = Client::new("http://localhost:7700", Some("aSampleMasterKey"));

// reading and parsing the file
// Reading and parsing the file
let mut file = File::open("movies.json")
.unwrap();
let mut content = String::new();
Expand All @@ -1109,19 +1102,15 @@ getting_started_add_documents_md: |-
let movies_docs: Vec<Movie> = serde_json::from_str(&content)
.unwrap();

// adding documents
// Adding documents
client
.index("movies")
.add_documents(&movies_docs, None)
.await
.unwrap();
})}
```

[About this SDK](https://github.com/meilisearch/meilisearch-rust/)
getting_started_search_md: |-
You can build a `SearchQuery` and execute it later:
```rust
getting_started_search: |-
// You can build a `SearchQuery` and execute it later:
let query: SearchQuery = SearchQuery::new(&movies)
.with_query("botman")
.build();
Expand All @@ -1131,29 +1120,22 @@ getting_started_search_md: |-
.execute_query(&query)
.await
.unwrap();
```

You can build a `SearchQuery` and execute it directly:
```rust
// You can build a `SearchQuery` and execute it directly:
let results: SearchResults<Movie> = SearchQuery::new(&movies)
.with_query("botman")
.execute()
.await
.unwrap();
```

You can search in an index directly:
```rust
// You can search in an index directly:
let results: SearchResults<Movie> = client
.index("movies")
.search()
.with_query("botman")
.execute()
.await
.unwrap();
```

[About this SDK](https://github.com/meilisearch/meilisearch-rust/)
getting_started_update_ranking_rules: |-
let ranking_rules = [
"exactness",
Expand Down Expand Up @@ -1650,7 +1632,7 @@ get_experimental_features_1: |-
update_experimental_features_1: |-
let client = Client::new("http://localhost:7700", Some("apiKey"));
let features = ExperimentalFeatures::new(&client);
// update the feature you want here
features.set_metrics(true)
let res = features
.update()
.await
Expand Down
50 changes: 50 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Code Coverage

on:
pull_request:
push:
# trying and staging branches are for BORS config
branches:
- trying
- staging
- main

permissions:
contents: read
issues: write

env:
CARGO_TERM_COLOR: always

jobs:
coverage:
# Will not run if the event is a PR to bump-meilisearch-v* (so a pre-release PR)
# Will still run for each push to bump-meilisearch-v*
# Will not run if the actor is Dependabot (dependabot PRs)
if: github.event_name != 'pull_request' || !startsWith(github.base_ref, 'bump-meilisearch-v') || github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
name: Code Coverage
steps:
- uses: actions/checkout@v4
# Nightly Rust is used for cargo llvm-cov --doc below.
- uses: dtolnay/rust-toolchain@nightly
with:
components: llvm-tools-preview
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2
with:
tool: cargo-llvm-cov
- name: Meilisearch (latest version) setup with Docker
run: docker run -d -p 7700:7700 getmeili/meilisearch:latest meilisearch --no-analytics --master-key=masterKey
- name: Collect coverage data
# Generate separate reports for tests and doctests, and combine them.
run: |
cargo llvm-cov --no-report --all-features --workspace
cargo llvm-cov --no-report --doc --all-features --workspace
cargo llvm-cov report --doctests --codecov --output-path codecov.json
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: codecov.json
fail_ci_if_error: true
1 change: 1 addition & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,7 @@ impl<Http: HttpClient> Client<Http> {
#[serde(rename_all = "camelCase")]
pub struct ClientStats {
pub database_size: usize,
pub used_database_size: usize,
#[serde(with = "time::serde::rfc3339::option")]
pub last_update: Option<OffsetDateTime>,
pub indexes: HashMap<String, IndexStats>,
Expand Down
106 changes: 99 additions & 7 deletions src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ use serde::{Deserialize, Serialize};
/// Struct representing the experimental features result from the API.
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExperimentalFeaturesResult {}
pub struct ExperimentalFeaturesResult {
pub metrics: bool,
pub logs_route: bool,
pub contains_filter: bool,
pub network: bool,
pub edit_documents_by_function: bool,
}

/// Struct representing the experimental features request.
///
Expand All @@ -28,12 +34,30 @@ pub struct ExperimentalFeaturesResult {}
pub struct ExperimentalFeatures<'a, Http: HttpClient> {
#[serde(skip_serializing)]
client: &'a Client<Http>,

#[serde(skip_serializing_if = "Option::is_none")]
pub metrics: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contains_filter: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub logs_route: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub network: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub edit_documents_by_function: Option<bool>,
}

impl<'a, Http: HttpClient> ExperimentalFeatures<'a, Http> {
#[must_use]
pub fn new(client: &'a Client<Http>) -> Self {
ExperimentalFeatures { client }
ExperimentalFeatures {
client,
metrics: None,
logs_route: None,
network: None,
contains_filter: None,
edit_documents_by_function: None,
}
}

/// Get all the experimental features
Expand Down Expand Up @@ -88,6 +112,34 @@ impl<'a, Http: HttpClient> ExperimentalFeatures<'a, Http> {
)
.await
}

pub fn set_metrics(&mut self, metrics: bool) -> &mut Self {
self.metrics = Some(metrics);
self
}

pub fn set_logs_route(&mut self, logs_route: bool) -> &mut Self {
self.logs_route = Some(logs_route);
self
}

pub fn set_contains_filter(&mut self, contains_filter: bool) -> &mut Self {
self.contains_filter = Some(contains_filter);
self
}

pub fn set_edit_documents_by_function(
&mut self,
edit_documents_by_function: bool,
) -> &mut Self {
self.edit_documents_by_function = Some(edit_documents_by_function);
self
}

pub fn set_network(&mut self, network: bool) -> &mut Self {
self.network = Some(network);
self
}
}

#[cfg(test)]
Expand All @@ -96,12 +148,52 @@ mod tests {
use meilisearch_test_macro::meilisearch_test;

#[meilisearch_test]
async fn test_experimental_features_get(client: Client) {
let features = ExperimentalFeatures::new(&client);
// set feature here, once some exist again
async fn test_experimental_features_set_metrics(client: Client) {
let mut features = ExperimentalFeatures::new(&client);
features.set_metrics(true);
let _ = features.update().await.unwrap();

let res = features.get().await.unwrap();
assert!(res.metrics)
}

#[meilisearch_test]
async fn test_experimental_features_set_logs_route(client: Client) {
let mut features = ExperimentalFeatures::new(&client);
features.set_logs_route(true);
let _ = features.update().await.unwrap();

let res = features.get().await.unwrap();
assert!(res.logs_route)
}

#[meilisearch_test]
async fn test_experimental_features_set_contains_filter(client: Client) {
let mut features = ExperimentalFeatures::new(&client);
features.set_contains_filter(true);
let _ = features.update().await.unwrap();

let res = features.get().await.unwrap();
assert!(res.contains_filter)
}

#[meilisearch_test]
async fn test_experimental_features_set_network(client: Client) {
let mut features = ExperimentalFeatures::new(&client);
features.set_network(true);
let _ = features.update().await.unwrap();

let res = features.get().await.unwrap();
assert!(res.network)
}

#[meilisearch_test]
async fn test_experimental_features_set_edit_documents_by_function(client: Client) {
let mut features = ExperimentalFeatures::new(&client);
features.set_edit_documents_by_function(true);
let _ = features.update().await.unwrap();

let _res = features.get().await.unwrap();
// assert that the feature has been set once they exist again
let res = features.get().await.unwrap();
assert!(res.edit_documents_by_function)
}
}
Loading