From ef6d16ebd129417a1ebc3b12ed6b1f3c2990dd93 Mon Sep 17 00:00:00 2001 From: Irina Gaynanova Date: Fri, 3 Nov 2023 11:18:40 -0400 Subject: [PATCH] add code coverage workflow --- .Rbuildignore | 1 + .github/workflows/test-coverage.yaml | 50 +++++++++++++++++++++++ README.Rmd | 1 + README.md | 27 ++++++------ codecov.yml | 14 +++++++ man/figures/README-unnamed-chunk-3-1.png | Bin 66747 -> 66706 bytes man/figures/README-unnamed-chunk-3-2.png | Bin 35948 -> 35907 bytes 7 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/test-coverage.yaml create mode 100644 codecov.yml diff --git a/.Rbuildignore b/.Rbuildignore index 1d85ebc2..c586da17 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -16,3 +16,4 @@ ^cran-comments\.md$ ^CRAN-RELEASE$ ^\.github$ +^codecov\.yml$ diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml new file mode 100644 index 00000000..27d45283 --- /dev/null +++ b/.github/workflows/test-coverage.yaml @@ -0,0 +1,50 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +name: test-coverage + +jobs: + test-coverage: + runs-on: ubuntu-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + + steps: + - uses: actions/checkout@v3 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::covr + needs: coverage + + - name: Test coverage + run: | + covr::codecov( + quiet = FALSE, + clean = FALSE, + install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") + ) + shell: Rscript {0} + + - name: Show testthat output + if: always() + run: | + ## -------------------------------------------------------------------- + find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash + + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v3 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package diff --git a/README.Rmd b/README.Rmd index d15efed4..692f58a0 100644 --- a/README.Rmd +++ b/README.Rmd @@ -19,6 +19,7 @@ knitr::opts_chunk$set( [![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/iglu)](https://cran.r-project.org/package=iglu)[![](https://cranlogs.r-pkg.org/badges/iglu)](https://CRAN.R-project.org/package=iglu) [![R-CMD-check](https://github.com/irinagain/iglu/workflows/R-CMD-check/badge.svg)](https://github.com/irinagain/iglu/actions) [![R-CMD-check](https://github.com/irinagain/iglu/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/irinagain/iglu/actions/workflows/R-CMD-check.yaml) +[![Codecov test coverage](https://codecov.io/gh/irinagain/iglu/branch/master/graph/badge.svg)](https://app.codecov.io/gh/irinagain/iglu?branch=master) iglu: Interpreting data from Continuous Glucose Monitors (CGMs) diff --git a/README.md b/README.md index 22f8fc7c..02194479 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/iglu)](https://cran.r-project.org/package=iglu)[![](https://cranlogs.r-pkg.org/badges/iglu)](https://CRAN.R-project.org/package=iglu) [![R-CMD-check](https://github.com/irinagain/iglu/workflows/R-CMD-check/badge.svg)](https://github.com/irinagain/iglu/actions) +[![R-CMD-check](https://github.com/irinagain/iglu/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/irinagain/iglu/actions/workflows/R-CMD-check.yaml) +[![Codecov test +coverage](https://codecov.io/gh/irinagain/iglu/branch/master/graph/badge.svg)](https://app.codecov.io/gh/irinagain/iglu?branch=master) # iglu: Interpreting data from Continuous Glucose Monitors (CGMs) @@ -20,18 +23,17 @@ the package, see [package website](https://irinagain.github.io/iglu/). To cite: -- Broll S, Urbanek J, Buchanan D, Chun E, Muschelli J, Punjabi N and - Gaynanova I (2021). [Interpreting blood glucose data with R package - iglu.](https://doi.org/10.1371/journal.pone.0248560) *PLoS One*, - Vol. 16, No. 4, e0248560. +- Broll S, Urbanek J, Buchanan D, Chun E, Muschelli J, Punjabi N and + Gaynanova I (2021). [Interpreting blood glucose data with R package + iglu.](https://doi.org/10.1371/journal.pone.0248560) *PLoS One*, Vol. + 16, No. 4, e0248560. -- Broll S, Buchanan D, Chun E, Muschelli J, Fernandes N, Seo J, Shih - J, Urbanek J, Schwenck J, Gaynanova I (2021). iglu: Interpreting - Glucose Data from Continuous Glucose Monitors. R package version - 3.0.0. +- Broll S, Buchanan D, Chun E, Muschelli J, Fernandes N, Seo J, Shih J, + Urbanek J, Schwenck J, Gaynanova I (2021). iglu: Interpreting Glucose + Data from Continuous Glucose Monitors. R package version 3.0.0. -iglu comes with two example datasets: example_data_1\_subject and -example_data_5\_subject. These data are collected using Dexcom G4 CGM on +iglu comes with two example datasets: example_data_1_subject and +example_data_5_subject. These data are collected using Dexcom G4 CGM on subjects with Type II diabetes. Each dataset follows the structure iglu’s functions are designed around. Note that the 1 subject data is a subset of the 5 subject data. See the examples below for loading and @@ -54,8 +56,6 @@ devtools::install_github("irinagain/iglu", build_vignettes = TRUE) ``` r library(iglu) -#> Warning in register(): Can't find generic `scale_type` in package ggplot2 to -#> register S3 method. data(example_data_1_subject) # Load single subject data ## Plot data @@ -66,6 +66,7 @@ plot_glu(example_data_1_subject) ``` r + # Summary statistics and some metrics summary_glu(example_data_1_subject) #> # A tibble: 1 × 7 @@ -102,11 +103,13 @@ conga(example_data_1_subject) data(example_data_5_subject) plot_glu(example_data_5_subject, plottype = 'lasagna', datatype = 'average') +#> Warning: Removed 5 rows containing missing values (`geom_tile()`). ``` ``` r + below_percent(example_data_5_subject, targets = c(80,170,260)) #> # A tibble: 5 × 4 #> id below_170 below_260 below_80 diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000..04c55859 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,14 @@ +comment: false + +coverage: + status: + project: + default: + target: auto + threshold: 1% + informational: true + patch: + default: + target: auto + threshold: 1% + informational: true diff --git a/man/figures/README-unnamed-chunk-3-1.png b/man/figures/README-unnamed-chunk-3-1.png index c09a89bef4f36380769f18617d77a81cf2c04d3c..60043bf53d29c2c6250820c4ad456ee79728d10c 100644 GIT binary patch literal 66706 zcmbTeWmuJ4*EY;r(jp;^G*SZ6-5{NUv~&y7-AGC|(n}Fkx?8#%L8ZGyx|??{_IW|9n5($KqPonsdxKN1WpvWA68=$}*48Nzf4x5FW|NzEDFzfWi9x^Q zy(!#@WcgI3`Ux?J;e7N`=Hm}Sw7>P7m5qsYHs1$kFV-{n{5IyDcjq6*)iLX(%+o@d zNlIAO#+NI5);l`|T-tm`ANh{5FvTQ4OQwT7S!r*X-r1w3=`_{wZX(@u`BuO?*2?r{BFz$e zA;`nEO{l+n_r-NJyJ04}tDjmX#yS=`!s7BXmNKt18uBtF>u2Eu(OOnKJ%{1vb?XEc zP~Tk^OKXAOqx^Xm5#r3dkt>HdnqNdZwZ3JiO57N-)Z%s13WpkGVz~6Oxn7@Kx@l#l zp)M!z6Fww~qGi>rK9K13*Q%!fjBQxs;vc&_+p9E_*bm8R$st)&O{7TNc`ee3{~@|h ztS#7c8=uVx_eC5fmbH(bQSKLXl1;0Rn|W3r&wnm%FSIjW+#=MzdUM5&BB3Zf?bYPE+Ocglsa*hjhHHzGJ(EN-7Ly%Oh6u!yC;R( z+3cu(Y{C;lqn5)P*%Z0yF5Z1>Y4%~UYNSg(hZlQtWOBr&Kl!(vfq<`_R%D~JW=`WT z=RYn_ElJ+6xb#j>WI2u8wHt2yE;HQV)y23)@q6I^cSf_8`!Cm^Cc1Bfysr?bBs0tml3Z`&1B{#p`!C7psy?~}i>$N50nZY7vTPL!BB^MS1pl8KL@50?m@XuCrY@j_(t%k6^+r#}?~n9EVtSyk2PTM-?7 zt1Bkxr5w))FxFaO41XIo8%f9VF{@Lp))30PIr!S`@BU!NdYW9qjJG9j(X1F4JEFz(MetYs*s77Y#U#d=@tH0Db9mUBZLIV8kTQ6W^6h`|Ba*iZ?W465Q-u1iuB{Ez?nMix5` z`b_+PJ=$c1s)>1{*FMJm_lw{);{Ttosh@CFKc_#PG>vuTM~Wx>_oxgKMwfrSxSRIG z3}O7zLf`yb+LE32((_+(i=lP~2IMcUFrYY6{bwma`oKVOG4#z=ylReT|9Z#=7DFP# zAO7(Fu38Kg0|TrECI4&k%YQutL*k9{^^3p$*F;7};MW3dQpHi|5UNo*M7!@Nn(kZQ zzBC*S3yugMbmHd8-mOsFIoP+{oW_-vHeVJr-d_F>?`wWM2Aj`{eLe>~dW^sp!`UxA`+EPos|CBWId^w0Ltj_pd2GucpXDUm zl`{Fp^xfxNC1(fteD>Q=?5=idM=&mT8}}L>VDh!d8L!@N!zMS>*A>&Mv`yU$ zoF)c2lt`&*yJBFL*fMj;BHcP45uqu^@A8k`_4xrNI#p6Lc+P&{z4!fW_G+(X&*Fn| z=;}>wtca6}=uOoV?l-SU{BJKd+y(cVoYCpph0bQ3?Fzo-J2?-s%WPpjlvZ5;3p)<5 zWT+Yuy=(H`ss24X$T>2LN092g-MH5*Cy*->Yj-#vd9P^lh+I%z+Dmyoa7@!wY;!K- z{ImOkI8qG0Y&NCeYp%v~Zj&Z~BnGt`+1_++*T!#d7K5;q7qEo(TUUMm7S}2#X?uXr z4|eHAFXSF0_tPeg-JH&h?9|NI+2#12I;zSV#|WQlhk3MI4B5|~wcPoln4c%9E6ZK` z-~2Uf#1g$`L$mZ()jXRt#i~8%ev*-x4cGWU2JBH(E4(gBI&eB)A41iY`OQBe+#baG zyU=I3By?=96%>|i@yytA^6pfP6Iht8C2P6qy{%66zF140OVP7Si%NI;Y*SL-&C;~r zZueW?T?wy0=Vse-xA|(<`R-!Gf3}OzaQpT!wdLubMbB|1-ugYiv&Q!v*M){R5q(cj z^HOx5c^ZJ-le}KNH_NY&A&fAMPo-5MKpFds~vm)jG~REl^DUv)~F)jty`O}nEUA2OE(cyE3TOV1zv7|=fXl~G#fqZswIJX3MfvwBqn;|Lx~+Q4Ia zxB`Y_fYIae!zXc|5|nm`Fb9dL&R&{d0VU<#B$)DRp-=2Kvwcsef<2=&(>*t`+y~Qz zWTJ@Tn@xQ;XPrl~Y%S!;o}{SwUyj?QnWxBQl^NjW!n6(FAdl~9+n|dQ!_7%-4ttbj zv?2M!IX+NwHN^EScLVn}B*Le;3Hes@ZZmKDLO+(9_6XRXw&hc*3)$DNrO^4Ywp<^Y z3EV7&Q7GfdN4=|Plcp;|({~w@noCf4{%2U|NbwBl1Ks#F&_b1l$lDL5F^*dLt{Mr? zmrZjM@BJ6-IjR+6)pJ@}5wLUN(7-9noVlHryW8Ee4ov4TQm60?udQ#1j4nlOotLT% zNdv4cO*0l5Zxgci2Uuz|JJ=O0vc0w#Yk@{J{5JF#=5Ows-KoFaDx{a;cw62@@Sa1^ zZnn-W3BQVW(kRFb_eZAlaN72}1;-w;M6Of=FYDSqx{Nw-M8iWI1I*I$D))O)g&JkG zU2?s5+Ha-9JTe)KhTD&#DGUFql?|trf!-~9CSE}iQ+;(ZDL6ODCn#%oQVuKc@%rhE zy$TN@nb+n=Yt>A4^ffnNzH)O$ZL;)!;Umc72j)EDj-*pyq1ezl34}`VTMVo(+*Rgg zhW|X1pu~lc_9dB1$bSo2bIq6xcG<1ppc7meqEHd!O`0yOMU;=ZcO}{?3%{ELQpv+wg4p9^Dh&U%X*sSdQ+c> zBBH}ro|t!SjvO2kFg?^oJ}Of4&rGz9A!VCT$gFP2_yYsK3v&oHVnb*vp1NZEtTK=F zkIyA}FA3XeWMT%*HPrX(_j}dZaMT(s z){W%l*#C-iy;5T6R?meF@u2@&=q4BN<$}>)H_;&Q^SlqJVyLUslt^5J){t5)wJ~s zDV2XsFF{EN7Vyuu20p`?1fF5;we!$g^LZDmW?$$J0w`SCKuq{79RU%UV8ATNMPMLu z;lhW#G`m4qBAcYfFG0|Qzb23Kq2R}aVCMNN^%D&@fhc9~)%*`8==85=I+V-%sSt>R z(E6r;x7o?|Tu_;3K1iKCRD1#K?pqaOSx+P zl09oqC<(Sdr+b;-)pL>Pio=>WJZ&4%RBu- zDEa#R7s;q*9uOO#0AgrS(z2Q0{je(5l`*S$;L6CIfKOg1YEI$7##UEBuc>!m@$R z6$w#V!b;+~Npf zKL`F%Uon45pcSJ1FYB?PzF`3^>*_QxU#-smIG`jCqQJr+&wb4GQ9GjoN&}Y3elv&w z56@o7GXIaMz!1Ue6aqd|0?j!lhxm6M0k`fN$x`z{&pI!8R*pVv!aFqS(?1&Q0uOFv zL2AL^x0_F)x2T%{;lwA1ZkKhaH8THWP^zNvC6^9%mSYp4BKja5@6;|RAAJWfDc?=! zKXdxQS8ka0-js?B8}(d$pSAhiBz@0)!I!ss0IU>lRVR{QL5EzCu+JzTUFY&I)WI zM8s>H(X$1A(IK8v6eTiqfC1q4I1N7_9w}PskX9qAMJ5;=hM^rpO{l(f)ljDfn+_HrZz%<4nNQEe}SvT7SvUxwvFf*bkYCM zE(!^mi0Z99l8JPKijt>0&DDFny7LX`-%1JH0_~)|6tjxHn-*c;MK_5-LV z4NOhUl!5Ai5-zG0Mc}vT*lFECkZb&$^Sj!y`<9pD*na`sJO zaf%S3p^xKP2gNO$_$C~%u{Q0$%K$z-@yt9`pXa66Uel3sEtsj!^_Nc1%^wwiry0A( z;u(jIM}Gqg>VUQwO@cKA$V13@nyBx^{)!h^!UX&9Oz>hgagHjCbeTZg2vXZcpjW5F zGu8RFa)`$+MaRMsOZYhM>ZH_vXFbEdnT`@uaGS06?)Iv2Ek*A+8c5Y<8c%*3E+}yh zaVaew105Ihrv^#{_D*!*bv=kuMh@7U4N!r#B=rVd6``>qwhj!mg1zRe67QoSUNV8W z+6BKEcwYAX_=m#ov`wk&N>8l&(I98+6#%KT<0_&%Y$WKMZrj?tH^<|Rmf41uD*zzd~?~Fzdj)qfvPKUCug`#TZgI0;suK#L)BG;t0e`O3`^0@n2&C+ z_7t91w#Iv7LlW7mEyX=nC#euYtc>_9oS4av!hERs8(;OQT|a&P5T@w0L+x(E-v)Nm z?mF+?`W~fhp{Y5qzr}V9fASUb*J@|%1Z&&TnVveEu&U;K31r69uekEi|Dy(f5^HWBe=_V2F_N1Y${j~Lt5&F zHR5kcnoLfDkY7IA&x-7cg`pEqz##q#uK^n z>DMy=1~H((vAGdx_=6m*A5n{lYLoy}#fG(-8gr+L?Q;gMuoJ%UUh5 z#XulPY+ko%_%r3Rpcn+R!PLr6(b6A6d#Vbeu&t0FhQqq=3(F*6sE|ZfZ-NjCv%71w zOH8UtpdNHR3_JB3*-B){c-ob|*izRCq{=n-2STua8Dl_*y{%l9&J0 zEu1ADo`;zrMvyqXeGyT&-K(^k3B zvp}Ka6w6H`R#RK9%^zFzkh!~vUi7IXFnVEFugKED(=cR|Kx!mB8rXjrA5|4ZX)cnB z*a8bO^|zD6SV$ARAM$HCC45EiZh*)~S;rz6hz^$sDH1SSvtY4W>{b%0D2q!QF?z)h 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