master
  1require "rails_helper"
  2
  3describe Program do
  4  it "saves a slug" do
  5    program = create(:program, name: "Strong Lifts 5x5")
  6    expect(program.slug).to eql("strong-lifts-5x5")
  7  end
  8
  9  describe ".stronglifts" do
 10    include_context "stronglifts_program"
 11
 12    it "returns the stronglifts program" do
 13      expect(Program.stronglifts).to eql(program)
 14    end
 15  end
 16
 17  describe "#prepare_sets_for" do
 18    include_context "stronglifts_program"
 19    subject { Program.stronglifts }
 20
 21    describe "squat" do
 22      let(:user) { build(:user) }
 23
 24      it "returns 5 work sets of 5 repetitions" do
 25        sets = subject.prepare_sets_for(user, squat)
 26        worksets = sets.select(&:work?)
 27        expect(worksets.length).to eql(5)
 28        expect(worksets.map(&:target_repetitions)).to match_array([5, 5, 5, 5, 5])
 29      end
 30
 31      it "returns 3 sets of 5 repetitions when the last workout was 3x5" do
 32        workout = create(:workout, user: user, routine: routine_a)
 33        3.times { workout.train(squat, 45, repetitions: 5) }
 34
 35        sets = subject.prepare_sets_for(user, squat)
 36        worksets = sets.select(&:work?)
 37        expect(worksets.length).to eql(3)
 38        expect(worksets.map(&:target_repetitions)).to match_array([5, 5, 5])
 39      end
 40
 41      it "returns the correct exercise for each set" do
 42        sets = subject.prepare_sets_for(user, squat)
 43        expect(sets.map(&:exercise).uniq).to match_array([squat])
 44      end
 45
 46      it "returns 45 lbs for the first workout" do
 47        sets = subject.prepare_sets_for(user, squat).select(&:work?)
 48        expect(sets.map(&:target_weight).uniq).to match_array([45.lbs])
 49      end
 50
 51      it "returns 50 lbs for the second workout" do
 52        workout = create(:workout, user: user, routine: routine_a)
 53        5.times { workout.train(squat, 45, repetitions: 5) }
 54
 55        sets = subject.prepare_sets_for(user, squat).select(&:work?)
 56        expect(sets.map(&:target_weight).uniq).to match_array([50.lbs])
 57      end
 58
 59      it "returns the same weight after a failed workout" do
 60        workout = create(:workout, user: user, routine: routine_a)
 61        5.times { |n| workout.train(squat, 45, repetitions: n) }
 62
 63        sets = subject.prepare_sets_for(user, squat).select(&:work?)
 64        expect(sets.map(&:target_weight).uniq).to match_array([45.lbs])
 65      end
 66
 67      it "deloads you by 10% after 3 consecutive failed workouts" do
 68        3.times do
 69          workout = create(:workout, user: user, routine: routine_a)
 70          5.times { |n| workout.train(squat, 310, repetitions: n) }
 71        end
 72
 73        sets = subject.prepare_sets_for(user, squat).select(&:work?)
 74        expect(sets.map(&:target_weight).uniq).to match_array([275.lbs])
 75      end
 76
 77      describe "warmup" do
 78        describe "when the workset is less than 65 lbs" do
 79          it "returns zero warmup sets" do
 80            sets = subject.prepare_sets_for(user, squat)
 81            warmup_sets = sets.select(&:warm_up?)
 82            expect(warmup_sets.length).to eql(0)
 83          end
 84        end
 85
 86        describe "when the work set is between 65 lbs an 95 lbs" do
 87          it "returns two warmup sets" do
 88            workout = create(:workout, user: user, routine: routine_a)
 89            5.times { workout.train(squat, 65, repetitions: 5) }
 90
 91            sets = subject.prepare_sets_for(user, squat)
 92            warmup_sets = sets.select(&:warm_up?)
 93            expect(warmup_sets.length).to eql(2)
 94            expect(warmup_sets.at(0).target_weight.to(:lbs)).to eql(45.lbs)
 95            expect(warmup_sets.at(0).target_repetitions).to eql(5)
 96            expect(warmup_sets.at(1).target_weight.to(:lbs)).to eql(45.lbs)
 97            expect(warmup_sets.at(1).target_repetitions).to eql(5)
 98          end
 99        end
100
101        describe "when the work set is between 95 lbs and 105 lbs" do
102          it "returns another warm up set" do
103            workout = create(:workout, user: user, routine: routine_a)
104            5.times { workout.train(squat, 95, repetitions: 5) }
105
106            sets = subject.prepare_sets_for(user, squat)
107            warmup_sets = sets.select(&:warm_up?)
108            expect(warmup_sets.length).to eql(3)
109            expect(warmup_sets.at(2).target_weight.to(:lbs)).to eql(65.lbs)
110            expect(warmup_sets.at(2).target_repetitions).to eql(3)
111          end
112        end
113
114        describe "when the work set is between 105 lbs and 125 lbs" do
115          it "returns another warm up set" do
116            workout = create(:workout, user: user, routine: routine_a)
117            5.times { workout.train(squat, 105, repetitions: 5) }
118
119            warmup_sets = subject.prepare_sets_for(user, squat).select(&:warm_up?)
120            expect(warmup_sets.length).to eql(3)
121            expect(warmup_sets.last.target_weight.to(:lbs)).to eql(75.lbs)
122            expect(warmup_sets.last.target_repetitions).to eql(3)
123          end
124        end
125
126        describe "when the work set is between 125 lbs and 135 lbs" do
127          it "returns another warm up set" do
128            workout = create(:workout, user: user, routine: routine_a)
129            5.times { workout.train(squat, 125, repetitions: 5) }
130
131            warmup_sets = subject.prepare_sets_for(user, squat).select(&:warm_up?)
132            expect(warmup_sets.length).to eql(3)
133            expect(warmup_sets.last.target_weight.to(:lbs)).to eql(85.lbs)
134            expect(warmup_sets.last.target_repetitions).to eql(3)
135          end
136        end
137
138        describe "when the work set is between 135 lbs and 150 lbs" do
139          it "returns another warm up set" do
140            workout = create(:workout, user: user, routine: routine_a)
141            5.times { workout.train(squat, 135, repetitions: 5) }
142
143            warmup_sets = subject.prepare_sets_for(user, squat).select(&:warm_up?)
144            expect(warmup_sets.length).to eql(4)
145            expect(warmup_sets.last.target_weight.to(:lbs)).to eql(115.lbs)
146            expect(warmup_sets.last.target_repetitions).to eql(3)
147          end
148        end
149      end
150    end
151
152    describe "deadlift" do
153      let(:user) { build(:user) }
154
155      it "returns 1 work set with 5 repetitions" do
156        sets = subject.prepare_sets_for(user, deadlift)
157        worksets = sets.select(&:work?)
158        expect(worksets.length).to eql(1)
159        expect(worksets.map(&:target_repetitions)).to match_array([5])
160      end
161    end
162
163    describe "planks" do
164      let(:user) { build(:user) }
165
166      it "returns 3 set with 1 rep at 60 seconds" do
167        sets = subject.prepare_sets_for(user, planks)
168        worksets = sets.select(&:work?)
169        expect(worksets.length).to eql(3)
170        expect(worksets.map(&:target_repetitions)).to match_array([1,1,1])
171        expect(worksets.map(&:target_weight).uniq).to match_array([0.lbs])
172        expect(worksets.map(&:target_duration).uniq).to match_array([60])
173      end
174    end
175  end
176end