rust_codecov/
commits.rs

1/**
2 * Codecov v2 API
3 * /repos endpoint returns a list of repos for a given owner.
4 */
5use serde::{Deserialize, Serialize};
6
7use crate::url::Url;
8
9/**
10 * CommitsAPIResponse is a struct that represents the response from the commits API.
11 */
12#[derive(Serialize, Deserialize, Debug)]
13pub struct CommitsAPIResponse {
14    pub results: Vec<Commit>,
15    pub count: usize,
16    pub next: Option<Url>,
17    pub previous: Option<Url>,
18    pub total_pages: usize,
19}
20
21/**
22 * CommitAuthor is a struct that represents the author of a commit.
23 */
24#[derive(Serialize, Deserialize, Debug)]
25pub struct CommitAuthor {
26    pub service: String,
27    pub username: String,
28    pub name: Option<String>,
29}
30
31/**
32 * Commit is a struct that represents a commit.
33 */
34#[derive(Serialize, Deserialize, Debug)]
35pub struct Commit {
36    pub commitid: String,
37    pub message: String,
38    pub timestamp: String, // TODO: ISO Date
39    pub ci_passed: bool,
40    pub author: CommitAuthor,
41    pub branch: Option<String>,
42    pub totals: Totals,
43    pub state: String,
44    pub parent: Option<String>,
45}
46
47/**
48 * Totals is a struct that represents the totals for a commit.
49 */
50#[derive(Serialize, Deserialize, Debug)]
51pub struct Totals {
52    pub files: usize,
53    pub lines: usize,
54    pub hits: usize,
55    pub misses: usize,
56    pub partials: usize,
57    pub coverage: f64,
58    pub branches: usize,
59    pub methods: usize,
60    pub sessions: usize,
61    pub complexity: f64,
62    pub complexity_total: f64,
63    pub complexity_ratio: f64,
64    pub diff: usize,
65}
66
67impl CommitsAPIResponse {
68    pub fn coverage(&self) -> Option<f64> {
69        if self.count == 0 {
70            return None;
71        }
72        let mut total_coverage = 0.0;
73        for commit in &self.results {
74            total_coverage += commit.totals.coverage;
75        }
76        Some(total_coverage / self.count as f64)
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    #[test]
83    fn test_coverage() {
84        use super::*;
85        let mut response = CommitsAPIResponse {
86            results: vec![],
87            count: 1,
88            next: None,
89            previous: None,
90            total_pages: 1,
91        };
92        assert_eq!(response.coverage(), Some(0.0));
93        let commit = Commit {
94            commitid: String::from("123"),
95            message: String::from("message"),
96            timestamp: String::from("timestamp"),
97            ci_passed: true,
98            author: CommitAuthor {
99                service: String::from("service"),
100                username: String::from("username"),
101                name: Some(String::from("name")),
102            },
103            branch: Some(String::from("branch")),
104            totals: Totals {
105                files: 1,
106                lines: 1,
107                hits: 1,
108                misses: 1,
109                partials: 1,
110                coverage: 2.0,
111                branches: 1,
112                methods: 1,
113                sessions: 1,
114                complexity: 1.0,
115                complexity_total: 1.0,
116                complexity_ratio: 1.0,
117                diff: 1,
118            },
119            state: String::from("state"),
120            parent: Some(String::from("parent")),
121        };
122        response.results.push(commit);
123        assert_eq!(response.coverage(), Some(2.0));
124    }
125}