Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Rspec in one file like test/unit

When I have time I like to take on a challenge at codewars. Until now I used test/unit to do my unit testing but I would like to use Rspec now without changing my way of working. These are small methods/files/tests so I like to keep everything together in one script.

I run almost all of my code using Sublime Text and get the result in a window at the bottom of the editor.

Here my working test/unit example

require 'test/unit'

def anagrams(word, words)
  words.select { |w| w.chars.sort == word.chars.sort }
end

class MyTest < Test::Unit::TestCase
  def test_fail
    assert_equal(['aabb', 'bbaa'], anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) )
    assert_equal(['carer', 'racer'], anagrams('racer', ['crazer', 'carer', 'racar', 'caers', 'racer']) )
    assert_equal([], anagrams('laser', ['lazing', 'lazy',  'lacer']) )
  end
end

This gives in Sublime the following output

Loaded suite C:/Users/.../codewars/anagram
Started
.

Finished in 0.001 seconds.
------
1 tests, 3 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
------
1000.00 tests/s, 3000.00 assertions/s
[Finished in 0.3s]

And here what I tried for Rspec

require 'rspec'

describe "Anagrams" do
  def anagrams(word, words)
    words.select { |w| w.chars.sort == word.chars.sort }
  end

  it "should only match the anagrams" do
    anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) == ['aabb', 'bbaa']
  end
end

In Sublime text, I get no output, just a empty black window with the time it took to execute the script, if I use the console and run rspec anagram.rb I get

.

Finished in 0.001 seconds (files took 0.10601 seconds to load)
1 example, 0 failures

How do I have my code and test in the same file and do the test just by running the script in my Sublime Text editor (and get the output) and how could I better rephrase this test ?

like image 864
peter Avatar asked Mar 11 '23 02:03

peter


2 Answers

You just need to tell the RSpec::Core::Runner to run your spec.

Adding RSpec::Core::Runner.run([$__FILE__]) at the end of your fill should work.

Updated code:

require 'rspec'

describe "Anagrams" do
  def anagrams(word, words)
    words.select { |w| w.chars.sort == word.chars.sort }
  end

  it "should only match the anagrams" do
    anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada']) == ['aabb', 'bbaa']
  end
end

RSpec::Core::Runner.run([$__FILE__])
like image 158
Stanko Krtalić Rusendić Avatar answered Mar 19 '23 19:03

Stanko Krtalić Rusendić


I don't know what magic you used for sublime text to auto run your unit tests. What I can answer is how to phrase the test better.

require 'rspec'

def anagrams(word, words)
  words.select { |w| w.chars.sort == word.chars.sort }
end

RSpec.describe "Anagrams" do
  it "matches words that are anagrams" do
    # 2 different ways to do this
    expect(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada'])).to match_array(['aabb', 'bbaa'])
    expect(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada'])).to contain_exactly('aabb', 'bbaa')
  end
end

match_array & contain_exactly are identical, except that match_array needs 1 parameter: array and contain exactly needs no array, instead you list all memebers of array.

https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/contain-exactly-matcher

You could also break this into 2 or more specs if you want to. I'd do that if logic was more complicated. Going to do it here anyway so you can see more examples of rspec messages. Using should in spec name is no longer recommended.

RSpec.describe "Anagrams" do
  it "when no annagrams found returns empty array" do
    expect(anagrams('abba', ['abcd', 'dada'])).to eq([])
  end

  it "recognizes itself as annagram" do
    expect(anagrams('abba', ['abba'])).to eq(['abba'])
  end

  it "returns array containing words that are anagrams" do
    expect(anagrams('abba', ['aabb', 'abcd', 'bbaa', 'dada'])).to contain_exactly('aabb', 'bbaa')
  end
end
like image 21
Marko Avlijaš Avatar answered Mar 19 '23 21:03

Marko Avlijaš