diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/ActivitySummary_spec.rb | 19 | ||||
-rw-r--r-- | spec/FitFileStore_spec.rb | 133 | ||||
-rw-r--r-- | spec/FlexiTable_spec.rb | 2 | ||||
-rw-r--r-- | spec/PersonalRecords_spec.rb | 206 | ||||
-rw-r--r-- | spec/PostRunner_spec.rb | 81 | ||||
-rw-r--r-- | spec/View_spec.rb | 2 | ||||
-rw-r--r-- | spec/spec_helper.rb | 71 |
7 files changed, 453 insertions, 61 deletions
diff --git a/spec/ActivitySummary_spec.rb b/spec/ActivitySummary_spec.rb index b3d77b0..f949a8d 100644 --- a/spec/ActivitySummary_spec.rb +++ b/spec/ActivitySummary_spec.rb @@ -18,16 +18,27 @@ end describe PostRunner::ActivitySummary do + before(:all) do + capture_stdio + create_working_dirs + create_fit_file_store + end + before(:each) do - fa = create_fit_activity('2014-08-26-19:00', 30) - a = Activity.new(fa, 'running') - @as = PostRunner::ActivitySummary.new(a, :metric, + acfg = { :t => '2014-08-26T19:00', :duration => 30, :serial => 123456790 } + fn = create_fit_activity_file(@fit_dir, acfg) + fa = @ffs.add_fit_file(fn) + @as = PostRunner::ActivitySummary.new(fa, :metric, { :name => 'test', :type => 'Running', :sub_type => 'Street' }) end + after(:all) do + cleanup + end + it 'should create a metric summary' do - puts @as.to_s #TODO: Fix aggregation first + @as.to_s #TODO: Fix aggregation first end end diff --git a/spec/FitFileStore_spec.rb b/spec/FitFileStore_spec.rb new file mode 100644 index 0000000..91797aa --- /dev/null +++ b/spec/FitFileStore_spec.rb @@ -0,0 +1,133 @@ +#!/usr/bin/env ruby -w +# encoding: UTF-8 +# +# = PostRunner_spec.rb -- PostRunner - Manage the data from your Garmin sport devices. +# +# Copyright (c) 2014, 2015, 2016 by Chris Schlaeger <cs@taskjuggler.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# + +require 'spec_helper' + +require 'fit4ruby/FileNameCoder' +require 'postrunner/RuntimeConfig' +require 'postrunner/FitFileStore' +require 'postrunner/PersonalRecords' + +describe PostRunner::FitFileStore do + + before(:all) do + capture_stdio + create_working_dirs + create_fit_file_store + + # Create some test fit files + @fit_file_names = [] + [ + { :t => '2015-10-21T21:00', :duration => 10, :serial => 123456790 }, + { :t => '2015-10-22T08:10', :duration => 15, :serial => 123456791 }, + { :t => '2015-11-01T13:30', :duration => 20, :serial => 123456790 } + ].each do |config| + f = create_fit_activity_file(@fit_dir, config) + @fit_file_names << f + end + @activities = [] + end + + after(:all) do + cleanup + end + + it 'should be empty at start' do + expect(@ffs.devices.length).to eq(0) + expect(@ffs.activities.length).to eq(0) + end + + it 'should store a FIT file' do + @activities << @ffs.add_fit_file(@fit_file_names[0]) + expect(@activities[-1]).not_to be_nil + + expect(@ffs.devices.length).to eq(1) + expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true + expect(@ffs.activities.length).to eq(1) + expect(@ffs.ref_by_activity(@activities[0])).to eq(1) + end + + it 'should not store the same FIT file twice' do + expect(@ffs.add_fit_file(@fit_file_names[0])).to be_nil + + expect(@ffs.devices.length).to eq(1) + expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true + expect(@ffs.activities.length).to eq(1) + end + + it 'should store another FIT file as 2nd device' do + @activities << @ffs.add_fit_file(@fit_file_names[1]) + expect(@activities[-1]).not_to be_nil + + expect(@ffs.devices.length).to eq(2) + expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true + expect(@ffs.devices.include?('garmin-fenix3-123456791')).to be true + expect(@ffs.activities.length).to eq(2) + expect(@ffs.ref_by_activity(@activities[1])).to eq(1) + end + + it 'should store another activity of a known device' do + @activities << @ffs.add_fit_file(@fit_file_names[2]) + expect(@activities[-1]).not_to be_nil + + expect(@ffs.devices.length).to eq(2) + expect(@ffs.devices.include?('garmin-fenix3-123456790')).to be true + expect(@ffs.devices.include?('garmin-fenix3-123456791')).to be true + expect(@ffs.activities.length).to eq(3) + expect(@ffs.ref_by_activity(@activities[2])).to eq(1) + end + + it 'should find activities by index' do + expect(@ffs.find('0')).to eq([]) + expect(@ffs.find('1')).to eq([ @activities[2] ]) + expect(@ffs.find('2')).to eq([ @activities[1] ]) + expect(@ffs.find('3')).to eq([ @activities[0] ]) + expect(@ffs.find('1-2')).to eq([ @activities[2], @activities[1] ]) + expect(@ffs.find('2-1')).to eq([]) + expect(@ffs.find('')).to eq([]) + end + + it 'should check all stored fit files' do + @ffs.check + end + + it 'should know the successor of each activity' do + expect(@ffs.successor(@activities[2])).to be_nil + expect(@ffs.successor(@activities[1])).to eq(@activities[2]) + expect(@ffs.successor(@activities[0])).to eq(@activities[1]) + end + + it 'should know the predecessor of each activity' do + expect(@ffs.predecessor(@activities[2])).to eq(@activities[1]) + expect(@ffs.predecessor(@activities[1])).to eq(@activities[0]) + expect(@ffs.predecessor(@activities[0])).to be_nil + end + + it 'should delete activities' do + @ffs.delete_activity(@activities[1]) + expect(@ffs.find('1')).to eq([ @activities[2] ]) + expect(@ffs.find('2')).to eq([ @activities[0] ]) + expect(@ffs.find('3')).to eq([]) + + @ffs.delete_activity(@activities[2]) + expect(@ffs.find('1')).to eq([ @activities[0] ]) + expect(@ffs.find('2')).to eq([]) + end + + it 'should rename an activity' do + @ffs.rename_activity(@activities[0], 'new name') + expect(@activities[0].name).to eq('new name') + expect(@activities[0].fit_file_name).to eq(File.basename(@fit_file_names[0])) + end + +end + diff --git a/spec/FlexiTable_spec.rb b/spec/FlexiTable_spec.rb index c3357cd..9b67ec6 100644 --- a/spec/FlexiTable_spec.rb +++ b/spec/FlexiTable_spec.rb @@ -26,7 +26,7 @@ describe PostRunner::FlexiTable do |ccc|ddddd| +---+-----+ EOT - t.to_s.should == ref + expect(t.to_s).to eq(ref) end end diff --git a/spec/PersonalRecords_spec.rb b/spec/PersonalRecords_spec.rb new file mode 100644 index 0000000..c23010b --- /dev/null +++ b/spec/PersonalRecords_spec.rb @@ -0,0 +1,206 @@ +#!/usr/bin/env ruby -w +# encoding: UTF-8 +# +# = PostRunner_spec.rb -- PostRunner - Manage the data from your Garmin sport devices. +# +# Copyright (c) 2014, 2015, 2016 by Chris Schlaeger <cs@taskjuggler.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# + +require 'spec_helper' +require 'perobs' + +require 'fit4ruby/FileNameCoder' +require 'postrunner/FitFileStore' +require 'postrunner/PersonalRecords' + +describe PostRunner::PersonalRecords do + + class Mock_Activity < PEROBS::Object + + po_attr :name, :fit_file_name + + def initialize(store, name = nil) + super(store) + init_attr(:name, name) + init_attr(:fit_file_name, name) + end + + end + + class Mock_FitFileStore < PEROBS::Object + + po_attr :activities + + def initialize(store) + super + init_attr(:activities, @store.new(PEROBS::Array)) + end + + def add_activity(a) + @activities << a + end + + def ref_by_activity(a) + @activities.index(a) + 1 + end + + end + + before(:all) do + @log = StringIO.new + Fit4Ruby::Log.open(@log) + @work_dir = tmp_dir_name(__FILE__) + Dir.mkdir(@work_dir) + + # Create the FitFileStore + @store = PEROBS::Store.new(File.join(@work_dir, 'db')) + @store['config'] = @store.new(PEROBS::Hash) + @store['config']['data_dir'] = @work_dir + @ffs = @store['file_store'] = @store.new(Mock_FitFileStore) + @records = @store['records'] = @store.new(PostRunner::PersonalRecords) + end + + after(:all) do + FileUtils.rm_rf(@work_dir) + end + + it 'should initialize properly' do + expect(@records.to_s).to eq('') + end + + it 'should register a record' do + a = @store.new(Mock_Activity, 'Activity 1') + @ffs.add_activity(a) + t = Time.parse('2014-11-08T09:16:00') + expect(@records.register_result(a, 'running', 5000.0, 20 * 60, + t)).to be true + expect(@records.register_result(a, 'running', 5000.0, nil, t)).to be true + expect(@records.activity_records(a).length).to eq(4) + expect(tables_to_arrays(@records.to_s)).to eq([ + [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"], + ["Longest Distance", "5.000 km", "-", "1", "Activity 1", "2014-11-08"]], + [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"], + ["Longest Distance", "5.000 km", "-", "1", "Activity 1", "2014-11-08"]] + ]) + end + + it 'should register another record' do + a = @store.new(Mock_Activity, 'Activity 2') + @ffs.add_activity(a) + t = Time.parse('2014-11-09T09:16:00') + expect(@records.register_result(a, 'running', 10000.0, + 42 * 60, t)).to be true + expect(@records.register_result(a, 'running', 10000.0, + nil, t)).to be true + expect(@records.activity_records(a).length).to eq(4) + expect(tables_to_arrays(@records.to_s)).to eq([ + [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"], + ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + [["5 km", "0:20:00", "4:00", "1", "Activity 1", "2014-11-08"], + ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + ]) + end + + it 'should replace an old record with a new one' do + a = @store.new(Mock_Activity, 'Activity 3') + @ffs.add_activity(a) + t = Time.parse('2014-11-11T09:16:00') + expect(@records.register_result(a, 'running', 5000.0, + 19 * 60, t)).to be true + expect(@records.activity_records(a).length).to eq (2) + expect(@records.activity_records(@ffs.activities[0]).length).to eq(0) + expect(tables_to_arrays(@records.to_s)).to eq([ + [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"], + ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"], + ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + ]) + end + + it 'should add a new table for a new year' do + a = @store.new(Mock_Activity, 'Activity 4') + @ffs.add_activity(a) + t = Time.parse('2015-01-01T06:00:00') + expect(@records.register_result(a, 'running', 5000.0, + 21 * 60, t)).to be true + expect(@records.activity_records(a).length).to eq(1) + expect(tables_to_arrays(@records.to_s)).to eq([ + [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"], + ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + [["5 km", "0:21:00", "4:12", "4", "Activity 4", "2015-01-01"]], + [["5 km", "0:19:00", "3:47", "3", "Activity 3", "2014-11-11"], + ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + ]) + end + + it 'should not add a new record for poor result' do + a = @store.new(Mock_Activity, 'Activity 5') + @ffs.add_activity(a) + t = Time.parse('2015-01-02T10:00:00') + expect(@records.register_result(a, 'running', 5000.0, 22 * 60, + t)).to be false + expect(@records.activity_records(a).length).to eq(0) + end + + it 'should not delete a record for non-record activity' do + expect(@records.delete_activity(@ffs.activities[0])).to be false + end + + it 'should delete a record for a record activity' do + expect(@records.delete_activity(@ffs.activities[2])).to be true + expect(tables_to_arrays(@records.to_s)).to eq([ + [["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + [["5 km", "0:21:00", "4:12", "4", "Activity 4", "2015-01-01"]], + [["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + ]) + end + + it 'should add a new distance record' do + a = @store.new(Mock_Activity, 'Activity 6') + @ffs.add_activity(a) + t = Time.parse('2015-01-10T07:00:00') + expect(@records.register_result(a, 'running', 15000.0, nil, t)).to be true + expect(@records.activity_records(a).length).to eq(2) + expect(tables_to_arrays(@records.to_s)).to eq([ + [ ["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "15.000 km", "-", "6", "Activity 6", "2015-01-10"]], + [["5 km", "0:21:00", "4:12", "4", "Activity 4", "2015-01-01"], + ["Longest Distance", "15.000 km", "-", "6", "Activity 6", "2015-01-10"]], + [["10 km", "0:42:00", "4:12", "2", "Activity 2", "2014-11-09"], + ["Longest Distance", "10.000 km", "-", "2", "Activity 2", "2014-11-09"]], + ]) + end + + it 'should not register a record for a bogus sport' do + a = @store.new(Mock_Activity, 'Activity 5') + @ffs.add_activity(a) + t = Time.parse('2015-04-01T11:11:11') + expect(@records.register_result(a, 'foobaring', 5000.0, 10 * 60, + t)).to be false + end + + it 'should not register a record for unknown distance' do + a = @store.new(Mock_Activity, 'Activity 6') + @ffs.add_activity(a) + expect { @records.register_result(a, 'cycling', 42.0, 10 * 60, + Time.parse('2015-04-01T11:11:11'))}.to raise_error(Fit4Ruby::Error) + end + + it 'should delete all records' do + @records.delete_all_records + expect(@records.to_s).to eq('') + end + +end diff --git a/spec/PostRunner_spec.rb b/spec/PostRunner_spec.rb index f4dd33b..24ae0fa 100644 --- a/spec/PostRunner_spec.rb +++ b/spec/PostRunner_spec.rb @@ -3,7 +3,7 @@ # # = PostRunner_spec.rb -- PostRunner - Manage the data from your Garmin sport devices. # -# Copyright (c) 2014 by Chris Schlaeger <cs@taskjuggler.org> +# Copyright (c) 2014, 2015, 2016 by Chris Schlaeger <cs@taskjuggler.org> # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as @@ -21,14 +21,15 @@ describe PostRunner::Main do args = [ '--dbdir', @db_dir ] + args old_stdout = $stdout $stdout = (stdout = StringIO.new) - PostRunner::Main.new(args) + @postrunner = PostRunner::Main.new(args) $stdout = old_stdout stdout.string end before(:all) do - @work_dir = tmp_dir_name(__FILE__) - Dir.mkdir(@work_dir) + capture_stdio + create_working_dirs + @db_dir = File.join(@work_dir, '.postrunner') @file1 = File.join(@work_dir, 'FILE1.FIT') @file2 = File.join(@work_dir, 'FILE2.FIT') @@ -37,15 +38,15 @@ describe PostRunner::Main do end after(:all) do - FileUtils.rm_rf(@work_dir) + cleanup end it 'should abort without arguments' do - lambda { postrunner([]) }.should raise_error Fit4Ruby::Error + expect { postrunner([]) }.to raise_error(Fit4Ruby::Error) end it 'should abort with bad command' do - lambda { postrunner(%w( foobar)) }.should raise_error Fit4Ruby::Error + expect { postrunner(%w( foobar)) }.to raise_error(Fit4Ruby::Error) end it 'should support the -v option' do @@ -73,62 +74,53 @@ describe PostRunner::Main do end it 'should list the imported file' do - postrunner(%w( list )).index('FILE1').should be_a(Fixnum) + expect(postrunner(%w( list )).index('FILE1')).to be_a(Fixnum) end it 'should import the other FIT file' do postrunner([ 'import', @work_dir ]) list = postrunner(%w( list )) - list.index('FILE1.FIT').should be_a(Fixnum) - list.index('FILE2.FIT').should be_a(Fixnum) - rc = YAML::load_file(File.join(@db_dir, 'config.yml')) - rc[:import_dir].should == @work_dir - - template = "<a href=\"%s.html\"><img src=\"icons/%s.png\" " + - "class=\"active_button\">" - html1 = File.read(File.join(@db_dir, 'html', 'FILE1.html')) - html1.include?(template % ['FILE2', 'forward']).should be_true - html2 = File.read(File.join(@db_dir, 'html', 'FILE2.html')) - html2.include?(template % ['FILE1', 'back']).should be_true + expect(list.index('FILE1.FIT')).to be_a(Fixnum) + expect(list.index('FILE2.FIT')).to be_a(Fixnum) end it 'should delete the first file' do postrunner(%w( delete :2 )) list = postrunner(%w( list )) - list.index('FILE1.FIT').should be_nil - list.index('FILE2.FIT').should be_a(Fixnum) + expect(list.index('FILE1.FIT')).to be_nil + expect(list.index('FILE2.FIT')).to be_a(Fixnum) end it 'should not import the deleted file again' do postrunner(%w( import . )) list = postrunner(%w( list )) - list.index('FILE1.FIT').should be_nil - list.index('FILE2.FIT').should be_a(Fixnum) + expect(list.index('FILE1.FIT')).to be_nil + expect(list.index('FILE2.FIT')).to be_a(Fixnum) end it 'should rename FILE2.FIT activity' do postrunner(%w( rename foobar :1 )) list = postrunner(%w( list )) - list.index(@file2).should be_nil - list.index('foobar').should be_a(Fixnum) + expect(list.index('FILE2.FIT')).to be_nil + expect(list.index('foobar')).to be_a(Fixnum) end it 'should fail when setting bad attribute' do - lambda { postrunner(%w( set foo bar :1)) }.should raise_error Fit4Ruby::Error + expect { postrunner(%w( set foo bar :1)) }.to raise_error(Fit4Ruby::Error) end it 'should set name for FILE2.FIT activity' do postrunner(%w( set name foobar :1 )) list = postrunner(%w( list )) - list.index(@file2).should be_nil - list.index('foobar').should be_a(Fixnum) + expect(list.index(@file2)).to be_nil + expect(list.index('foobar')).to be_a(Fixnum) end it 'should set activity type for FILE2.FIT activity' do postrunner(%w( set type Cycling :1 )) list = postrunner(%w( summary :1 )) - list.index('Running').should be_nil - list.index('Cycling').should be_a(Fixnum) + expect(list.index('Running')).to be_nil + expect(list.index('Cycling')).to be_a(Fixnum) end it 'should list the events of an activity' do @@ -140,18 +132,18 @@ describe PostRunner::Main do end it 'should fail when setting bad activity type' do - lambda { postrunner(%w( set type foobar :1)) }.should raise_error Fit4Ruby::Error + expect { postrunner(%w( set type foobar :1)) }.to raise_error(Fit4Ruby::Error) end it 'should set activity subtype for FILE2.FIT activity' do postrunner(%w( set subtype Road :1 )) list = postrunner(%w( summary :1 )) - list.index('Generic').should be_nil - list.index('Road').should be_a(Fixnum) + expect(list.index('Generic')).to be_nil + expect(list.index('Road')).to be_a(Fixnum) end it 'should fail when setting bad activity subtype' do - lambda { postrunner(%w( set subtype foobar :1)) }.should raise_error Fit4Ruby::Error + expect { postrunner(%w( set subtype foobar :1)) }.to raise_error(Fit4Ruby::Error) end it 'should dump an activity from the archive' do @@ -170,26 +162,5 @@ describe PostRunner::Main do postrunner(%w( units metric )) end - it 'should properly upgrade to a new version' do - # Change version in config file to 0.0.0. - rc = PostRunner::RuntimeConfig.new(@db_dir) - rc.set_option(:version, '0.0.0') - # Check that the config file really was changed. - rc = PostRunner::RuntimeConfig.new(@db_dir) - rc.get_option(:version).should == '0.0.0' - - archive_file = File.join(@db_dir, 'archive.yml') - archive = YAML.load_file(archive_file) - archive.each { |a| a.remove_instance_variable:@sport } - File.write(archive_file, archive.to_yaml) - - # Run some command. - postrunner(%w( list )) - - # Check that version matches the current version again. - rc = PostRunner::RuntimeConfig.new(@db_dir) - rc.get_option(:version).should == PostRunner::VERSION - end - end diff --git a/spec/View_spec.rb b/spec/View_spec.rb index 538b71f..79c95a9 100644 --- a/spec/View_spec.rb +++ b/spec/View_spec.rb @@ -52,7 +52,7 @@ module PostRunner pages.current_page = file PostRunner::View.new("Test File: #{file}", views, pages).body. write(file) - File.exists?(file).should be true + expect(File.exists?(file)).to be true end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dbb1e0e..dba6be6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -19,6 +19,16 @@ require 'fileutils' $:.unshift(File.join(File.dirname(__FILE__), '..', '..', lib_dir, 'lib')) end +require 'fit4ruby' +require 'perobs' +require 'postrunner/FitFileStore' +require 'postrunner/PersonalRecords' + +def capture_stdio + @log = StringIO.new + Fit4Ruby::Log.open(@log) +end + def tmp_dir_name(caller_file) begin dir_name = File.join(Dir.tmpdir, @@ -28,6 +38,29 @@ def tmp_dir_name(caller_file) dir_name end +def create_working_dirs + @work_dir = tmp_dir_name(__FILE__) + Dir.mkdir(@work_dir) + @fit_dir = File.join(@work_dir, 'fit') + Dir.mkdir(@fit_dir) + @html_dir = File.join(@work_dir, 'html') + Dir.mkdir(@html_dir) +end + +def cleanup + FileUtils.rm_rf(@work_dir) +end + +def create_fit_file_store + store = PEROBS::Store.new(File.join(@work_dir, 'db')) + store['config'] = store.new(PEROBS::Hash) + store['config']['data_dir'] = @work_dir + store['config']['html_dir'] = @html_dir + store['config']['unit_system'] = :metric + @ffs = store['file_store'] = store.new(PostRunner::FitFileStore) + @records = store['records'] = store.new(PostRunner::PersonalRecords) +end + def create_fit_file(name, date, duration_minutes = 30) Fit4Ruby.write(name, create_fit_activity( { :t => date, :duration => duration_minutes })) @@ -112,4 +145,42 @@ def create_fit_activity(config) a end +def tables_to_arrays(str) + mode = :searching_table + arrays = [] + array = [] + str.each_line do |line| + case mode + when :searching_table + if line[0] == '+' + mode = :header + end + when :header + if line[0] == '|' + mode = :separation_line + else + mode = :searching_table + end + when :separation_line + if line[0] == '+' + mode = :body + else + mode = :searching_table + end + when :body + if line[0] == '|' + array << line[1..-3].split('|').map(&:strip) + elsif line[0] == '+' + arrays << array + array = [] + mode = :searching_table + else + array = [] + mode = :searching_table + end + end + end + + arrays +end |