post-push-party 0.1.7

Push code, earn points, throw a party!
Documentation
use super::{BonusTrack, PushContext, Reward, Tier};

/// bonus for pushing a lot of commits at once
pub struct BigPush;

/// how many commits is considered "big"
const BIG_PUSH_COMMIT_COUNT: usize = 10;

static TIERS: &[Tier] = &[
    Tier {
        cost: 50,
        reward: Reward::Multiplier(2),
    },
    Tier {
        cost: 500,
        reward: Reward::Multiplier(3),
    },
    Tier {
        cost: 3000,
        reward: Reward::Multiplier(4),
    },
    Tier {
        cost: 20000,
        reward: Reward::Multiplier(5),
    },
    Tier {
        cost: 120000,
        reward: Reward::Multiplier(6),
    },
];

impl BonusTrack for BigPush {
    fn id(&self) -> &'static str {
        "big_push"
    }

    fn name(&self) -> &'static str {
        "Big Push"
    }

    fn description(&self) -> &'static str {
        // NOTE: gotta keep this in sync with BIG_PUSH_COMMIT_COUNT above
        "Multiplier for pushing 10+ commits at once."
    }

    fn tiers(&self) -> &'static [Tier] {
        TIERS
    }

    fn applies(&self, ctx: &PushContext) -> u32 {
        if ctx.push.commits().len() >= BIG_PUSH_COMMIT_COUNT {
            1
        } else {
            0
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::{
        bonus_track::Clock,
        git::{Commit, Push},
        storage::{DbConnection, PushHistory},
    };

    #[test]
    fn applies_to_big_pushes() {
        let conn = DbConnection::create_in_memory().unwrap();

        let bonus = BigPush;
        let history = PushHistory::new(&conn);
        let clock = Clock::default();

        let push = Push::new(vec![Commit::default(); BIG_PUSH_COMMIT_COUNT]);
        let ctx = PushContext {
            push: &push,
            history: &history,
            clock: &clock,
        };
        assert_eq!(bonus.applies(&ctx), 1);

        let push = Push::new(vec![Commit::default(); 1_000]);
        let ctx = PushContext {
            push: &push,
            history: &history,
            clock: &clock,
        };
        assert_eq!(bonus.applies(&ctx), 1);
    }

    #[test]
    fn does_not_apply_to_small_pushes() {
        let conn = DbConnection::create_in_memory().unwrap();

        let bonus = BigPush;
        let history = PushHistory::new(&conn);
        let clock = Clock::default();

        let push = Push::new(vec![Commit::default(); BIG_PUSH_COMMIT_COUNT - 1]);
        let ctx = PushContext {
            push: &push,
            history: &history,
            clock: &clock,
        };
        assert_eq!(bonus.applies(&ctx), 0);

        let push = Push::new(vec![Commit::default(); 1]);
        let ctx = PushContext {
            push: &push,
            history: &history,
            clock: &clock,
        };
        assert_eq!(bonus.applies(&ctx), 0);
    }
}