diff --git a/.rspec b/.rspec new file mode 100644 index 00000000..c99d2e73 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..41df210d --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# gem "rails" + +gem "rspec", "~> 3.12" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..2cfabf80 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,26 @@ +GEM + remote: https://rubygems.org/ + specs: + diff-lcs (1.5.0) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) + +PLATFORMS + arm64-darwin-21 + +DEPENDENCIES + rspec (~> 3.12) + +BUNDLED WITH + 2.4.12 diff --git a/app.rb b/app.rb new file mode 100644 index 00000000..7e962826 --- /dev/null +++ b/app.rb @@ -0,0 +1,6 @@ +require_relative './lib/score_total' +require_relative './lib/score_card' +require_relative './lib/score_entry' + +class Application +end \ No newline at end of file diff --git a/coverage/.last_run.json b/coverage/.last_run.json new file mode 100644 index 00000000..52d2bf29 --- /dev/null +++ b/coverage/.last_run.json @@ -0,0 +1,5 @@ +{ + "result": { + "line": 100.0 + } +} diff --git a/coverage/.resultset.json b/coverage/.resultset.json new file mode 100644 index 00000000..666c52e0 --- /dev/null +++ b/coverage/.resultset.json @@ -0,0 +1,338 @@ +{ + "RSpec": { + "coverage": { + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/spec/intergration/app_spec.rb": { + "lines": [ + 1, + null, + 1, + 1, + 1, + 1, + 1, + null, + 1, + 1, + 1, + null, + 1, + 1, + 1, + 1, + null, + 1, + null, + 1, + 1, + null, + 1, + 1, + null, + null, + null, + null, + null, + null, + null + ] + }, + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/app.rb": { + "lines": [ + 1, + 1, + 1, + null, + 1, + null + ] + }, + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/lib/score_total.rb": { + "lines": [ + 1, + null, + 1, + 10, + null, + null, + 1, + 10, + 53, + 32, + 32, + 25, + 6, + null, + 19, + null, + null, + null, + null, + null, + 10, + null, + null, + 1, + 7, + 39, + 5, + 5, + 5, + 4, + 4, + null, + 1, + 1, + null, + null, + null, + null, + null, + 7, + null, + null, + 1, + 2, + null, + null, + 1, + 2, + null, + null + ] + }, + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/lib/score_card.rb": { + "lines": [ + 1, + 1, + 7, + 7, + 7, + null, + null, + 1, + 12, + null, + null, + 1, + 7, + 7, + null, + null, + 1, + 4, + null, + null, + 1, + 11, + 10, + null, + null, + null, + null, + null + ] + }, + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/lib/score_entry.rb": { + "lines": [ + 1, + 1, + 6, + 6, + null, + null, + 1, + 2, + null, + null, + 1, + 4, + null, + null + ] + }, + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/spec/score_card_spec.rb": { + "lines": [ + 1, + null, + 1, + null, + 1, + 1, + 1, + null, + 1, + 1, + null, + null, + null, + 1, + 1, + 1, + null, + 1, + 1, + 1, + 1, + null, + null, + null, + 1, + 1, + 1, + null, + 1, + 1, + 1, + 1, + null, + null, + 1, + 1, + null, + 1, + 1, + 1, + null, + null, + 1, + 1, + null, + 1, + 1, + 1, + 1, + 1, + 1, + null, + null, + null, + 1, + 1, + 1, + null, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + null, + 1, + null, + null, + null + ] + }, + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/spec/score_entry_spec.rb": { + "lines": [ + 1, + null, + 1, + 1, + 1, + 1, + 1, + null, + null, + 1, + 1, + 1, + null, + null, + null, + 1, + 1, + 1, + 1, + null, + null, + 1, + 1, + 1, + null, + null, + null + ] + }, + "/Users/christoplisek/Projects_Makers/bowling-challenge-ruby-CT/spec/score_total_spec.rb": { + "lines": [ + 1, + null, + 1, + 1, + 1, + 1, + null, + 1, + null, + null, + 1, + 1, + null, + 1, + null, + null, + 1, + 1, + null, + 1, + null, + null, + null, + 1, + 1, + 1, + 1, + 1, + null, + null, + 1, + 1, + 1, + 1, + null, + null, + 1, + 1, + 1, + 1, + null, + null, + 1, + 1, + 1, + 1, + null, + null, + null, + 1, + 1, + 1, + 1, + 1, + 1, + null, + null, + null, + 1, + 1, + 1, + 1, + 1, + 1, + null, + null, + null, + null, + null, + null + ] + } + }, + "timestamp": 1682325409 + } +} diff --git a/coverage/.resultset.json.lock b/coverage/.resultset.json.lock new file mode 100644 index 00000000..e69de29b diff --git a/lib/score_card.rb b/lib/score_card.rb new file mode 100644 index 00000000..cd5656e7 --- /dev/null +++ b/lib/score_card.rb @@ -0,0 +1,28 @@ +class ScoreCard + def initialize + @frames = 0 + @score_card = [] + @frame_score = [] + end + + def frame_score_array(score) + @frame_score << score + end + + def score_card + @score_card << @frame_score + @frame_score = [] + end + + def print_total_score + @score_card + end + + def frames_counter + return false if @frames == 10 + @frames += 1 + end +end + + + diff --git a/lib/score_entry.rb b/lib/score_entry.rb new file mode 100644 index 00000000..8dc5a52d --- /dev/null +++ b/lib/score_entry.rb @@ -0,0 +1,14 @@ +class ScoreEntry + def initialize(roll, score) + @roll = roll + @score = score + end + + def roll + return @roll + end + + def score + return @score + end +end diff --git a/lib/score_total.rb b/lib/score_total.rb new file mode 100644 index 00000000..09c35b6e --- /dev/null +++ b/lib/score_total.rb @@ -0,0 +1,50 @@ +class ScoreTotal + + def initialize + @total_score = [] + end + + def strike_score(score_card) + score_card.each.with_index do | frame, index | + if frame.length == 1 + next_score = index + 1 + if next_score < score_card.length + if score_card[next_score].length == 1 + frame[0] = 30 + else + frame[0] = (10 + score_card[next_score].sum) + end + end + end + end + # binding.irb + @total_score = score_card + end + + def spare_score + @total_score.each.with_index do | frame, index | + if frame.length == 2 && frame.sum == 10 + next_score = index + 1 + if next_score < @total_score.length + if @total_score[next_score].length == 1 + frame[0] = 20 + frame.pop + else + frame[0] = (10 + @total_score[next_score][0]) + frame.pop + end + end + end + end + # binding.irb + @total_score = @total_score + end + + def total_score + return @total_score.flatten.sum + end + + def print_score_card + return @total_score + end +end diff --git a/spec/intergration/app_spec.rb b/spec/intergration/app_spec.rb new file mode 100644 index 00000000..722e94ef --- /dev/null +++ b/spec/intergration/app_spec.rb @@ -0,0 +1,31 @@ +require_relative '../../app' + +RSpec.describe Application do + context 'runs application controller' do + it 'returns first roll' do + score_entry = ScoreEntry.new(1, 5) + score_entry1 = ScoreEntry.new(2, 2) + + entry = score_entry.score + entry1 = score_entry1.score + score_card = ScoreCard.new + + score_card.frame_score_array(entry) + score_card.frame_score_array(entry1) + score_card.score_card + result = score_card.print_total_score + + score_total = ScoreTotal.new + + score_total.strike_score(result) + score_total.spare_score + + expect(score_total.total_score).to eq 7 + expect(score_total.print_score_card).to eq [[5, 2]] + end + end +end + + + + diff --git a/spec/score_card_spec.rb b/spec/score_card_spec.rb new file mode 100644 index 00000000..0c8a8c07 --- /dev/null +++ b/spec/score_card_spec.rb @@ -0,0 +1,73 @@ +require 'score_card' + +RSpec.describe ScoreCard do + + context 'creates array for the frame' do + it 'combines roll one & two' do + repo = ScoreCard.new + + repo.frame_score_array(5) + expect(repo.frame_score_array(5)).to eq [5, 5] + end + end + + context 'Clears the frame score array' do + it 'returns empty array of arrays' do + repo = ScoreCard.new + + repo.frame_score_array(0) + repo.frame_score_array(10) + repo.score_card + expect(repo.score_card).to eq [] # EMPTY + end + end + + context 'Keeps games history in array of frame score arrays' do + it 'returns score card array of arrays with spare' do + repo = ScoreCard.new + + repo.frame_score_array(0) + repo.frame_score_array(10) + repo.score_card + expect(repo.print_total_score).to eq [[0, 10]] # SPARE + end + + it 'returns score card array of arrays with strike' do + repo = ScoreCard.new + + repo.frame_score_array(10) + repo.score_card + expect(repo.print_total_score).to eq [[10]] # strike + end + + it 'returns score card array of arrays for 2 frames' do + repo = ScoreCard.new + + repo.frame_score_array(5) + repo.frame_score_array(5) + repo.score_card + repo.frame_score_array(10) + repo.score_card + expect(repo.print_total_score).to eq [[5, 5], [10]] # Frame 1 & Frame 2 + end + end + + context 'Keeps a check of the current frame' do + it 'returns frame true' do + repo = ScoreCard.new + + repo.frames_counter + repo.frames_counter + repo.frames_counter + repo.frames_counter + repo.frames_counter + repo.frames_counter + repo.frames_counter + repo.frames_counter + repo.frames_counter + repo.frames_counter + + expect(repo.frames_counter).to eq false + end + end +end diff --git a/spec/score_entry_spec.rb b/spec/score_entry_spec.rb new file mode 100644 index 00000000..1ff47a5d --- /dev/null +++ b/spec/score_entry_spec.rb @@ -0,0 +1,27 @@ +require 'score_entry' + +RSpec.describe ScoreEntry do + context 'test the entry scoring system' do + it 'returns stike if roll one eq 10' do + repo = ScoreEntry.new(1, 10) + expect(repo.roll).to eq 1 + end + + it 'returns roll one score' do + repo = ScoreEntry.new(1, 5) + expect(repo.score).to eq 5 + end + end + + context 'test the entry scoring system' do + it 'returns spare if roll two eq 10' do + repo = ScoreEntry.new(2, 10) + expect(repo.roll).to eq 2 + end + + it 'returns roll two score' do + repo = ScoreEntry.new(2, 5) + expect(repo.score).to eq 5 + end + end +end \ No newline at end of file diff --git a/spec/score_total_spec.rb b/spec/score_total_spec.rb new file mode 100644 index 00000000..29c38a8b --- /dev/null +++ b/spec/score_total_spec.rb @@ -0,0 +1,70 @@ +require 'score_total' + +RSpec.describe ScoreTotal do + context 'calculates the score after a stike' do + it 'returns strike frame after next frame' do + repo = ScoreTotal.new + + expect(repo.strike_score([[10],[5, 2]])).to eq [[17], [5, 2]] + end + + it 'returns 30 after after next frame strike' do + repo = ScoreTotal.new + + expect(repo.strike_score([[10],[5, 2],[10],[10]])).to eq [[17], [5, 2], [30], [10]] + end + + it 'returns 30 after after next frame strike' do + repo = ScoreTotal.new + + expect(repo.strike_score([[10],[5, 2],[10],[10],[0,0],[10],[9, 1],[10]])).to eq [[17], [5, 2], [30], [10], [0, 0], [20], [9, 1], [10]] + end + end + + context 'calculates the score after a spare' do + it 'returns spare frame after next frame' do + repo = ScoreTotal.new + repo.strike_score([[10],[5, 2]]) + expect(repo.spare_score).to eq [[17], [5, 2]] + end + + it 'returns 20 after after next frame spare' do + repo = ScoreTotal.new + repo.strike_score([[10],[5, 2],[10],[10]]) + expect(repo.spare_score).to eq [[17], [5, 2], [30], [10]] + end + + it 'returns 30 after after next frame spare' do + repo = ScoreTotal.new + repo.strike_score([[10],[5, 2],[10],[10],[0,0],[10],[9, 1],[10]]) + expect(repo.spare_score).to eq [[17], [5, 2], [30], [10], [0, 0], [20], [20], [10]] + end + + it 'returns 30 after after next frame spare' do + repo = ScoreTotal.new + repo.strike_score([[10],[5, 5],[5, 0],[10],[0,0],[10],[9, 1],[10]]) + expect(repo.spare_score).to eq [[20], [15], [5, 0], [10], [0, 0], [20], [20], [10]] + end + end + + context 'calculates the total score' do + it 'returns total' do + repo = ScoreTotal.new + repo.strike_score([[10],[5, 2],[10],[10],[0,0],[10],[9, 1],[10]]) + repo.spare_score + expect(repo.total_score).to eq 114 + end + end + + context 'prints score card' do + it 'returns score card' do + repo = ScoreTotal.new + repo.strike_score([[10],[5, 2],[10],[10],[0,0],[10],[9, 1],[10]]) + repo.spare_score + expect(repo.print_score_card).to eq [[17], [5, 2], [30], [10], [0, 0], [20], [20], [10]] + end + end +end + + + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..6d767f83 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,110 @@ +ENV['ENV'] = 'test' + +require 'simplecov' +require 'simplecov-console' + +SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ + SimpleCov::Formatter::Console, + # Want a nice code coverage website? Uncomment this next line! + # SimpleCov::Formatter::HTMLFormatter +]) +SimpleCov.start + +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # https://relishapp.com/rspec/rspec-core/docs/configuration/zero-monkey-patching-mode + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end