master
  1require "rails_helper"
  2
  3describe Workout, type: :model do
  4  subject { create(:workout) }
  5
  6  describe "#train" do
  7    let(:routine) { subject.routine }
  8    let(:target_weight) { 200 }
  9    let(:squat) { create(:exercise) }
 10
 11    before :each do
 12      routine.add_exercise(squat)
 13    end
 14
 15    it "returns a completed exercise" do
 16      result = subject.train(squat, target_weight, repetitions: 5)
 17
 18      expect(result).to be_persisted
 19      expect(result.exercise).to eql(squat)
 20      expect(subject.progress_for(squat).to_sets).to eql([5])
 21      sets = subject.sets.to_a
 22      expect(sets.at(0).exercise).to eql(squat)
 23      expect(sets.at(0).target_weight).to eql(target_weight.to_f)
 24      expect(sets.at(0).target_repetitions).to eql(5)
 25      expect(sets.at(0).actual_repetitions).to eql(5)
 26    end
 27
 28    it "records the next set" do
 29      subject.train(squat, target_weight, repetitions: 5)
 30      result = subject.train(squat, target_weight, repetitions: 3)
 31
 32      expect(result).to be_persisted
 33      expect(result.exercise).to eql(squat)
 34      expect(subject.progress_for(squat).to_sets).to eql([5, 3])
 35      sets = subject.sets.in_order.to_a
 36      set = sets.at(0)
 37      expect(set.exercise).to eql(squat)
 38      expect(set.target_weight).to eql(target_weight.to_f)
 39      expect(set.target_repetitions).to eql(5)
 40      expect(set.actual_repetitions).to eql(5)
 41      set = sets.at(1)
 42      expect(set.exercise).to eql(squat)
 43      expect(set.target_weight).to eql(target_weight.to_f)
 44      expect(set.target_repetitions).to eql(5)
 45      expect(set.actual_repetitions).to eql(3)
 46    end
 47
 48    it "updates a completed exercise" do
 49      subject.train(squat, target_weight, repetitions: 5)
 50      subject.train(squat, target_weight, repetitions: 5)
 51      subject.train(squat, target_weight, repetitions: 5)
 52
 53      new_weight = target_weight + 10
 54      result = subject.train(squat, new_weight, repetitions: 3, set: 1)
 55
 56      expect(result).to be_persisted
 57      expect(result.exercise).to eql(squat)
 58      progress = subject.progress_for(squat)
 59      expect(progress.to_sets).to eql([5, 3, 5])
 60      sets = progress.sets.to_a
 61      expect(sets.at(0).exercise).to eql(squat)
 62      expect(sets.at(0).target_weight).to eql(target_weight.to_f)
 63      expect(sets.at(0).target_repetitions).to eql(5)
 64      expect(sets.at(0).actual_repetitions).to eql(5)
 65      expect(sets.at(1).exercise).to eql(squat)
 66      expect(sets.at(1).target_weight).to eql(new_weight.to_f)
 67      expect(sets.at(1).target_repetitions).to eql(5)
 68      expect(sets.at(1).actual_repetitions).to eql(3)
 69      expect(sets.at(2).exercise).to eql(squat)
 70      expect(sets.at(2).target_weight).to eql(target_weight.to_f)
 71      expect(sets.at(2).target_repetitions).to eql(5)
 72      expect(sets.at(2).actual_repetitions).to eql(5)
 73    end
 74
 75    it "cannot save a duplicate exercise" do
 76      subject.train(squat, target_weight, repetitions: 5, set: 0)
 77      subject.train(squat, target_weight, repetitions: 5, set: 0)
 78
 79      expect(subject.sets.count).to eql(1)
 80    end
 81  end
 82
 83  describe "#progress_for" do
 84    let(:exercise) { create(:exercise) }
 85    let(:other_exercise) { create(:exercise) }
 86    let(:routine) { subject.routine }
 87
 88    before :each do
 89      routine.add_exercise(exercise)
 90      routine.add_exercise(other_exercise)
 91      subject.train(exercise, 100, repetitions: 5)
 92      subject.train(other_exercise, 100, repetitions: 5)
 93      subject.train(exercise, 100, repetitions: 5)
 94    end
 95
 96    it "returns the progress for the specific exercise" do
 97      result = subject.progress_for(exercise)
 98      expect(result.exercise).to eql(exercise)
 99      expect(result.to_sets).to eql([5, 5])
100    end
101  end
102
103  describe ".since" do
104    subject { described_class }
105
106    it 'returns workouts that occurred after the date given' do
107      monday = create(:workout, occurred_at: 3.days.ago)
108      wednesday = create(:workout, occurred_at: 1.day.ago)
109
110      expect(subject.since(2.days.ago)).to match_array([wednesday])
111    end
112  end
113
114  describe ".to_line_chart" do
115    let(:routine) { subject.routine }
116    let(:squat) { create(:exercise) }
117
118    before :each do
119      routine.add_exercise(squat)
120    end
121
122    it 'returns a single series' do
123      subject.train(squat, 315, repetitions: 5)
124      subject.reload
125
126      expect(described_class.to_line_chart).to eql({
127        subject.occurred_at => 315.0
128      })
129    end
130  end
131end