diff --git a/.path_progress b/.path_progress new file mode 100644 index 0000000..ddff9b9 --- /dev/null +++ b/.path_progress @@ -0,0 +1 @@ +0,0,0,1,2,3,4,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,9,10,11,11,11,13,14,15,15,16,17,18,18,19,19,19,20,20,21,21,21,22,22,23,24,25,26,27,27,27,28,29,30,30,31,31,31,32,33,34,34,35,35,35,35,35,36,36,37,37,38,39,39,40,40,40,40,41,41,42,43,47,48,49,49,49,49,49,50,50,50,51,52,56,56,56,57,58,58,59,59,60,61,62,63,63,64,65,66,67,68,70,72,73,74,74,74,75,75,76,76,76,77,78,79,79,80,81,82,82,83,83,84,85,86,86,88,88,88,89,89,90,91,93,93,94,95,96,97,97,98,98,98,98,100,100,102,103,104,105,106,106,107,107,108,109,110,111,111,111,111,111,111,111,111,111,113,113,113,113,114,115,116,117,118,119,120,121,122,124,124,124,124,124,124,125,125,126,129,130,131,132,132,133,133,134,135,136,137,139,140,142,143,143,144,145,145,146,148,151,152,153,153,153,153,153,153,153,153,153,155,155,155,155,156,156,156,156,157,158,159,159,160,160,160,160,160,160,152,152,161,162,163,165,166,167,168,168,169,169,169,169,169,175,178,178,179,180,180,180,181,182,182,183,184,184,192,193,193,194,194,195,196,196,196,197,201,202,203,203,203,203,203,203,203,204,205,206,207,207,207,207,207,208,210,211,212,212,212,212,212,212,216,220,222,222,223,224,226,228,228,229,229,230,231,233,234,235,235,236,236,237,237,236,237,237,237,237,237,237,240,241,241,242,243,244,246,246,247,248,250,251,252,255,256,257,258,259,261,262,263,264,265,267,267,267,267,267,267,267,267,267,267,267,267,268,267,267,268,268,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,267,277,278,279,279,280,281,281,173,140,17,267,267,267,133,25,24,26,24,28,225,132,193,197,184,184,184,189,121,159,159,159,6,6,246,248,248,152,135 \ No newline at end of file diff --git a/Rakefile b/Rakefile index 1a2c7f2..b090dc0 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,4 @@ +# rubocop:disable all #!/usr/bin/env ruby # -*- ruby -*- diff --git a/about_array_assignment.rb b/about_array_assignment.rb index 87186ff..1fe345b 100644 --- a/about_array_assignment.rb +++ b/about_array_assignment.rb @@ -1,51 +1,54 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about array class AboutArrayAssignment < Neo::Koan def test_non_parallel_assignment - names = ["John", "Smith"] - assert_equal __, names + names = %w[John Smith] + assert_equal %w[John Smith], names end def test_parallel_assignments - first_name, last_name = ["John", "Smith"] - assert_equal __, first_name - assert_equal __, last_name + first_name = 'John' + last_name = 'Smith' + assert_equal 'John', first_name + assert_equal 'Smith', last_name end def test_parallel_assignments_with_extra_values - first_name, last_name = ["John", "Smith", "III"] - assert_equal __, first_name - assert_equal __, last_name + first_name, last_name = %w[John Smith III] + assert_equal 'John', first_name + assert_equal 'Smith', last_name end def test_parallel_assignments_with_splat_operator - first_name, *last_name = ["John", "Smith", "III"] - assert_equal __, first_name - assert_equal __, last_name + first_name, *last_name = %w[John Smith III] + assert_equal 'John', first_name + assert_equal %w[Smith III], last_name end def test_parallel_assignments_with_too_few_variables - first_name, last_name = ["Cher"] - assert_equal __, first_name - assert_equal __, last_name + first_name, last_name = %w[Cher] + assert_equal 'Cher', first_name + assert_equal nil, last_name end def test_parallel_assignments_with_subarrays - first_name, last_name = [["Willie", "Rae"], "Johnson"] - assert_equal __, first_name - assert_equal __, last_name + first_name = %w[Willie Rae] + last_name = 'Johnson' + assert_equal %w[Willie Rae], first_name + assert_equal 'Johnson', last_name end def test_parallel_assignment_with_one_variable - first_name, = ["John", "Smith"] - assert_equal __, first_name + first_name, = %w[John Smith] + assert_equal 'John', first_name end def test_swapping_with_parallel_assignment - first_name = "Roy" - last_name = "Rob" + first_name = 'Roy' + last_name = 'Rob' first_name, last_name = last_name, first_name - assert_equal __, first_name - assert_equal __, last_name + assert_equal 'Rob', first_name + assert_equal 'Roy', last_name end end diff --git a/about_arrays.rb b/about_arrays.rb index ce9b46e..4df5d24 100644 --- a/about_arrays.rb +++ b/about_arrays.rb @@ -1,84 +1,84 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about array class AboutArrays < Neo::Koan def test_creating_arrays - empty_array = Array.new - assert_equal __, empty_array.class - assert_equal __, empty_array.size + empty_array = [] + assert_equal Array, empty_array.class + assert_equal 0, empty_array.size end def test_array_literals - array = Array.new + array = [] assert_equal [], array array[0] = 1 assert_equal [1], array array[1] = 2 - assert_equal [1, __], array + assert_equal [1, 2], array array << 333 - assert_equal __, array + assert_equal [1, 2, 333], array end def test_accessing_array_elements - array = [:peanut, :butter, :and, :jelly] - - assert_equal __, array[0] - assert_equal __, array.first - assert_equal __, array[3] - assert_equal __, array.last - assert_equal __, array[-1] - assert_equal __, array[-3] + array = %i[peanut butter and jelly] + + assert_equal :peanut, array[0] + assert_equal :peanut, array.first + assert_equal :jelly, array[3] + assert_equal :jelly, array.last + assert_equal :jelly, array[-1] + assert_equal :butter, array[-3] end def test_slicing_arrays - array = [:peanut, :butter, :and, :jelly] - - assert_equal __, array[0,1] - assert_equal __, array[0,2] - assert_equal __, array[2,2] - assert_equal __, array[2,20] - assert_equal __, array[4,0] - assert_equal __, array[4,100] - assert_equal __, array[5,0] + array = %i[peanut butter and jelly] + + assert_equal [:peanut], array[0, 1] + assert_equal %i[peanut butter], array[0, 2] + assert_equal %i[and jelly], array[2, 2] + assert_equal %i[and jelly], array[2, 20] + assert_equal [], array[4, 0] + assert_equal [], array[4, 100] + assert_equal nil, array[5, 0] end def test_arrays_and_ranges - assert_equal __, (1..5).class - assert_not_equal [1,2,3,4,5], (1..5) - assert_equal __, (1..5).to_a - assert_equal __, (1...5).to_a + assert_equal Range, (1..5).class + assert_not_equal [1, 2, 3, 4, 5], (1..5) + assert_equal [1, 2, 3, 4, 5], (1..5).to_a + assert_equal [1, 2, 3, 4], (1...5).to_a end def test_slicing_with_ranges - array = [:peanut, :butter, :and, :jelly] + array = %i[peanut butter and jelly] - assert_equal __, array[0..2] - assert_equal __, array[0...2] - assert_equal __, array[2..-1] + assert_equal %i[peanut butter and], array[0..2] + assert_equal %i[peanut butter], array[0...2] + assert_equal %i[and jelly], array[2..-1] end def test_pushing_and_popping_arrays - array = [1,2] + array = [1, 2] array.push(:last) - assert_equal __, array + assert_equal [1, 2, :last], array popped_value = array.pop - assert_equal __, popped_value - assert_equal __, array + assert_equal :last, popped_value + assert_equal [1, 2], array end def test_shifting_arrays - array = [1,2] + array = [1, 2] array.unshift(:first) - assert_equal __, array + assert_equal [:first, 1, 2], array shifted_value = array.shift - assert_equal __, shifted_value - assert_equal __, array + assert_equal :first, shifted_value + assert_equal [1, 2], array end - end diff --git a/about_asserts.rb b/about_asserts.rb index 5defa59..04ba410 100644 --- a/about_asserts.rb +++ b/about_asserts.rb @@ -1,25 +1,23 @@ -#!/usr/bin/env ruby -# -*- ruby -*- - +# rubocop:disable Lint/UnneededCopDisableDirective, Lint/ScriptPermission require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about asserts class AboutAsserts < Neo::Koan - # We shall contemplate truth by testing reality, via asserts. def test_assert_truth - assert false # This should be true + assert true # This should be true end # Enlightenment may be more easily achieved with appropriate # messages. def test_assert_with_message - assert false, "This should be true -- Please fix this" + assert true, 'This should be true -- Please fix this' end # To understand reality, we must compare our expectations against # reality. def test_assert_equality - expected_value = __ + expected_value = 2 actual_value = 1 + 1 assert expected_value == actual_value @@ -27,7 +25,7 @@ def test_assert_equality # Some ways of asserting equality are better than others. def test_a_better_way_of_asserting_equality - expected_value = __ + expected_value = 2 actual_value = 1 + 1 assert_equal expected_value, actual_value @@ -35,6 +33,7 @@ def test_a_better_way_of_asserting_equality # Sometimes we will ask you to fill in the values def test_fill_in_values - assert_equal __, 1 + 1 + assert_equal 2, 1 + 1 end end +# rubocop:enable Lint/UnneededCopDisableDirective, Lint/ScriptPermission diff --git a/about_blocks.rb b/about_blocks.rb index c02dab9..90f88a9 100644 --- a/about_blocks.rb +++ b/about_blocks.rb @@ -1,5 +1,6 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about block class AboutBlocks < Neo::Koan def method_with_block result = yield @@ -8,23 +9,23 @@ def method_with_block def test_methods_can_take_blocks yielded_result = method_with_block { 1 + 2 } - assert_equal __, yielded_result + assert_equal 3, yielded_result end def test_blocks_can_be_defined_with_do_end_too - yielded_result = method_with_block do 1 + 2 end - assert_equal __, yielded_result + yielded_result = method_with_block { 1 + 2 } + assert_equal 3, yielded_result end # ------------------------------------------------------------------ def method_with_block_arguments - yield("Jim") + yield('Jim') end def test_blocks_can_take_arguments method_with_block_arguments do |argument| - assert_equal __, argument + assert_equal 'Jim', argument end end @@ -40,7 +41,7 @@ def many_yields def test_methods_can_call_yield_many_times result = [] many_yields { |item| result << item } - assert_equal __, result + assert_equal %i[peanut butter and jelly], result end # ------------------------------------------------------------------ @@ -54,8 +55,8 @@ def yield_tester end def test_methods_can_see_if_they_have_been_called_with_a_block - assert_equal __, yield_tester { :with_block } - assert_equal __, yield_tester + assert_equal :with_block, (yield_tester { :with_block }) + assert_equal :no_block, yield_tester end # ------------------------------------------------------------------ @@ -63,34 +64,33 @@ def test_methods_can_see_if_they_have_been_called_with_a_block def test_block_can_affect_variables_in_the_code_where_they_are_created value = :initial_value method_with_block { value = :modified_in_a_block } - assert_equal __, value + assert_equal :modified_in_a_block, value end def test_blocks_can_be_assigned_to_variables_and_called_explicitly - add_one = lambda { |n| n + 1 } - assert_equal __, add_one.call(10) + add_one = ->(elem) { elem + 1 } + assert_equal 11, add_one.call(10) # Alternative calling syntax - assert_equal __, add_one[10] + assert_equal 11, add_one[10] end def test_stand_alone_blocks_can_be_passed_to_methods_expecting_blocks - make_upper = lambda { |n| n.upcase } + make_upper = ->(elem) { elem.upcase } result = method_with_block_arguments(&make_upper) - assert_equal __, result + assert_equal 'JIM', result end # ------------------------------------------------------------------ - def method_with_explicit_block(&block) - block.call(10) + def method_with_explicit_block + yield(10) end def test_methods_can_take_an_explicit_block_argument - assert_equal __, method_with_explicit_block { |n| n * 2 } + assert_equal 20, (method_with_explicit_block { |elem| elem * 2 }) - add_one = lambda { |n| n + 1 } - assert_equal __, method_with_explicit_block(&add_one) + add_one = ->(elem) { elem + 1 } + assert_equal 11, method_with_explicit_block(&add_one) end - end diff --git a/about_class_methods.rb b/about_class_methods.rb index 46aab74..dbefdbd 100644 --- a/about_class_methods.rb +++ b/about_class_methods.rb @@ -1,29 +1,31 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about ClassMethods class AboutClassMethods < Neo::Koan + # Class about dog class Dog end def test_objects_are_objects fido = Dog.new - assert_equal __, fido.is_a?(Object) + assert_equal true, fido.is_a?(Object) end def test_classes_are_classes - assert_equal __, Dog.is_a?(Class) + assert_equal true, Dog.is_a?(Class) end def test_classes_are_objects_too - assert_equal __, Dog.is_a?(Object) + assert_equal true, Dog.is_a?(Object) end def test_objects_have_methods fido = Dog.new - assert fido.methods.size > _n_ + assert fido.methods.size > 1 end def test_classes_have_methods - assert Dog.methods.size > _n_ + assert Dog.methods.size > 1 end def test_you_can_define_methods_on_individual_objects @@ -31,7 +33,7 @@ def test_you_can_define_methods_on_individual_objects def fido.wag :fidos_wag end - assert_equal __, fido.wag + assert_equal :fidos_wag, fido.wag end def test_other_objects_are_not_affected_by_these_singleton_methods @@ -41,13 +43,14 @@ def fido.wag :fidos_wag end - assert_raise(___) do + assert_raise(NoMethodError) do rover.wag end end # ------------------------------------------------------------------ + # Class about dog2 class Dog2 def wag :instance_level_wag @@ -59,66 +62,69 @@ def Dog2.wag end def test_since_classes_are_objects_you_can_define_singleton_methods_on_them_too - assert_equal __, Dog2.wag + assert_equal :class_level_wag, Dog2.wag end def test_class_methods_are_independent_of_instance_methods fido = Dog2.new - assert_equal __, fido.wag - assert_equal __, Dog2.wag + assert_equal :instance_level_wag, fido.wag + assert_equal :class_level_wag, Dog2.wag end # ------------------------------------------------------------------ + # Class about dog class Dog attr_accessor :name end - def Dog.name + def Dog.name # rubocop:disable Style/TrivialAccessors @name end def test_classes_and_instances_do_not_share_instance_variables fido = Dog.new - fido.name = "Fido" - assert_equal __, fido.name - assert_equal __, Dog.name + fido.name = 'Fido' + assert_equal 'Fido', fido.name + assert_equal nil, Dog.name end # ------------------------------------------------------------------ + # Class about dog class Dog - def Dog.a_class_method + def self.a_class_method :dogs_class_method end end def test_you_can_define_class_methods_inside_the_class - assert_equal __, Dog.a_class_method + assert_equal :dogs_class_method, Dog.a_class_method end # ------------------------------------------------------------------ - LastExpressionInClassStatement = class Dog - 21 - end + LAST_EXPRESSION_IN_CLASS_STATEMENT = class Dog + 21 + end def test_class_statements_return_the_value_of_their_last_expression - assert_equal __, LastExpressionInClassStatement + assert_equal 21, LAST_EXPRESSION_IN_CLASS_STATEMENT end # ------------------------------------------------------------------ - SelfInsideOfClassStatement = class Dog - self - end + SELF_INSIDE_OF_CLASS_STATEMENT = class Dog + self + end def test_self_while_inside_class_is_class_object_not_instance - assert_equal __, Dog == SelfInsideOfClassStatement + assert_equal true, Dog == SELF_INSIDE_OF_CLASS_STATEMENT end # ------------------------------------------------------------------ + # Class about dog class Dog def self.class_method2 :another_way_to_write_class_methods @@ -126,11 +132,12 @@ def self.class_method2 end def test_you_can_use_self_instead_of_an_explicit_reference_to_dog - assert_equal __, Dog.class_method2 + assert_equal :another_way_to_write_class_methods, Dog.class_method2 end # ------------------------------------------------------------------ + # Class about dog class Dog class << self def another_class_method @@ -140,7 +147,7 @@ def another_class_method end def test_heres_still_another_way_to_write_class_methods - assert_equal __, Dog.another_class_method + assert_equal :still_another_way, Dog.another_class_method end # THINK ABOUT IT: @@ -163,7 +170,6 @@ def test_heres_still_another_way_to_write_class_methods def test_heres_an_easy_way_to_call_class_methods_from_instance_methods fido = Dog.new - assert_equal __, fido.class.another_class_method + assert_equal :still_another_way, fido.class.another_class_method end - end diff --git a/about_classes.rb b/about_classes.rb index 1d146be..7352feb 100644 --- a/about_classes.rb +++ b/about_classes.rb @@ -1,111 +1,119 @@ +# rubocop:disable Style/EvalWithLocation + require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about classes class AboutClasses < Neo::Koan + # Class about dog class Dog end def test_instances_of_classes_can_be_created_with_new fido = Dog.new - assert_equal __, fido.class + assert_equal Dog, fido.class end # ------------------------------------------------------------------ + # Class about dog2 class Dog2 - def set_name(a_name) + def named(a_name) @name = a_name end end def test_instance_variables_can_be_set_by_assigning_to_them fido = Dog2.new - assert_equal __, fido.instance_variables + assert_equal [], fido.instance_variables - fido.set_name("Fido") - assert_equal __, fido.instance_variables + fido.named('Fido') + assert_equal [:@name], fido.instance_variables end def test_instance_variables_cannot_be_accessed_outside_the_class fido = Dog2.new - fido.set_name("Fido") + fido.named('Fido') - assert_raise(___) do + assert_raise(NoMethodError) do fido.name end - assert_raise(___) do - eval "fido.@name" + assert_raise(SyntaxError) do + eval <<-RUBY, binding, __FILE__, __LINE__ + 1 + fido.@name + RUBY # NOTE: Using eval because the above line is a syntax error. end end def test_you_can_politely_ask_for_instance_variable_values fido = Dog2.new - fido.set_name("Fido") + fido.named('Fido') - assert_equal __, fido.instance_variable_get("@name") + assert_equal 'Fido', fido.instance_variable_get('@name') end def test_you_can_rip_the_value_out_using_instance_eval fido = Dog2.new - fido.set_name("Fido") + fido.named('Fido') - assert_equal __, fido.instance_eval("@name") # string version - assert_equal __, fido.instance_eval { @name } # block version + assert_equal 'Fido', fido.instance_eval('@name') # string version + assert_equal 'Fido', (fido.instance_eval { @name }) # block version end # ------------------------------------------------------------------ + # Class about dog3 class Dog3 - def set_name(a_name) + attr_reader :name + + def named(a_name) @name = a_name end - def name - @name - end end def test_you_can_create_accessor_methods_to_return_instance_variables fido = Dog3.new - fido.set_name("Fido") + fido.named('Fido') - assert_equal __, fido.name + assert_equal 'Fido', fido.name end # ------------------------------------------------------------------ + # Class about dog4 class Dog4 attr_reader :name - def set_name(a_name) + def named(a_name) @name = a_name end end - def test_attr_reader_will_automatically_define_an_accessor fido = Dog4.new - fido.set_name("Fido") + fido.named('Fido') - assert_equal __, fido.name + assert_equal 'Fido', fido.name end # ------------------------------------------------------------------ + # Class about dog5 class Dog5 attr_accessor :name end - def test_attr_accessor_will_automatically_define_both_read_and_write_accessors fido = Dog5.new - fido.name = "Fido" - assert_equal __, fido.name + fido.name = 'Fido' + assert_equal 'Fido', fido.name end # ------------------------------------------------------------------ + # Class about dog6 class Dog6 attr_reader :name def initialize(initial_name) @@ -114,12 +122,12 @@ def initialize(initial_name) end def test_initialize_provides_initial_values_for_instance_variables - fido = Dog6.new("Fido") - assert_equal __, fido.name + fido = Dog6.new('Fido') + assert_equal 'Fido', fido.name end def test_args_to_new_must_match_initialize - assert_raise(___) do + assert_raise(ArgumentError) do Dog6.new end # THINK ABOUT IT: @@ -127,14 +135,15 @@ def test_args_to_new_must_match_initialize end def test_different_objects_have_different_instance_variables - fido = Dog6.new("Fido") - rover = Dog6.new("Rover") + fido = Dog6.new('Fido') + rover = Dog6.new('Rover') - assert_equal __, rover.name != fido.name + assert_equal true, rover.name != fido.name end # ------------------------------------------------------------------ + # Class about dog7 class Dog7 attr_reader :name @@ -142,7 +151,7 @@ def initialize(initial_name) @name = initial_name end - def get_self + def selfed self end @@ -156,35 +165,35 @@ def inspect end def test_inside_a_method_self_refers_to_the_containing_object - fido = Dog7.new("Fido") + fido = Dog7.new('Fido') - fidos_self = fido.get_self - assert_equal __, fidos_self + fidos_self = fido.selfed + assert_equal fido, fidos_self end def test_to_s_provides_a_string_version_of_the_object - fido = Dog7.new("Fido") - assert_equal __, fido.to_s + fido = Dog7.new('Fido') + assert_equal 'Fido', fido.to_s end def test_to_s_is_used_in_string_interpolation - fido = Dog7.new("Fido") - assert_equal __, "My dog is #{fido}" + fido = Dog7.new('Fido') + assert_equal 'My dog is Fido', "My dog is #{fido}" end def test_inspect_provides_a_more_complete_string_version - fido = Dog7.new("Fido") - assert_equal __, fido.inspect + fido = Dog7.new('Fido') + assert_equal "", fido.inspect end def test_all_objects_support_to_s_and_inspect - array = [1,2,3] + array = [1, 2, 3] - assert_equal __, array.to_s - assert_equal __, array.inspect + assert_equal '[1, 2, 3]', array.to_s + assert_equal '[1, 2, 3]', array.inspect - assert_equal __, "STRING".to_s - assert_equal __, "STRING".inspect + assert_equal 'STRING', 'STRING'.to_s + assert_equal '"STRING"', 'STRING'.inspect end - end +# rubocop:enable Style/EvalWithLocation diff --git a/about_constants.rb b/about_constants.rb index 68ae078..afcadd4 100644 --- a/about_constants.rb +++ b/about_constants.rb @@ -1,32 +1,34 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') -C = "top level" +C = 'top level'.freeze +# Class about canstants class AboutConstants < Neo::Koan - - C = "nested" + C = 'nested'.freeze def test_nested_constants_may_also_be_referenced_with_relative_paths - assert_equal __, C + assert_equal 'nested', C end def test_top_level_constants_are_referenced_by_double_colons - assert_equal __, ::C + assert_equal 'top level', ::C end def test_nested_constants_are_referenced_by_their_complete_path - assert_equal __, AboutConstants::C - assert_equal __, ::AboutConstants::C + assert_equal 'nested', AboutConstants::C + assert_equal 'nested', ::AboutConstants::C end # ------------------------------------------------------------------ + # Class about animal class Animal LEGS = 4 def legs_in_animal LEGS end + # Class about nestad animal class NestedAnimal def legs_in_nested_animal LEGS @@ -35,11 +37,12 @@ def legs_in_nested_animal end def test_nested_classes_inherit_constants_from_enclosing_classes - assert_equal __, Animal::NestedAnimal.new.legs_in_nested_animal + assert_equal 4, Animal::NestedAnimal.new.legs_in_nested_animal end # ------------------------------------------------------------------ + # Class about reptile class Reptile < Animal def legs_in_reptile LEGS @@ -47,14 +50,16 @@ def legs_in_reptile end def test_subclasses_inherit_constants_from_parent_classes - assert_equal __, Reptile.new.legs_in_reptile + assert_equal 4, Reptile.new.legs_in_reptile end # ------------------------------------------------------------------ + # Class about my animal class MyAnimals LEGS = 2 + # Class about bird class Bird < Animal def legs_in_bird LEGS @@ -63,7 +68,7 @@ def legs_in_bird end def test_who_wins_with_both_nested_and_inherited_constants - assert_equal __, MyAnimals::Bird.new.legs_in_bird + assert_equal 2, MyAnimals::Bird.new.legs_in_bird end # QUESTION: Which has precedence: The constant in the lexical scope, @@ -71,14 +76,17 @@ def test_who_wins_with_both_nested_and_inherited_constants # ------------------------------------------------------------------ - class MyAnimals::Oyster < Animal - def legs_in_oyster - LEGS + # Class about my animal + class MyAnimals + class Oyster < Animal + def legs_in_oyster + LEGS + end end end def test_who_wins_with_explicit_scoping_on_class_definition - assert_equal __, MyAnimals::Oyster.new.legs_in_oyster + assert_equal 2, MyAnimals::Oyster.new.legs_in_oyster end # QUESTION: Now which has precedence: The constant in the lexical diff --git a/about_control_statements.rb b/about_control_statements.rb index f323757..a2c23d3 100644 --- a/about_control_statements.rb +++ b/about_control_statements.rb @@ -1,22 +1,21 @@ -require File.expand_path(File.dirname(__FILE__) + '/neo') +# rubocop:disable Metrics/ClassLength, Lint/LiteralAsCondition, Metrics/MethodLength +require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about control statements class AboutControlStatements < Neo::Koan - def test_if_then_else_statements - if true - result = :true_value - else - result = :false_value - end - assert_equal __, result + result = if true + :true_value + else + :false_value + end + assert_equal :true_value, result end def test_if_then_statements result = :default_value - if true - result = :true_value - end - assert_equal __, result + result = :true_value if true + assert_equal :true_value, result end def test_if_statements_return_values @@ -25,110 +24,108 @@ def test_if_statements_return_values else :false_value end - assert_equal __, value + assert_equal :true_value, value value = if false :true_value else :false_value end - assert_equal __, value + assert_equal :false_value, value # NOTE: Actually, EVERY statement in Ruby will return a value, not # just if statements. end def test_if_statements_with_no_else_with_false_condition_return_value - value = if false - :true_value - end - assert_equal __, value + value = :true_value if false + assert_equal nil, value end def test_condition_operators - assert_equal __, (true ? :true_value : :false_value) - assert_equal __, (false ? :true_value : :false_value) + assert_equal :true_value, (true ? :true_value : :false_value) + assert_equal :false_value, (false ? :true_value : :false_value) end def test_if_statement_modifiers result = :default_value result = :true_value if true - assert_equal __, result + assert_equal :true_value, result end def test_unless_statement result = :default_value - unless false # same as saying 'if !false', which evaluates as 'if true' - result = :false_value - end - assert_equal __, result + result = :false_value unless false # same as saying 'if !false', which evaluates as 'if true' + assert_equal :false_value, result end def test_unless_statement_evaluate_true result = :default_value - unless true # same as saying 'if !true', which evaluates as 'if false' - result = :true_value - end - assert_equal __, result + result = :true_value unless true # same as saying 'if !true', which evaluates as 'if false' + assert_equal :default_value, result end def test_unless_statement_modifier result = :default_value result = :false_value unless false - assert_equal __, result + assert_equal :false_value, result end + # This method smells of :reek:FeatureEnvy def test_while_statement - i = 1 + counter = 1 result = 1 - while i <= 10 - result = result * i - i += 1 + while counter <= 10 + result *= counter + counter += 1 end - assert_equal __, result + assert_equal 3_628_800, result end + # This method smells of :reek:FeatureEnvy def test_break_statement - i = 1 + counter = 1 result = 1 - while true - break unless i <= 10 - result = result * i - i += 1 + loop do + break unless counter <= 10 + result *= counter + counter += 1 end - assert_equal __, result + assert_equal 3_628_800, result end + # This method smells of :reek:FeatureEnvy def test_break_statement_returns_values - i = 1 - result = while i <= 10 - break i if i % 2 == 0 - i += 1 - end + counter = 1 + result = while counter <= 10 + break counter if counter.even? + counter += 1 + end - assert_equal __, result + assert_equal 2, result end + # This method smells of :reek:FeatureEnvy def test_next_statement - i = 0 + counter = 0 result = [] - while i < 10 - i += 1 - next if (i % 2) == 0 - result << i + while counter < 10 + counter += 1 + next if counter.even? + result << counter end - assert_equal __, result + assert_equal [1, 3, 5, 7, 9], result end def test_for_statement - array = ["fish", "and", "chips"] + array = %w[fish and chips] result = [] - for item in array + array.each do |item| result << item.upcase end - assert_equal [__, __, __], result + assert_equal %w[FISH AND CHIPS], result end def test_times_statement @@ -136,7 +133,7 @@ def test_times_statement 10.times do sum += 1 end - assert_equal __, sum + assert_equal 10, sum end - end +# rubocop:enable Metrics/ClassLength, Lint/LiteralAsCondition, Metrics/MethodLength diff --git a/about_dice_project.rb b/about_dice_project.rb index 5a1848f..e8f0cc4 100644 --- a/about_dice_project.rb +++ b/about_dice_project.rb @@ -1,11 +1,15 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') # Implement a DiceSet Class here: -# -# class DiceSet -# code ... -# end +# Class about dice set +class DiceSet + attr_reader :values + def roll(size) + @values = Array.new(size) { rand(1..6) } + end +end +# Class about dice project class AboutDiceProject < Neo::Koan def test_can_create_a_dice_set dice = DiceSet.new @@ -16,7 +20,7 @@ def test_rolling_the_dice_returns_a_set_of_integers_between_1_and_6 dice = DiceSet.new dice.roll(5) - assert dice.values.is_a?(Array), "should be an array" + assert dice.values.is_a?(Array), 'should be an array' assert_equal 5, dice.values.size dice.values.each do |value| assert value >= 1 && value <= 6, "value #{value} must be between 1 and 6" @@ -41,7 +45,7 @@ def test_dice_values_should_change_between_rolls second_time = dice.values assert_not_equal first_time, second_time, - "Two rolls should not be equal" + 'Two rolls should not be equal' # THINK ABOUT IT: # @@ -59,5 +63,4 @@ def test_you_can_roll_different_numbers_of_dice dice.roll(1) assert_equal 1, dice.values.size end - end diff --git a/about_exceptions.rb b/about_exceptions.rb index 464f57e..aa8adee 100644 --- a/about_exceptions.rb +++ b/about_exceptions.rb @@ -1,68 +1,69 @@ +# rubocop:disable Lint/HandleExceptions, Metrics/MethodLength require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about exeptions class AboutExceptions < Neo::Koan - + # Class about special error class MySpecialError < RuntimeError end - def test_exceptions_inherit_from_Exception - assert_equal __, MySpecialError.ancestors[1] - assert_equal __, MySpecialError.ancestors[2] - assert_equal __, MySpecialError.ancestors[3] - assert_equal __, MySpecialError.ancestors[4] + def test_exceptions_inherit_from_exception + assert_equal RuntimeError, MySpecialError.ancestors[1] + assert_equal StandardError, MySpecialError.ancestors[2] + assert_equal Exception, MySpecialError.ancestors[3] + assert_equal Object, MySpecialError.ancestors[4] end def test_rescue_clause result = nil begin - fail "Oops" + raise 'Oops' rescue StandardError => ex result = :exception_handled end - assert_equal __, result + assert_equal :exception_handled, result - assert_equal __, ex.is_a?(StandardError), "Should be a Standard Error" - assert_equal __, ex.is_a?(RuntimeError), "Should be a Runtime Error" + assert_equal true, ex.is_a?(StandardError), 'Should be a Standard Error' + assert_equal true, ex.is_a?(RuntimeError), 'Should be a Runtime Error' assert RuntimeError.ancestors.include?(StandardError), - "RuntimeError is a subclass of StandardError" + 'RuntimeError is a subclass of StandardError' - assert_equal __, ex.message + assert_equal 'Oops', ex.message end def test_raising_a_particular_error result = nil begin # 'raise' and 'fail' are synonyms - raise MySpecialError, "My Message" + raise MySpecialError, 'My Message' rescue MySpecialError => ex result = :exception_handled end - assert_equal __, result - assert_equal __, ex.message + assert_equal :exception_handled, result + assert_equal 'My Message', ex.message end def test_ensure_clause - result = nil begin - fail "Oops" + raise 'Oops' rescue StandardError # no code here ensure result = :always_run end - assert_equal __, result + assert_equal :always_run, result end # Sometimes, we must know about the unknown def test_asserting_an_error_is_raised # A do-end is a block, a topic to explore more later - assert_raise(___) do - raise MySpecialError.new("New instances can be raised directly.") + assert_raise(AboutExceptions::MySpecialError) do + raise MySpecialError, 'New instances can be raised directly.' end end - end +# rubocop:enable Lint/HandleExceptions, Metrics/MethodLength diff --git a/about_hashes.rb b/about_hashes.rb index 7287ba0..956fd4a 100644 --- a/about_hashes.rb +++ b/about_hashes.rb @@ -1,29 +1,31 @@ +# rubocop:disable Metrics/AbcSize require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about hashes class AboutHashes < Neo::Koan def test_creating_hashes - empty_hash = Hash.new - assert_equal __, empty_hash.class - assert_equal(__, empty_hash) - assert_equal __, empty_hash.size + empty_hash = {} + assert_equal Hash, empty_hash.class + assert_equal({}, empty_hash) + assert_equal 0, empty_hash.size end def test_hash_literals - hash = { :one => "uno", :two => "dos" } - assert_equal __, hash.size + hash = { one: 'uno', two: 'dos' } + assert_equal 2, hash.size end def test_accessing_hashes - hash = { :one => "uno", :two => "dos" } - assert_equal __, hash[:one] - assert_equal __, hash[:two] - assert_equal __, hash[:doesnt_exist] + hash = { one: 'uno', two: 'dos' } + assert_equal 'uno', hash[:one] + assert_equal 'dos', hash[:two] + assert_equal nil, hash[:doesnt_exist] end def test_accessing_hashes_with_fetch - hash = { :one => "uno" } - assert_equal __, hash.fetch(:one) - assert_raise(___) do + hash = { one: 'uno' } + assert_equal 'uno', hash.fetch(:one) + assert_raise(IndexError) do hash.fetch(:doesnt_exist) end @@ -33,84 +35,85 @@ def test_accessing_hashes_with_fetch end def test_changing_hashes - hash = { :one => "uno", :two => "dos" } - hash[:one] = "eins" + hash = { one: 'uno', two: 'dos' } + hash[:one] = 'eins' - expected = { :one => __, :two => "dos" } - assert_equal __, hash + expected = { one: 'eins', two: 'dos' } + assert_equal expected, hash # Bonus Question: Why was "expected" broken out into a variable # rather than used as a literal? end def test_hash_is_unordered - hash1 = { :one => "uno", :two => "dos" } - hash2 = { :two => "dos", :one => "uno" } + hash1 = { one: 'uno', two: 'dos' } + hash2 = { two: 'dos', one: 'uno' } - assert_equal __, hash1 == hash2 + assert_equal true, hash1 == hash2 end def test_hash_keys - hash = { :one => "uno", :two => "dos" } - assert_equal __, hash.keys.size - assert_equal __, hash.keys.include?(:one) - assert_equal __, hash.keys.include?(:two) - assert_equal __, hash.keys.class + hash = { one: 'uno', two: 'dos' } + assert_equal 2, hash.keys.size + assert_equal true, hash.keys.include?(:one) + assert_equal true, hash.keys.include?(:two) + assert_equal Array, hash.keys.class end def test_hash_values - hash = { :one => "uno", :two => "dos" } - assert_equal __, hash.values.size - assert_equal __, hash.values.include?("uno") - assert_equal __, hash.values.include?("dos") - assert_equal __, hash.values.class + hash = { one: 'uno', two: 'dos' } + assert_equal 2, hash.values.size + assert_equal true, hash.values.include?('uno') + assert_equal true, hash.values.include?('dos') + assert_equal Array, hash.values.class end def test_combining_hashes - hash = { "jim" => 53, "amy" => 20, "dan" => 23 } - new_hash = hash.merge({ "jim" => 54, "jenny" => 26 }) + hash = { jim: 53, amy: 20, dan: 23 } + new_hash = hash.merge(jim: 54, jenny: 26) - assert_equal __, hash != new_hash + assert_equal true, hash != new_hash - expected = { "jim" => __, "amy" => 20, "dan" => 23, "jenny" => __ } - assert_equal __, expected == new_hash + expected = { jim: 53, amy: 20, dan: 23, jenny: 26 } + assert_equal false, expected == new_hash end def test_default_value - hash1 = Hash.new + hash1 = {} hash1[:one] = 1 - assert_equal __, hash1[:one] - assert_equal __, hash1[:two] + assert_equal 1, hash1[:one] + assert_equal nil, hash1[:two] - hash2 = Hash.new("dos") + hash2 = Hash.new('dos') hash2[:one] = 1 - assert_equal __, hash2[:one] - assert_equal __, hash2[:two] + assert_equal 1, hash2[:one] + assert_equal 'dos', hash2[:two] end def test_default_value_is_the_same_object hash = Hash.new([]) - hash[:one] << "uno" - hash[:two] << "dos" + hash[:one] << 'uno' + hash[:two] << 'dos' - assert_equal __, hash[:one] - assert_equal __, hash[:two] - assert_equal __, hash[:three] + assert_equal %w[uno dos], hash[:one] + assert_equal %w[uno dos], hash[:two] + assert_equal %w[uno dos], hash[:three] - assert_equal __, hash[:one].object_id == hash[:two].object_id + assert_equal true, hash[:one].object_id == hash[:two].object_id end def test_default_value_with_block - hash = Hash.new {|hash, key| hash[key] = [] } + hash = Hash.new { |hash_one, key| hash_one[key] = [] } - hash[:one] << "uno" - hash[:two] << "dos" + hash[:one] << 'uno' + hash[:two] << 'dos' - assert_equal __, hash[:one] - assert_equal __, hash[:two] - assert_equal __, hash[:three] + assert_equal %w[uno], hash[:one] + assert_equal %w[dos], hash[:two] + assert_equal [], hash[:three] end end +# rubocop:enable Metrics/AbcSize diff --git a/about_inheritance.rb b/about_inheritance.rb index 61bc890..1ad4fb6 100644 --- a/about_inheritance.rb +++ b/about_inheritance.rb @@ -1,6 +1,8 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about inheritance class AboutInheritance < Neo::Koan + # Class about dog class Dog attr_reader :name @@ -9,77 +11,79 @@ def initialize(name) end def bark - "WOOF" + 'WOOF' end end + # Class about chihuahua class Chihuahua < Dog def wag :happy end def bark - "yip" + 'yip' end end def test_subclasses_have_the_parent_as_an_ancestor - assert_equal __, Chihuahua.ancestors.include?(Dog) + assert_equal true, Chihuahua.ancestors.include?(Dog) end def test_all_classes_ultimately_inherit_from_object - assert_equal __, Chihuahua.ancestors.include?(Object) + assert_equal true, Chihuahua.ancestors.include?(Object) end def test_subclasses_inherit_behavior_from_parent_class - chico = Chihuahua.new("Chico") - assert_equal __, chico.name + chico = Chihuahua.new('Chico') + assert_equal 'Chico', chico.name end def test_subclasses_add_new_behavior - chico = Chihuahua.new("Chico") - assert_equal __, chico.wag + chico = Chihuahua.new('Chico') + assert_equal :happy, chico.wag - assert_raise(___) do - fido = Dog.new("Fido") + assert_raise(NoMethodError) do + fido = Dog.new('Fido') fido.wag end end def test_subclasses_can_modify_existing_behavior - chico = Chihuahua.new("Chico") - assert_equal __, chico.bark + chico = Chihuahua.new('Chico') + assert_equal 'yip', chico.bark - fido = Dog.new("Fido") - assert_equal __, fido.bark + fido = Dog.new('Fido') + assert_equal 'WOOF', fido.bark end # ------------------------------------------------------------------ + # Class about bull dog class BullDog < Dog def bark - super + ", GROWL" + super + ', GROWL' end end def test_subclasses_can_invoke_parent_behavior_via_super - ralph = BullDog.new("Ralph") - assert_equal __, ralph.bark + ralph = BullDog.new('Ralph') + assert_equal 'WOOF, GROWL', ralph.bark end # ------------------------------------------------------------------ + # Class about create dane class GreatDane < Dog def growl - super.bark + ", GROWL" + super.bark + ', GROWL' end end def test_super_does_not_work_cross_method - george = GreatDane.new("George") - assert_raise(___) do + george = GreatDane.new('George') + assert_raise(NoMethodError) do george.growl end end - end diff --git a/about_iteration.rb b/about_iteration.rb index 6179c2c..e4325d6 100644 --- a/about_iteration.rb +++ b/about_iteration.rb @@ -1,20 +1,20 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about iteration class AboutIteration < Neo::Koan - # -- An Aside ------------------------------------------------------ # Ruby 1.8 stores names as strings. Ruby 1.9 and later stores names # as symbols. So we use a version dependent method "as_name" to # convert to the right format in the koans. We will use "as_name" # whenever comparing to lists of methods. - in_ruby_version("1.8") do + in_ruby_version('1.8') do def as_name(name) name.to_s end end - in_ruby_version("1.9", "2") do + in_ruby_version('1.9', '2') do def as_name(name) name.to_sym end @@ -24,7 +24,7 @@ def as_name(name) # ------------------------------------------------------------------- def test_each_is_a_method_on_arrays - assert_equal __, [].methods.include?(as_name(:each)) + assert_equal true, [].methods.include?(as_name(:each)) end def test_iterating_with_each @@ -33,14 +33,14 @@ def test_iterating_with_each array.each do |item| sum += item end - assert_equal __, sum + assert_equal 6, sum end def test_each_can_use_curly_brace_blocks_too array = [1, 2, 3] sum = 0 array.each { |item| sum += item } - assert_equal __, sum + assert_equal 6, sum end def test_break_works_with_each_style_iterations @@ -50,42 +50,42 @@ def test_break_works_with_each_style_iterations break if item > 3 sum += item end - assert_equal __, sum + assert_equal 6, sum end def test_collect_transforms_elements_of_an_array array = [1, 2, 3] new_array = array.collect { |item| item + 10 } - assert_equal __, new_array + assert_equal [11, 12, 13], new_array # NOTE: 'map' is another name for the 'collect' operation another_array = array.map { |item| item + 10 } - assert_equal __, another_array + assert_equal [11, 12, 13], another_array end def test_select_selects_certain_items_from_an_array array = [1, 2, 3, 4, 5, 6] - even_numbers = array.select { |item| (item % 2) == 0 } - assert_equal __, even_numbers + even_numbers = array.select(&:even?) + assert_equal [2, 4, 6], even_numbers # NOTE: 'find_all' is another name for the 'select' operation - more_even_numbers = array.find_all { |item| (item % 2) == 0 } - assert_equal __, more_even_numbers + more_even_numbers = array.find_all(&:even?) + assert_equal [2, 4, 6], more_even_numbers end def test_find_locates_the_first_element_matching_a_criteria - array = ["Jim", "Bill", "Clarence", "Doug", "Eli"] + array = %w[Jim Bill Clarence Doug Eli] - assert_equal __, array.find { |item| item.size > 4 } + assert_equal 'Clarence', (array.find { |item| item.size > 4 }) end def test_inject_will_blow_your_mind result = [2, 3, 4].inject(0) { |sum, item| sum + item } - assert_equal __, result + assert_equal 9, result result2 = [2, 3, 4].inject(1) { |product, item| product * item } - assert_equal __, result2 + assert_equal 24, result2 # Extra Credit: # Describe in your own words what inject does. @@ -94,12 +94,12 @@ def test_inject_will_blow_your_mind def test_all_iteration_methods_work_on_any_collection_not_just_arrays # Ranges act like a collection result = (1..3).map { |item| item + 10 } - assert_equal __, result + assert_equal [11, 12, 13], result # Files act like a collection of lines - File.open("example_file.txt") do |file| + File.open('example_file.txt') do |file| upcase_lines = file.map { |line| line.strip.upcase } - assert_equal __, upcase_lines + assert_equal %w[THIS IS A TEST], upcase_lines end # NOTE: You can create your own collections that work with each, @@ -118,5 +118,4 @@ def test_all_iteration_methods_work_on_any_collection_not_just_arrays # # code to read 'file' # # When you get to the "AboutSandwichCode" koan, recheck your answer. - end diff --git a/about_java_interop.rb b/about_java_interop.rb index 47fef28..f7d9214 100644 --- a/about_java_interop.rb +++ b/about_java_interop.rb @@ -1,3 +1,4 @@ +# rubocop:disable all require File.expand_path(File.dirname(__FILE__) + '/neo') include Java @@ -11,6 +12,7 @@ # * Calling custom java class # * Calling Ruby from java??? +# Class about java interop class AboutJavaInterop < Neo::Koan def test_using_a_java_library_class java_array = java.util.ArrayList.new @@ -23,7 +25,7 @@ def test_java_class_can_be_referenced_using_both_ruby_and_java_like_syntax def test_include_class_includes_class_in_module_scope assert_nil defined?(TreeSet) - include_class "java.util.TreeSet" + include_class 'java.util.TreeSet' assert_equal __, defined?(TreeSet) end @@ -39,30 +41,30 @@ def test_include_class_includes_class_in_module_scope JString = java.lang.String def test_also_java_class_can_be_given_ruby_aliases - java_string = JString.new("A Java String") + java_string = JString.new('A Java String') assert_equal __, java_string.class assert_equal __, JString end def test_can_directly_call_java_methods_on_java_objects - java_string = JString.new("A Java String") + java_string = JString.new('A Java String') assert_equal __, java_string.toLowerCase end def test_jruby_provides_snake_case_versions_of_java_methods - java_string = JString.new("A Java String") + java_string = JString.new('A Java String') assert_equal __, java_string.to_lower_case end def test_jruby_provides_question_mark_versions_of_boolean_methods - java_string = JString.new("A Java String") - assert_equal __, java_string.endsWith("String") - assert_equal __, java_string.ends_with("String") - assert_equal __, java_string.ends_with?("String") + java_string = JString.new('A Java String') + assert_equal __, java_string.endsWith('String') + assert_equal __, java_string.ends_with('String') + assert_equal __, java_string.ends_with?('String') end def test_java_string_are_not_ruby_strings - ruby_string = "A Java String" + ruby_string = 'A Java String' java_string = java.lang.String.new(ruby_string) assert_equal __, java_string.is_a?(java.lang.String) assert_equal __, java_string.is_a?(String) @@ -96,7 +98,7 @@ def test_however_most_methods_returning_strings_return_ruby_strings end def test_some_ruby_objects_can_be_coerced_to_java - assert_equal __, "ruby string".to_java.class + assert_equal __, 'ruby string'.to_java.class assert_equal __, 1.to_java.class assert_equal __, 9.32.to_java.class assert_equal __, false.to_java.class @@ -110,7 +112,7 @@ def test_some_ruby_objects_are_not_coerced_to_what_you_might_expect def test_java_collections_are_enumerable java_array = java.util.ArrayList.new - java_array << "one" << "two" << "three" + java_array << 'one' << 'two' << 'three' assert_equal __, java_array.map { |item| item.upcase } end @@ -129,9 +131,8 @@ def multiply_all def test_java_class_are_open_from_ruby java_array = java.util.ArrayList.new - java_array.add_all([1,2,3,4,5]) + java_array.add_all([1, 2, 3, 4, 5]) assert_equal __, java_array.multiply_all end - end diff --git a/about_keyword_arguments.rb b/about_keyword_arguments.rb index 740d0c0..ca5cdc2 100644 --- a/about_keyword_arguments.rb +++ b/about_keyword_arguments.rb @@ -1,16 +1,16 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about Keyword Arguments class AboutKeywordArguments < Neo::Koan - def method_with_keyword_arguments(one: 1, two: 'two') [one, two] end def test_keyword_arguments - assert_equal __, method_with_keyword_arguments.class - assert_equal __, method_with_keyword_arguments - assert_equal __, method_with_keyword_arguments(one: 'one') - assert_equal __, method_with_keyword_arguments(two: 2) + assert_equal Array, method_with_keyword_arguments.class + assert_equal [1, 'two'], method_with_keyword_arguments + assert_equal %w[one two], method_with_keyword_arguments(one: 'one') + assert_equal [1, 2], method_with_keyword_arguments(two: 2) end def method_with_keyword_arguments_with_mandatory_argument(one, two: 2, three: 3) @@ -18,14 +18,13 @@ def method_with_keyword_arguments_with_mandatory_argument(one, two: 2, three: 3) end def test_keyword_arguments_with_wrong_number_of_arguments - exception = assert_raise (___) do + exception = assert_raise(ArgumentError) do method_with_keyword_arguments_with_mandatory_argument end - assert_match(/__/, exception.message) + assert_match(/wrong number of arguments/, exception.message) end # THINK ABOUT IT: # # Keyword arguments always have a default value, making them optional to the caller - end diff --git a/about_message_passing.rb b/about_message_passing.rb index c6d80a8..ebf59e9 100644 --- a/about_message_passing.rb +++ b/about_message_passing.rb @@ -1,7 +1,8 @@ +# rubocop:disable Style/MethodMissing require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about Message Passing class AboutMessagePassing < Neo::Koan - class MessageCatcher def caught? true @@ -23,15 +24,15 @@ def test_methods_can_be_invoked_by_sending_the_message def test_methods_can_be_invoked_more_dynamically mc = MessageCatcher.new - assert mc.send("caught?") - assert mc.send("caught" + __ ) # What do you need to add to the first string? - assert mc.send("CAUGHT?".____ ) # What would you need to do to the string? + assert mc.send('caught?') + assert mc.send('caught' + '?') # What do you need to add to the first string? + assert mc.send('CAUGHT?'.downcase) # What would you need to do to the string? end def test_send_with_underscores_will_also_send_messages mc = MessageCatcher.new - assert_equal __, mc.__send__(:caught?) + assert_equal true, mc.__send__(:caught?) # THINK ABOUT IT: # @@ -41,12 +42,13 @@ def test_send_with_underscores_will_also_send_messages def test_classes_can_be_asked_if_they_know_how_to_respond mc = MessageCatcher.new - assert_equal __, mc.respond_to?(:caught?) - assert_equal __, mc.respond_to?(:does_not_exist) + assert_equal true, mc.respond_to?(:caught?) + assert_equal false, mc.respond_to?(:does_not_exist) end # ------------------------------------------------------------------ + # Class about Message Catcher class MessageCatcher def add_a_payload(*args) args @@ -56,11 +58,11 @@ def add_a_payload(*args) def test_sending_a_message_with_arguments mc = MessageCatcher.new - assert_equal __, mc.add_a_payload - assert_equal __, mc.send(:add_a_payload) + assert_equal [], mc.add_a_payload + assert_equal [], mc.send(:add_a_payload) - assert_equal __, mc.add_a_payload(3, 4, nil, 6) - assert_equal __, mc.send(:add_a_payload, 3, 4, nil, 6) + assert_equal [3, 4, nil, 6], mc.add_a_payload(3, 4, nil, 6) + assert_equal [3, 4, nil, 6], mc.send(:add_a_payload, 3, 4, nil, 6) end # NOTE: @@ -72,13 +74,14 @@ def test_sending_a_message_with_arguments # ------------------------------------------------------------------ + # Class about Typical Object class TypicalObject end def test_sending_undefined_messages_to_a_typical_object_results_in_errors typical = TypicalObject.new - exception = assert_raise(___) do + exception = assert_raise(NoMethodError) do typical.foobar end assert_match(/foobar/, exception.message) @@ -87,7 +90,7 @@ def test_sending_undefined_messages_to_a_typical_object_results_in_errors def test_calling_method_missing_causes_the_no_method_error typical = TypicalObject.new - exception = assert_raise(___) do + exception = assert_raise(NoMethodError) do typical.method_missing(:foobar) end assert_match(/foobar/, exception.message) @@ -112,18 +115,19 @@ def test_calling_method_missing_causes_the_no_method_error # ------------------------------------------------------------------ + # Class about All Message Catcher class AllMessageCatcher - def method_missing(method_name, *args, &block) - "Someone called #{method_name} with <#{args.join(", ")}>" + def method_missing(method_name, *args) + "Someone called #{method_name} with <#{args.join(', ')}>" end end def test_all_messages_are_caught catcher = AllMessageCatcher.new - assert_equal __, catcher.foobar - assert_equal __, catcher.foobaz(1) - assert_equal __, catcher.sum(1,2,3,4,5,6) + assert_equal 'Someone called foobar with <>', catcher.foobar + assert_equal 'Someone called foobaz with <1>', catcher.foobaz(1) + assert_equal 'Someone called sum with <1, 2, 3, 4, 5, 6>', catcher.sum(1, 2, 3, 4, 5, 6) end def test_catching_messages_makes_respond_to_lie @@ -132,32 +136,37 @@ def test_catching_messages_makes_respond_to_lie assert_nothing_raised do catcher.any_method end - assert_equal __, catcher.respond_to?(:any_method) + assert_equal false, catcher.respond_to?(:any_method) end # ------------------------------------------------------------------ + # Class about Well Behaved Foo Catcher class WellBehavedFooCatcher def method_missing(method_name, *args, &block) - if method_name.to_s[0,3] == "foo" - "Foo to you too" + if method_name.to_s[0, 3] == 'foo' + 'Foo to you too' else super(method_name, *args, &block) end end end + def respond_to_missing?(method_name) + super + end + def test_foo_method_are_caught catcher = WellBehavedFooCatcher.new - assert_equal __, catcher.foo_bar - assert_equal __, catcher.foo_baz + assert_equal 'Foo to you too', catcher.foo_bar + assert_equal 'Foo to you too', catcher.foo_baz end def test_non_foo_messages_are_treated_normally catcher = WellBehavedFooCatcher.new - assert_raise(___) do + assert_raise(NoMethodError) do catcher.normal_undefined_method end end @@ -167,7 +176,7 @@ def test_non_foo_messages_are_treated_normally # (note: just reopening class from above) class WellBehavedFooCatcher def respond_to?(method_name) - if method_name.to_s[0,3] == "foo" + if method_name.to_s[0, 3] == 'foo' true else super(method_name) @@ -178,8 +187,8 @@ def respond_to?(method_name) def test_explicitly_implementing_respond_to_lets_objects_tell_the_truth catcher = WellBehavedFooCatcher.new - assert_equal __, catcher.respond_to?(:foo_bar) - assert_equal __, catcher.respond_to?(:something_else) + assert_equal true, catcher.respond_to?(:foo_bar) + assert_equal false, catcher.respond_to?(:something_else) end - end +# rubocop:enable Style/MethodMissing diff --git a/about_methods.rb b/about_methods.rb index 5678f22..4916b8d 100644 --- a/about_methods.rb +++ b/about_methods.rb @@ -1,24 +1,28 @@ +# rubocop:disable Lint/UnneededCopDisableDirective +# rubocop:disable Style/EvalWithLocation, Lint/UnreachableCode, Lint/Void +# rubocop:disable Style/AccessModifierDeclarations, Style/RedundantSelf, Lint/AmbiguousRegexpLiteral + require File.expand_path(File.dirname(__FILE__) + '/neo') -def my_global_method(a,b) - a + b +def my_global_method(firstarg, secondarg) + firstarg + secondarg end +# Class about methods class AboutMethods < Neo::Koan - def test_calling_global_methods - assert_equal __, my_global_method(2,3) + assert_equal 5, my_global_method(2, 3) end def test_calling_global_methods_without_parentheses result = my_global_method 2, 3 - assert_equal __, result + assert_equal 5, result end # (NOTE: We are Using eval below because the example code is # considered to be syntactically invalid). def test_sometimes_missing_parentheses_are_ambiguous - eval "assert_equal 5, my_global_method 2, 3" # ENABLE CHECK + eval 'assert_equal(5, my_global_method(2, 3))' # ENABLE CHECK # # Ruby doesn't know if you mean: # @@ -33,26 +37,26 @@ def test_sometimes_missing_parentheses_are_ambiguous # NOTE: wrong number of arguments is not a SYNTAX error, but a # runtime error. def test_calling_global_methods_with_wrong_number_of_arguments - exception = assert_raise(___) do + exception = assert_raise(ArgumentError) do my_global_method end - assert_match(/__/, exception.message) + assert_match(/wrong number of arguments/, exception.message) - exception = assert_raise(___) do - my_global_method(1,2,3) + exception = assert_raise(ArgumentError) do + my_global_method(1, 2, 3) end - assert_match(/__/, exception.message) + assert_match(/wrong number of arguments/, exception.message) end # ------------------------------------------------------------------ - def method_with_defaults(a, b=:default_value) - [a, b] + def method_with_defaults(fisttarg, secondarg = :default_value) + [fisttarg, secondarg] end def test_calling_with_default_values - assert_equal [1, __], method_with_defaults(1) - assert_equal [1, __], method_with_defaults(1, 2) + assert_equal [1, :default_value], method_with_defaults(1) + assert_equal [1, 2], method_with_defaults(1, 2) end # ------------------------------------------------------------------ @@ -62,10 +66,10 @@ def method_with_var_args(*args) end def test_calling_with_variable_arguments - assert_equal __, method_with_var_args.class - assert_equal __, method_with_var_args - assert_equal __, method_with_var_args(:one) - assert_equal __, method_with_var_args(:one, :two) + assert_equal Array, method_with_var_args.class + assert_equal [], method_with_var_args + assert_equal [:one], method_with_var_args(:one) + assert_equal %i[one two], method_with_var_args(:one, :two) end # ------------------------------------------------------------------ @@ -77,7 +81,7 @@ def method_with_explicit_return end def test_method_with_explicit_return - assert_equal __, method_with_explicit_return + assert_equal :return_value, method_with_explicit_return end # ------------------------------------------------------------------ @@ -88,64 +92,68 @@ def method_without_explicit_return end def test_method_without_explicit_return - assert_equal __, method_without_explicit_return + assert_equal :return_value, method_without_explicit_return end # ------------------------------------------------------------------ - def my_method_in_the_same_class(a, b) - a * b + def my_method_in_the_same_class(firsarg, secontarg) + firsarg * secontarg end def test_calling_methods_in_same_class - assert_equal __, my_method_in_the_same_class(3,4) + assert_equal 12, my_method_in_the_same_class(3, 4) end def test_calling_methods_in_same_class_with_explicit_receiver - assert_equal __, self.my_method_in_the_same_class(3,4) + assert_equal 12, my_method_in_the_same_class(3, 4) end # ------------------------------------------------------------------ def my_private_method - "a secret" + 'a secret' end private :my_private_method def test_calling_private_methods_without_receiver - assert_equal __, my_private_method + assert_equal 'a secret', my_private_method end def test_calling_private_methods_with_an_explicit_receiver - exception = assert_raise(___) do + exception = assert_raise(NoMethodError) do self.my_private_method end - assert_match /__/, exception.message + assert_match /private method `my_private_method' called for/, exception.message end # ------------------------------------------------------------------ + # Class about dog class Dog def name - "Fido" + 'Fido' end private def tail - "tail" + 'tail' end end def test_calling_methods_in_other_objects_require_explicit_receiver rover = Dog.new - assert_equal __, rover.name + assert_equal 'Fido', rover.name end def test_calling_private_methods_in_other_objects rover = Dog.new - assert_raise(___) do + assert_raise(NoMethodError) do rover.tail end end end +# rubocop:enable Style/EvalWithLocation, Lint/UnreachableCode, Lint/Void +# rubocop:enable Style/AccessModifierDeclarations, Style/RedundantSelf, Lint/AmbiguousRegexpLiteral +# rubocop:enable Lint/UnneededCopDisableDirective diff --git a/about_modules.rb b/about_modules.rb index 38652df..87bb6ae 100644 --- a/about_modules.rb +++ b/about_modules.rb @@ -1,8 +1,9 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about modules class AboutModules < Neo::Koan module Nameable - def set_name(new_name) + def nemed(new_name) @name = new_name end @@ -12,24 +13,25 @@ def here end def test_cant_instantiate_modules - assert_raise(___) do + assert_raise(NoMethodError) do Nameable.new end end # ------------------------------------------------------------------ + # Class about dog class Dog include Nameable attr_reader :name def initialize - @name = "Fido" + @name = 'Fido' end def bark - "WOOF" + 'WOOF' end def here @@ -39,25 +41,25 @@ def here def test_normal_methods_are_available_in_the_object fido = Dog.new - assert_equal __, fido.bark + assert_equal 'WOOF', fido.bark end def test_module_methods_are_also_available_in_the_object fido = Dog.new assert_nothing_raised do - fido.set_name("Rover") + fido.nemed('Rover') end end def test_module_methods_can_affect_instance_variables_in_the_object fido = Dog.new - assert_equal __, fido.name - fido.set_name("Rover") - assert_equal __, fido.name + assert_equal 'Fido', fido.name + fido.nemed('Rover') + assert_equal 'Rover', fido.name end def test_classes_can_override_module_methods fido = Dog.new - assert_equal __, fido.here + assert_equal :in_object, fido.here end end diff --git a/about_nil.rb b/about_nil.rb index be1d5db..680f501 100644 --- a/about_nil.rb +++ b/about_nil.rb @@ -1,30 +1,28 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') - +# Lets think about nil class AboutNil < Neo::Koan def test_nil_is_an_object - assert_equal __, nil.is_a?(Object), "Unlike NULL in other languages" + assert_equal true, nil.is_a?(Object), 'Unlike NULL in other languages' end def test_you_dont_get_null_pointer_errors_when_calling_methods_on_nil # What happens when you call a method that doesn't exist. The # following begin/rescue/end code block captures the exception and # makes some assertions about it. - begin - nil.some_method_nil_doesnt_know_about - rescue Exception => ex - # What exception has been caught? - assert_equal __, ex.class + nil.some_method_nil_doesnt_know_about + rescue StandardError => e + # What exception has been caught? + assert_equal NoMethodError, e.class - # What message was attached to the exception? - # (HINT: replace __ with part of the error message.) - assert_match(/__/, ex.message) - end + # What message was attached to the exception? + # (HINT: replace __ with part of the error message.) + assert_match(/undefined method `some_method_nil_doesnt_know_about' for nil:NilClass/, e.message) end def test_nil_has_a_few_methods_defined_on_it - assert_equal __, nil.nil? - assert_equal __, nil.to_s - assert_equal __, nil.inspect + assert_equal true, nil.nil? + assert_equal '', nil.to_s + assert_equal 'nil', nil.inspect # THINK ABOUT IT: # @@ -34,5 +32,4 @@ def test_nil_has_a_few_methods_defined_on_it # obj == nil # Why? end - end diff --git a/about_objects.rb b/about_objects.rb index 514fcdc..7e8f9a3 100644 --- a/about_objects.rb +++ b/about_objects.rb @@ -1,40 +1,41 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about objects class AboutObjects < Neo::Koan def test_everything_is_an_object - assert_equal __, 1.is_a?(Object) - assert_equal __, 1.5.is_a?(Object) - assert_equal __, "string".is_a?(Object) - assert_equal __, nil.is_a?(Object) - assert_equal __, Object.is_a?(Object) + assert_equal true, 1.is_a?(Object) + assert_equal true, 1.5.is_a?(Object) + assert_equal true, 'string'.is_a?(Object) + assert_equal true, nil.is_a?(Object) + assert_equal true, Object.is_a?(Object) end def test_objects_can_be_converted_to_strings - assert_equal __, 123.to_s - assert_equal __, nil.to_s + assert_equal '123', 123.to_s + assert_equal '', nil.to_s end def test_objects_can_be_inspected - assert_equal __, 123.inspect - assert_equal __, nil.inspect + assert_equal '123', 123.inspect + assert_equal 'nil', nil.inspect end def test_every_object_has_an_id obj = Object.new - assert_equal __, obj.object_id.class + assert_equal Integer, obj.object_id.class end def test_every_object_has_different_id obj = Object.new another_obj = Object.new - assert_equal __, obj.object_id != another_obj.object_id + assert_equal true, obj.object_id != another_obj.object_id end def test_small_integers_have_fixed_ids - assert_equal __, 0.object_id - assert_equal __, 1.object_id - assert_equal __, 2.object_id - assert_equal __, 100.object_id + assert_equal 1, 0.object_id + assert_equal 3, 1.object_id + assert_equal 5, 2.object_id + assert_equal 201, 100.object_id # THINK ABOUT IT: # What pattern do the object IDs for small integers follow? @@ -44,7 +45,7 @@ def test_clone_creates_a_different_object obj = Object.new copy = obj.clone - assert_equal __, obj != copy - assert_equal __, obj.object_id != copy.object_id + assert_equal true, obj != copy + assert_equal true, obj.object_id != copy.object_id end end diff --git a/about_open_classes.rb b/about_open_classes.rb index 56d1817..1817ab3 100644 --- a/about_open_classes.rb +++ b/about_open_classes.rb @@ -1,15 +1,16 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about Open Classes class AboutOpenClasses < Neo::Koan class Dog def bark - "WOOF" + 'WOOF' end end def test_as_defined_dogs_do_bark fido = Dog.new - assert_equal __, fido.bark + assert_equal 'WOOF', fido.bark end # ------------------------------------------------------------------ @@ -17,27 +18,28 @@ def test_as_defined_dogs_do_bark # Open the existing Dog class and add a new method. class Dog def wag - "HAPPY" + 'HAPPY' end end def test_after_reopening_dogs_can_both_wag_and_bark fido = Dog.new - assert_equal __, fido.wag - assert_equal __, fido.bark + assert_equal 'HAPPY', fido.wag + assert_equal 'WOOF', fido.bark end # ------------------------------------------------------------------ - class ::Integer + # Class about integer + class Integer def even? - (self % 2) == 0 + (self % 2).zero? end end def test_even_existing_built_in_classes_can_be_reopened - assert_equal __, 1.even? - assert_equal __, 2.even? + assert_equal false, 1.even? + assert_equal true, 2.even? end # NOTE: To understand why we need the :: before Integer, you need to diff --git a/about_proxy_object_project.rb b/about_proxy_object_project.rb index 36d1cf0..e4205dc 100644 --- a/about_proxy_object_project.rb +++ b/about_proxy_object_project.rb @@ -1,3 +1,7 @@ +# rubocop:disable Lint/UnneededCopDisableDirective +# rubocop:disable Style/MethodMissingSuper, Style/MissingRespondToMissing +# rubocop:disable Style/MethodMissing + require File.expand_path(File.dirname(__FILE__) + '/neo') # Project: Create a Proxy Class @@ -12,17 +16,40 @@ # missing handler and any other supporting methods. The specification # of the Proxy class is given in the AboutProxyObjectProject koan. +# Class about proxy class Proxy def initialize(target_object) @object = target_object # ADD MORE CODE HERE + @messages = Hash.new(0) end # WRITE CODE HERE + + def method_missing(method_name, *args, &block) + @messages[method_name] += 1 + @object.send(method_name, *args, &block) + end + + def called?(method_name) + @messages.key?(method_name) + end + + def number_of_times_called(method_name) + @messages[method_name] + end + + def messages + @messages.keys + end + + def respond_to_missing? + true + end end # The proxy object should pass the following Koan: -# +# Class about Proxy Object Project class AboutProxyObjectProject < Neo::Koan def test_proxy_method_returns_wrapped_object # NOTE: The Television class is defined below @@ -49,7 +76,7 @@ def test_proxy_records_messages_sent_to_tv tv.power tv.channel = 10 - assert_equal [:power, :channel=], tv.messages + assert_equal %i[power channel=], tv.messages end def test_proxy_handles_invalid_messages @@ -67,7 +94,7 @@ def test_proxy_reports_methods_have_been_called tv.power assert tv.called?(:power) - assert ! tv.called?(:channel) + assert !tv.called?(:channel) end def test_proxy_counts_method_calls @@ -83,17 +110,16 @@ def test_proxy_counts_method_calls end def test_proxy_can_record_more_than_just_tv_objects - proxy = Proxy.new("Code Mash 2009") + proxy = Proxy.new('Code Mash 2009') proxy.upcase! result = proxy.split - assert_equal ["CODE", "MASH", "2009"], result - assert_equal [:upcase!, :split], proxy.messages + assert_equal %w[CODE MASH 2009], result + assert_equal %i[upcase! split], proxy.messages end end - # ==================================================================== # The following code is to support the testing of the Proxy class. No # changes should be necessary to anything below this comment. @@ -103,11 +129,11 @@ class Television attr_accessor :channel def power - if @power == :on - @power = :off - else - @power = :on - end + @power = if @power == :on + :off + else + :on + end end def on? @@ -130,7 +156,7 @@ def test_it_also_turns_off tv.power tv.power - assert ! tv.on? + assert !tv.on? end def test_edge_case_on_off @@ -144,7 +170,7 @@ def test_edge_case_on_off tv.power - assert ! tv.on? + assert !tv.on? end def test_can_set_the_channel @@ -154,3 +180,6 @@ def test_can_set_the_channel assert_equal 11, tv.channel end end +# rubocop:enable Style/MethodMissingSuper, Style/MissingRespondToMissing +# rubocop:enable Style/MethodMissing +# rubocop:enable Lint/UnneededCopDisableDirective diff --git a/about_regular_expressions.rb b/about_regular_expressions.rb index b1b47a2..9a71c92 100644 --- a/about_regular_expressions.rb +++ b/about_regular_expressions.rb @@ -1,34 +1,34 @@ -# -*- coding: utf-8 -*- require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about Regular Expressions class AboutRegularExpressions < Neo::Koan def test_a_pattern_is_a_regular_expression - assert_equal __, /pattern/.class + assert_equal Regexp, /pattern/.class end def test_a_regexp_can_search_a_string_for_matching_content - assert_equal __, "some matching content"[/match/] + assert_equal 'match', 'some matching content'[/match/] end def test_a_failed_match_returns_nil - assert_equal __, "some matching content"[/missing/] + assert_equal nil, 'some matching content'[/missing/] end # ------------------------------------------------------------------ def test_question_mark_means_optional - assert_equal __, "abbcccddddeeeee"[/ab?/] - assert_equal __, "abbcccddddeeeee"[/az?/] + assert_equal 'ab', 'abbcccddddeeeee'[/ab?/] + assert_equal 'a', 'abbcccddddeeeee'[/az?/] end def test_plus_means_one_or_more - assert_equal __, "abbcccddddeeeee"[/bc+/] + assert_equal 'bccc', 'abbcccddddeeeee'[/bc+/] end def test_asterisk_means_zero_or_more - assert_equal __, "abbcccddddeeeee"[/ab*/] - assert_equal __, "abbcccddddeeeee"[/az*/] - assert_equal __, "abbcccddddeeeee"[/z*/] + assert_equal 'abb', 'abbcccddddeeeee'[/ab*/] + assert_equal 'a', 'abbcccddddeeeee'[/az*/] + assert_equal '', 'abbcccddddeeeee'[/z*/] # THINK ABOUT IT: # @@ -44,101 +44,101 @@ def test_asterisk_means_zero_or_more # ------------------------------------------------------------------ def test_the_left_most_match_wins - assert_equal __, "abbccc az"[/az*/] + assert_equal 'a', 'abbccc az'[/az*/] end # ------------------------------------------------------------------ def test_character_classes_give_options_for_a_character - animals = ["cat", "bat", "rat", "zat"] - assert_equal __, animals.select { |a| a[/[cbr]at/] } + animals = %w[cat bat rat zat] + assert_equal %w[cat bat rat], (animals.select { |a| a[/[cbr]at/] }) end def test_slash_d_is_a_shortcut_for_a_digit_character_class - assert_equal __, "the number is 42"[/[0123456789]+/] - assert_equal __, "the number is 42"[/\d+/] + assert_equal '42', 'the number is 42'[/[0123456789]+/] + assert_equal '42', 'the number is 42'[/\d+/] end def test_character_classes_can_include_ranges - assert_equal __, "the number is 42"[/[0-9]+/] + assert_equal '42', 'the number is 42'[/[0-9]+/] end def test_slash_s_is_a_shortcut_for_a_whitespace_character_class - assert_equal __, "space: \t\n"[/\s+/] + assert_equal " \t\n", "space: \t\n"[/\s+/] end def test_slash_w_is_a_shortcut_for_a_word_character_class # NOTE: This is more like how a programmer might define a word. - assert_equal __, "variable_1 = 42"[/[a-zA-Z0-9_]+/] - assert_equal __, "variable_1 = 42"[/\w+/] + assert_equal 'variable_1', 'variable_1 = 42'[/[a-zA-Z0-9_]+/] + assert_equal 'variable_1', 'variable_1 = 42'[/\w+/] end def test_period_is_a_shortcut_for_any_non_newline_character - assert_equal __, "abc\n123"[/a.+/] + assert_equal 'abc', "abc\n123"[/a.+/] end def test_a_character_class_can_be_negated - assert_equal __, "the number is 42"[/[^0-9]+/] + assert_equal 'the number is ', 'the number is 42'[/[^0-9]+/] end def test_shortcut_character_classes_are_negated_with_capitals - assert_equal __, "the number is 42"[/\D+/] - assert_equal __, "space: \t\n"[/\S+/] + assert_equal 'the number is ', 'the number is 42'[/\D+/] + assert_equal 'space:', "space: \t\n"[/\S+/] # ... a programmer would most likely do - assert_equal __, "variable_1 = 42"[/[^a-zA-Z0-9_]+/] - assert_equal __, "variable_1 = 42"[/\W+/] + assert_equal ' = ', 'variable_1 = 42'[/[^a-zA-Z0-9_]+/] + assert_equal ' = ', 'variable_1 = 42'[/\W+/] end # ------------------------------------------------------------------ def test_slash_a_anchors_to_the_start_of_the_string - assert_equal __, "start end"[/\Astart/] - assert_equal __, "start end"[/\Aend/] + assert_equal 'start', 'start end'[/\Astart/] + assert_equal nil, 'start end'[/\Aend/] end def test_slash_z_anchors_to_the_end_of_the_string - assert_equal __, "start end"[/end\z/] - assert_equal __, "start end"[/start\z/] + assert_equal 'end', 'start end'[/end\z/] + assert_equal nil, 'start end'[/start\z/] end def test_caret_anchors_to_the_start_of_lines - assert_equal __, "num 42\n2 lines"[/^\d+/] + assert_equal '2', "num 42\n2 lines"[/^\d+/] end def test_dollar_sign_anchors_to_the_end_of_lines - assert_equal __, "2 lines\nnum 42"[/\d+$/] + assert_equal '42', "2 lines\nnum 42"[/\d+$/] end def test_slash_b_anchors_to_a_word_boundary - assert_equal __, "bovine vines"[/\bvine./] + assert_equal 'vines', 'bovine vines'[/\bvine./] end # ------------------------------------------------------------------ def test_parentheses_group_contents - assert_equal __, "ahahaha"[/(ha)+/] + assert_equal 'hahaha', 'ahahaha'[/(ha)+/] end # ------------------------------------------------------------------ def test_parentheses_also_capture_matched_content_by_number - assert_equal __, "Gray, James"[/(\w+), (\w+)/, 1] - assert_equal __, "Gray, James"[/(\w+), (\w+)/, 2] + assert_equal 'Gray', 'Gray, James'[/(\w+), (\w+)/, 1] + assert_equal 'James', 'Gray, James'[/(\w+), (\w+)/, 2] end def test_variables_can_also_be_used_to_access_captures - assert_equal __, "Name: Gray, James"[/(\w+), (\w+)/] - assert_equal __, $1 - assert_equal __, $2 + assert_equal 'Gray, James', 'Name: Gray, James'[/(\w+), (\w+)/] + assert_equal 'Gray', Regexp.last_match(1) + assert_equal 'James', Regexp.last_match(2) end # ------------------------------------------------------------------ def test_a_vertical_pipe_means_or grays = /(James|Dana|Summer) Gray/ - assert_equal __, "James Gray"[grays] - assert_equal __, "Summer Gray"[grays, 1] - assert_equal __, "Jim Gray"[grays, 1] + assert_equal 'James Gray', 'James Gray'[grays] + assert_equal 'Summer', 'Summer Gray'[grays, 1] + assert_equal nil, 'Jim Gray'[grays, 1] end # THINK ABOUT IT: @@ -148,14 +148,14 @@ def test_a_vertical_pipe_means_or # ------------------------------------------------------------------ def test_scan_is_like_find_all - assert_equal __, "one two-three".scan(/\w+/) + assert_equal %w[one two three], 'one two-three'.scan(/\w+/) end def test_sub_is_like_find_and_replace - assert_equal __, "one two-three".sub(/(t\w*)/) { $1[0, 1] } + assert_equal 'one t-three', 'one two-three'.sub(/(t\w*)/) { Regexp.last_match(1)[0, 1] } end def test_gsub_is_like_find_and_replace_all - assert_equal __, "one two-three".gsub(/(t\w*)/) { $1[0, 1] } + assert_equal 'one t-t', 'one two-three'.gsub(/(t\w*)/) { Regexp.last_match(1)[0, 1] } end end diff --git a/about_sandwich_code.rb b/about_sandwich_code.rb index ca9c554..9ac135d 100644 --- a/about_sandwich_code.rb +++ b/about_sandwich_code.rb @@ -1,20 +1,18 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about Sandwich Code class AboutSandwichCode < Neo::Koan - def count_lines(file_name) file = open(file_name) count = 0 - while file.gets - count += 1 - end + count += 1 while file.gets count ensure - file.close if file + file&.close end def test_counting_lines - assert_equal __, count_lines("example_file.txt") + assert_equal 4, count_lines('example_file.txt') end # ------------------------------------------------------------------ @@ -29,7 +27,7 @@ def find_line(file_name) end def test_finding_lines - assert_equal __, find_line("example_file.txt") + assert_equal "test\n", find_line('example_file.txt') end # ------------------------------------------------------------------ @@ -74,17 +72,24 @@ def count_lines2(file_name) end def test_counting_lines2 - assert_equal __, count_lines2("example_file.txt") + assert_equal 4, count_lines2('example_file.txt') end # ------------------------------------------------------------------ def find_line2(file_name) # Rewrite find_line using the file_sandwich library function. + file_sandwich(file_name) do |line| + count = 0 + while line.gets + count += 1 + end + count + end end def test_finding_lines2 - assert_equal __, find_line2("example_file.txt") + assert_equal 4, find_line2('example_file.txt') end # ------------------------------------------------------------------ @@ -100,7 +105,6 @@ def count_lines3(file_name) end def test_open_handles_the_file_sandwich_when_given_a_block - assert_equal __, count_lines3("example_file.txt") + assert_equal 4, count_lines3('example_file.txt') end - end diff --git a/about_scope.rb b/about_scope.rb index 451e98b..0aa25f4 100644 --- a/about_scope.rb +++ b/about_scope.rb @@ -1,5 +1,6 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') +# Class about scope class AboutScope < Neo::Koan module Jims class Dog @@ -18,7 +19,7 @@ def identify end def test_dog_is_not_available_in_the_current_scope - assert_raise(___) do + assert_raise(NameError) do Dog.new end end @@ -26,28 +27,29 @@ def test_dog_is_not_available_in_the_current_scope def test_you_can_reference_nested_classes_using_the_scope_operator fido = Jims::Dog.new rover = Joes::Dog.new - assert_equal __, fido.identify - assert_equal __, rover.identify + assert_equal :jims_dog, fido.identify + assert_equal :joes_dog, rover.identify - assert_equal __, fido.class != rover.class - assert_equal __, Jims::Dog != Joes::Dog + assert_equal true, fido.class != rover.class + assert_equal true, Jims::Dog != Joes::Dog end # ------------------------------------------------------------------ + # Class about string class String end def test_bare_bones_class_names_assume_the_current_scope - assert_equal __, AboutScope::String == String + assert_equal true, AboutScope::String == String end def test_nested_string_is_not_the_same_as_the_system_string - assert_equal __, String == "HI".class + assert_equal false, String == 'HI'.class end def test_use_the_prefix_scope_operator_to_force_the_global_scope - assert_equal __, ::String == "HI".class + assert_equal true, ::String == 'HI'.class end # ------------------------------------------------------------------ @@ -55,7 +57,7 @@ def test_use_the_prefix_scope_operator_to_force_the_global_scope PI = 3.1416 def test_constants_are_defined_with_an_initial_uppercase_letter - assert_equal __, PI + assert_equal 3.1416, PI end # ------------------------------------------------------------------ @@ -63,17 +65,17 @@ def test_constants_are_defined_with_an_initial_uppercase_letter MyString = ::String def test_class_names_are_just_constants - assert_equal __, MyString == ::String - assert_equal __, MyString == "HI".class + assert_equal true, MyString == ::String + assert_equal true, MyString == 'HI'.class end def test_constants_can_be_looked_up_explicitly - assert_equal __, PI == AboutScope.const_get("PI") - assert_equal __, MyString == AboutScope.const_get("MyString") + assert_equal true, PI == AboutScope.const_get('PI') + assert_equal true, MyString == AboutScope.const_get('MyString') end def test_you_can_get_a_list_of_constants_for_any_class_or_module - assert_equal __, Jims.constants - assert Object.constants.size > _n_ + assert_equal [:Dog], Jims.constants + assert Object.constants.size > 1 end end diff --git a/about_scoring_project.rb b/about_scoring_project.rb index bdc5dd1..6b6cfb8 100644 --- a/about_scoring_project.rb +++ b/about_scoring_project.rb @@ -1,3 +1,5 @@ +# rubocop:disable Metrics/AbcSize, Lint/UnneededCopDisableDirective + require File.expand_path(File.dirname(__FILE__) + '/neo') # Greed is a dice game where you roll up to five dice to accumulate @@ -30,9 +32,18 @@ # Your goal is to write the score method. def score(dice) - # You need to write this method + price = dice.sort + result = 0 + (1..6).each do |number| + throw_count = price.count(number) + result += (number == 1 ? 1000 : number * 100) if throw_count >= 3 + result += (throw_count % 3) * 100 if number == 1 + result += (throw_count % 3) * 50 if number == 5 + end + result end +# Class about Scoring Project class AboutScoringProject < Neo::Koan def test_score_of_an_empty_list_is_zero assert_equal 0, score([]) @@ -47,31 +58,31 @@ def test_score_of_a_single_roll_of_1_is_100 end def test_score_of_multiple_1s_and_5s_is_the_sum_of_individual_scores - assert_equal 300, score([1,5,5,1]) + assert_equal 300, score([1, 5, 5, 1]) end def test_score_of_single_2s_3s_4s_and_6s_are_zero - assert_equal 0, score([2,3,4,6]) + assert_equal 0, score([2, 3, 4, 6]) end def test_score_of_a_triple_1_is_1000 - assert_equal 1000, score([1,1,1]) + assert_equal 1000, score([1, 1, 1]) end def test_score_of_other_triples_is_100x - assert_equal 200, score([2,2,2]) - assert_equal 300, score([3,3,3]) - assert_equal 400, score([4,4,4]) - assert_equal 500, score([5,5,5]) - assert_equal 600, score([6,6,6]) + assert_equal 200, score([2, 2, 2]) + assert_equal 300, score([3, 3, 3]) + assert_equal 400, score([4, 4, 4]) + assert_equal 500, score([5, 5, 5]) + assert_equal 600, score([6, 6, 6]) end def test_score_of_mixed_is_sum - assert_equal 250, score([2,5,2,2,3]) - assert_equal 550, score([5,5,5,5]) - assert_equal 1100, score([1,1,1,1]) - assert_equal 1200, score([1,1,1,1,1]) - assert_equal 1150, score([1,1,1,5,1]) + assert_equal 250, score([2, 5, 2, 2, 3]) + assert_equal 550, score([5, 5, 5, 5]) + assert_equal 1100, score([1, 1, 1, 1]) + assert_equal 1200, score([1, 1, 1, 1, 1]) + assert_equal 1150, score([1, 1, 1, 5, 1]) end - end +# rubocop:enable Metrics/AbcSize, Lint/UnneededCopDisableDirective diff --git a/about_strings.rb b/about_strings.rb index 1e0ea49..36532d2 100644 --- a/about_strings.rb +++ b/about_strings.rb @@ -1,38 +1,39 @@ require File.expand_path(File.dirname(__FILE__) + '/neo') -class AboutStrings < Neo::Koan +# Class about string +class AboutStrings < Neo::Koan # rubocop:disable Metrics/ClassLength def test_double_quoted_strings_are_strings - string = "Hello, World" - assert_equal __, string.is_a?(String) + string = 'Hello, World' + assert_equal true, string.is_a?(String) end def test_single_quoted_strings_are_also_strings string = 'Goodbye, World' - assert_equal __, string.is_a?(String) + assert_equal true, string.is_a?(String) end def test_use_single_quotes_to_create_string_with_double_quotes string = 'He said, "Go Away."' - assert_equal __, string + assert_equal 'He said, "Go Away."', string end def test_use_double_quotes_to_create_strings_with_single_quotes string = "Don't" - assert_equal __, string + assert_equal "Don't", string end def test_use_backslash_for_those_hard_cases a = "He said, \"Don't\"" b = 'He said, "Don\'t"' - assert_equal __, a == b + assert_equal true, a == b end def test_use_flexible_quoting_to_handle_really_hard_cases a = %(flexible quotes can handle both ' and " characters) b = %!flexible quotes can handle both ' and " characters! c = %{flexible quotes can handle both ' and " characters} - assert_equal __, a == b - assert_equal __, a == c + assert_equal true, a == b + assert_equal true, a == c end def test_flexible_quotes_can_handle_multiple_lines @@ -40,63 +41,65 @@ def test_flexible_quotes_can_handle_multiple_lines It was the best of times, It was the worst of times. } - assert_equal __, long_string.length - assert_equal __, long_string.lines.count - assert_equal __, long_string[0,1] + assert_equal 54, long_string.length + assert_equal 3, long_string.lines.count + assert_equal "\n", long_string[0, 1] end def test_here_documents_can_also_handle_multiple_lines - long_string = < 0, :black => 30, :red => 31, - :green => 32, :yellow => 33, :blue => 34, - :magenta => 35, :cyan => 36, + clear: 0, black: 30, red: 31, + green: 32, yellow: 33, blue: 34, + magenta: 35, cyan: 36, } module_function @@ -146,7 +150,7 @@ def flunk(msg) end def assert(condition, msg=nil) - msg ||= "Failed assertion." + msg ||= 'Failed assertion.' flunk(msg) unless condition true end @@ -196,6 +200,7 @@ def assert_nothing_raised end end + # Class about sensei class Sensei attr_reader :failure, :failed_test, :pass_count @@ -270,7 +275,7 @@ def show_progress bar_width = 50 total_tests = Neo::Koan.total_tests scale = bar_width.to_f/total_tests - print Color.green("your path thus far [") + print Color.green('your path thus far [') happy_steps = (pass_count*scale).to_i happy_steps = 1 if happy_steps == 0 && pass_count > 0 print Color.green('.'*happy_steps) @@ -292,11 +297,11 @@ def end_screen end def boring_end_screen - puts "Mountains are again merely mountains" + puts 'Mountains are again merely mountains' end def artistic_end_screen - "JRuby 1.9.x Koans" + 'JRuby 1.9.x Koans' ruby_version = "(in #{'J' if defined?(JRUBY_VERSION)}Ruby #{defined?(JRUBY_VERSION) ? JRUBY_VERSION : RUBY_VERSION})" ruby_version = ruby_version.side_padding(54) completed = <<-ENDTEXT @@ -339,12 +344,12 @@ def artistic_end_screen def encourage puts - puts "The Master says:" - puts Color.cyan(" You have not yet reached enlightenment.") + puts 'The Master says:' + puts Color.cyan(' You have not yet reached enlightenment.') if ((recents = progress.last(5)) && recents.size == 5 && recents.uniq.size == 1) - puts Color.cyan(" I sense frustration. Do not be afraid to ask for help.") + puts Color.cyan(' I sense frustration. Do not be afraid to ask for help.') elsif progress.last(2).size == 2 && progress.last(2).uniq.size == 1 - puts Color.cyan(" Do not lose hope.") + puts Color.cyan(' Do not lose hope.') elsif progress.last.to_i > 0 puts Color.cyan(" You are progressing. Excellent. #{progress.last} completed.") end @@ -352,10 +357,10 @@ def encourage def guide_through_error puts - puts "The answers you seek..." + puts 'The answers you seek...' puts Color.red(indent(failure.message).join) puts - puts "Please meditate on the following code:" + puts 'Please meditate on the following code:' puts embolden_first_line_only(indent(find_interesting_lines(failure.backtrace))) puts end @@ -387,17 +392,17 @@ def find_interesting_lines(backtrace) # metakoans Ruby Quiz (http://rubyquiz.com/quiz67.html) def a_zenlike_statement if !failed? - zen_statement = "Mountains are again merely mountains" + zen_statement = 'Mountains are again merely mountains' else zen_statement = case (@pass_count % 10) when 0 - "mountains are merely mountains" + 'mountains are merely mountains' when 1, 2 - "learn the rules so you know how to break them properly" + 'learn the rules so you know how to break them properly' when 3, 4 - "remember that silence is sometimes the best answer" + 'remember that silence is sometimes the best answer' when 5, 6 - "sleep is the best meditation" + 'sleep is the best meditation' when 7, 8 "when you lose, don't lose the lesson" else diff --git a/path_to_enlightenment.rb b/path_to_enlightenment.rb index 9e8ccbe..205345c 100644 --- a/path_to_enlightenment.rb +++ b/path_to_enlightenment.rb @@ -12,7 +12,7 @@ require 'about_symbols' require 'about_regular_expressions' require 'about_methods' -in_ruby_version("2") do +in_ruby_version('2') do require 'about_keyword_arguments' end require 'about_constants' @@ -35,7 +35,7 @@ require 'about_message_passing' require 'about_proxy_object_project' require 'about_to_str' -in_ruby_version("jruby") do +in_ruby_version('jruby') do require 'about_java_interop' end require 'about_extra_credit' diff --git a/triangle.rb b/triangle.rb index 8df052a..a4a5218 100644 --- a/triangle.rb +++ b/triangle.rb @@ -13,8 +13,14 @@ # and # about_triangle_project_2.rb # -def triangle(a, b, c) +def triangle(a_side, b_side, c_side) # WRITE THIS CODE + a_side, b_side, c_side = [a_side, b_side, c_side].sort + raise TriangleError if (a_side <= 0) || (a_side + b_side <= c_side) + return :equilateral if a_side == c_side # proverka + return :isosceles if (a_side == b_side) || (b_side == c_side) + + :scalene end # Error class used in part 2. No need to change this code. diff --git a/versioning_spec.rb b/versioning_spec.rb index 44cc763..7d7d942 100644 --- a/versioning_spec.rb +++ b/versioning_spec.rb @@ -1,6 +1,6 @@ def version_ints(version) - version.split(".").map { |v| v.to_i } + version.split('.').map(&:to_i) end def at_least_ruby_version(version) @@ -9,21 +9,20 @@ def at_least_ruby_version(version) vints.zip(ruby_vints).all? { |v, rv| v.nil? || rv.nil? || v >= rv } end - require 'rspec/given' -describe "#version_ints" do - Then { version_ints("1.2") == [1, 2] } - Then { version_ints("2.1.20") == [2, 1, 20] } +describe '#version_ints' do + Then { version_ints('1.2') == [1, 2] } + Then { version_ints('2.1.20') == [2, 1, 20] } end -describe "at_least_ruby_version" do - Then { at_least_ruby_version("2") } - Then { at_least_ruby_version("2.0") } - Then { at_least_ruby_version("2.0.1") } - Then { at_least_ruby_version("2.1") } - Then { at_least_ruby_version("2.1.3.4.1") } +describe 'at_least_ruby_version' do + Then { at_least_ruby_version('2') } + Then { at_least_ruby_version('2.0') } + Then { at_least_ruby_version('2.0.1') } + Then { at_least_ruby_version('2.1') } + Then { at_least_ruby_version('2.1.3.4.1') } - Then { ! at_least_ruby_version("1.9") } - Then { ! at_least_ruby_version("1.9.9.9.9") } + Then { !at_least_ruby_version('1.9') } + Then { !at_least_ruby_version('1.9.9.9.9') } end