Obed Lorisson
Obed Lorisson

Reputation: 449

implementation issue of a rspec test in ruby

i have this test in ruby I'm trying to implement require "silly_blocks"

describe "some silly block functions" do

  describe "reverser" do
    it "reverses the string returned by the default block" do
      result = reverser do
        "hello"
      end
      result.should == "olleh"
    end

    it "reverses each word in the string returned by the default block" do
      result = reverser do
        "hello dolly"
      end
      result.should == "olleh yllod"
    end
  end

here's the method

def do_reverse(str)
 str = str.split 
 first_str = str[0].reverse
 second_str= str[1]
 if (second_str == nil)
  str = first_str.to_s
 else
 second_str = str[1].reverse
 str = (first_str +" "+ second_str)
 end 
end 

what is the best way that i could implement it . when i try to rake the test it failed , but the method by itself return the reserve. i'm just a little confused.

Upvotes: 2

Views: 1282

Answers (5)

Roman Davis
Roman Davis

Reputation: 351

So. I came here looking for information on how to do this also. As the language wasn't clear. I went and looked offsite, and found enough information to pass the tests.

So, blocks are those things between curly braces that sometimes follow functions in ruby, such as

list.each {|i| i.reverse}

So what the spec is doing is trying to figure out what happens when it does:

rerverser {"hello"}

Putting yield in a function just returns whatever is in the block, so

def print_block
    puts yield
end

print_block {"Hello world."}

#=> "Hello world"

Then you can just manipulate yield like you would manipulate any argument. There's a lot more to blocks. Here's a good place to start, but that's all you need to know to solve the exercise if you've solved all of Test First's learn_ruby exercises up until now.

Upvotes: 0

Connor Leech
Connor Leech

Reputation: 18833

My reverser method:

def reverser
    # yield is the string given in the block
    words = yield.split(' ')
    final = []
    words.each do |word|
        final.push(word.reverse)
    end
    final.join(' ')
end

Upvotes: 0

hken27
hken27

Reputation: 413

Try this code:

def reverser

   yield.split.map { |word| word.reverse}.join(" ")

end

Upvotes: 2

D3RPZ1LLA
D3RPZ1LLA

Reputation: 281

This works. The data you want is stored in "yield".

def reverser
  yield.gsub(/\w+/) { |w| w.each_char.to_a.reverse.join }
end

Upvotes: 0

cfeduke
cfeduke

Reputation: 23226

Here's an easy way of doing what you're looking for, with specs.

# lib/reverse_words.rb
def reverse_words(phrase)
  return '' if phrase.nil?
  words = phrase.split
  phrase.split.map(&:reverse!).join(' ')
end

def reverser
  reverse_words(yield)
end

# spec/reverse_words_spec.rb
describe "#reverse_words" do
  context "when single word" do
    subject { reverse_words("hello") }
    it { should == "olleh" }
  end

  context "when multiple words" do
    subject { reverse_words("hello dolly") }
    it { should == "olleh yllod" }
  end

  context "when nil" do
    subject { reverse_words(nil) }
    it { should == '' }
  end

  context "when empty" do
    subject { reverse_words('') }
    it { should == '' }
  end

end

Note that the reverser spec simply makes use of the behavior that reverse_words has already been specced to pass.

describe "#reverser" do
  subject do
    reverser do
      "this is a test"
    end
  end
  it { should == reverse_words("this is a test") }
end

Here's a less wordy reverse_words spec:

describe "#reverse_words (less wordy)" do
  # counterintuitive keys as answers to support the nil case
  cases = { "olleh" => "hello",
      "olleh yllod" => "hello dolly",
      ''            => nil,
      ''            => ''
    }

  cases.each_pair do |expected, input| 
    context "#{input} should equal #{expected}" do
      subject { reverse_words(input) }
      it { should == expected }
    end
  end
end

Upvotes: 1

Related Questions