1

At this moment i am learning ruby ,and i want to learn how to develop apps using rspec and BDD, but i never done any kind of testing before. Its hard for me to think in write behavior->make it direction. I have found some simple beginners tutorials for rspec but not helpful so much in my case where i have built small program without classes.

This is my code. Simple Cesar cipher rotational program. Fast brief...when user inputs ROT following with 0-26 and text for example "ROT24 some text" it checks if input is properly formated and within ranges ,and than rotates characters in text depending on that number after ROT word. Example ROT5 rotates characters for 5 spots in alphabetical order.

i=0
#check input

while true

puts
    if i>0
        puts "Wrong Entry Please Try Again!"

        puts "Input Decipher key in ROT0-ROT26 format and text to decipher using white space between. Example (ROT2 SomeText)"
        input=gets.chop

    else
        puts "Input Decipher key in ROT0-ROT26 format and text to decipher using white space between. Example (ROT2 SomeText)"
        input=gets.chop
        i+=1
    end

 break if input.match(/\AROT([0-9]|1[0-9]|2[0-6]) /) 

end



#splitting input
inputArray=input.split(" ",2)

inputFirstPart= inputArray[0]

inputKey=inputFirstPart[3..4].to_i

inputText= inputArray[1]

#cipher method
def rotate (str,num)

    alphabetLow = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
    alphabetUp = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
    second_step=str.tr(alphabetLow.join,alphabetLow.rotate(num).join)
    second_step.tr(alphabetUp.join,alphabetUp.rotate(num).join)

end
#output result 
print "Your result is: "
print rotate(inputText,inputKey)
puts

Can anyone (if have some spare time for this poor soul) write rspec test for this code so i can reverse engineer it? I have tried few things but most of all i am confused with user inputs, cos during test its asking me to actually do the input which makes no sense to me.

Thank you in advance.

2 Answers 2

3

First, let's refactor your code into its own class:

caesar.rb

class Caesar
  def self.rotate (str, num)
    alphabet_low = ('a'..'z').to_a # Shorthand for alphabet creation, thanks Ruby!
    alphabet_high = ('A'..'Z').to_a

    second_step = str.tr(alphabet_low.join, alphabet_low.rotate(num).join)
    second_step.tr(alphabet_high.join, alphabet_high.rotate(num).join)
  end
end

Next we need to install the rspec gem:

$ gem install rspec

Let's add a spec directory and create an rspec file in there:

spec/caesar_spec.rb

require_relative '../caesar'

describe Caesar do
  describe '.rotate' do
    context 'when number 0 is provided' do
      let(:number) { 0 }

      it 'returns the same text that is provided' do
        string = 'Hello World'
        expect(Caesar.rotate(string, number)).to eq('Hello World')
      end
    end

    context 'when number 1 is provided' do
      let(:number) { 1 }

      it 'encrypts the given string by rotating it a single character' do
        string = 'Hello World'
        expect(Caesar.rotate(string, number)).to eq('Ifmmp Xpsme')
      end
    end
  end
end

Now from the command line inside your project folder, just run rspec:

$ rspec

Which should result in:

..

Finished in 0.00222 seconds (files took 0.09387 seconds to load)
2 examples, 0 failures
Sign up to request clarification or add additional context in comments.

Comments

1

First, you're going to want to split out the part of the code that you're actually going to test into a separate file, which puts the code into a class. You can then require that code in the file you're running, accept data from the input, and pass that data to it. At the same time, the spec file will require the file as well, and run specs against the methods in the class. Might look something like:

rotator.rb:

class Rotator
    def rotate(str, num)
        #do stuff
    end
end

rotator_spec.rb

require_relative 'rotator'
describe Rotator do
    it 'rotates' do
        expect(described_class.new.rotate('a', 'b')).to eq 'result'
    end
end

run.rb

require_relative 'rotator'
rotator = Rotator.new
#do input stuff
puts rotator.rotate(inputText, inputKey)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.