気になったので書いてみる
RSpec の shared examples に適用できそうだったから書いたというのはナイショ
仕様
質問文に書かれていた仕様は以下の通り
start:2:、 end: 6
start:6:、 end: 7
start:6:、 end: 9
はfalseです
なので、それに沿ったテストコードを書いていく
テストコードを書く
まずはテストを書く (今回は RSpec で書く)
テストをパスするコードはこんなふうに動いて欲しい
- 始点と終点、2つの数値を保持できる
- また、別の範囲と自身とを比較して、自身がその範囲に含まれているか否かを判定できる
「こういう実装になれば実際に使用する時に楽だなあ」みたいに理想像を考えて書く
shared_examples 'line cover?' do |start, _end| it "start:#{start}, end:#{_end}" do line2 = Line.new(start: start, end: _end) expect(line.cover?(line2)).to be_falsy end end describe 'Line' do context 'start:2, end:4' do let(:line) { Line.new(start: 2, end: 4) } context 'will got false result that compared by' do include_examples 'line cover?', 2, 6 include_examples 'line cover?', 6, 7 include_examples 'line cover?', 6, 9 end end end
上はリファクタリングをしたあとのテストコード
愚直にテストコードを書いてみると、テスト対象とする部分が、 start
と end
の数値以外変わっていないことに気づく、ので書き換えた
(ここで一応、テストコードを書いたあとに、Ruby のコードとしてエラー無く動いてくれていること、テスト対象をまだ書いていないので全落ちすることを、テストの実行をして確認した)
実装を書く
Line = Struct.new(:start, :end, keyword_init: true) do def cover?(line) start <= line.start && self.end >= line.end end end
とくに複雑なことをする必要もなく、2つの数値を保持できればいいので Struct で定義した
比較に関しても、自身と同じ Struct をもらって比較できればいい
Ruby 2.5 からは keyword_init
オプションが指定可能になったので利用している
結果
テスト結果がグリーンになったことが確認できた:
Links
- guard/guard: Guard is a command line tool to easily handle events on file system modifications. - GitHub
- guard/guard-rspec: Guard::RSpec automatically run your specs (much like autotest) - GitHub
- rspec/rspec: RSpec meta-gem that depends on the other components - GitHub
- shared examples - Example groups - RSpec Core - RSpec - Relish
- Class: Struct (Ruby 2.5.0) - ruby-doc.org
- TDD のこころ - SlideShare
- テスト駆動開発 | Kent Beck, 和田 卓人 - Amazon