Search code examples
rubytestingrspecbdd

Testing ruby program with rspec


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.


Solution

  • 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