/spec/brainfuck_spec.rb

https://github.com/seandmccarthy/rbfk · Ruby · 127 lines · 90 code · 24 blank · 13 comment · 1 complexity · 12f052992b4fad0643d3211bd539cf3a MD5 · raw file

  1. require File.expand_path(File.join('..', '..', 'lib', 'brain_fuck'), __FILE__)
  2. describe BrainFuck do
  3. describe "The Brain Fuck instruction set" do
  4. before :each do
  5. @bf = BrainFuck.new(StringIO.new(''))
  6. end
  7. it "should increment the value at the current memory location" do
  8. @bf.execute('+')
  9. expect(@bf.memory[0]).to eq 1
  10. end
  11. it "should decrement the value at the current memory location" do
  12. @bf.execute('-')
  13. expect(@bf.memory[0]).to eq -1
  14. end
  15. it "should increment the data pointer" do
  16. @bf.execute('>')
  17. expect(@bf.data_pointer).to eq 1
  18. end
  19. it "should decrement the data pointer" do
  20. @bf.execute('>')
  21. expect(@bf.data_pointer).to eq 1
  22. @bf.execute('<')
  23. expect(@bf.data_pointer).to eq 0
  24. end
  25. it "should read a char into the current memory location" do
  26. bf = BrainFuck.new(StringIO.new(''), input_stream: StringIO.new('A'))
  27. bf.execute(',')
  28. expect(bf.memory[0]).to eq 65
  29. end
  30. it "output the value at the current memory location" do
  31. output = StringIO.new
  32. bf = BrainFuck.new(StringIO.new(''), output_stream: output)
  33. bf.memory[0] = 65
  34. bf.execute('.')
  35. output.seek(0)
  36. expect(output.read).to eq 'A'
  37. end
  38. describe "loops" do
  39. it "should begin a loop when the current memory value is > 0" do
  40. @bf.execute('+')
  41. @bf.execute('[')
  42. expect(@bf.pointer_stack).to_not be_empty
  43. end
  44. it "should skip the loop when the current memory value is = 0" do
  45. expect(@bf).to receive(:matching_brace_position).and_return(1)
  46. @bf.execute('[')
  47. expect(@bf.pointer_stack).to eq []
  48. expect(@bf.instruction_pointer).to eq 1
  49. end
  50. it "should begin a new iteration when the current memory value is > 0" do
  51. # Increment current memory position
  52. @bf.execute('+')
  53. # Start loop
  54. @bf.instruction_pointer = 1
  55. @bf.execute('[')
  56. # The pointer stack should have (instruction_pointer - 1) pushed on
  57. expect(@bf.pointer_stack).to eq [0]
  58. # End of loop, should see memory position > zero, then
  59. # - pop the last value from pointer_stack
  60. # - instruction_pointer should be set to this value
  61. @bf.execute(']')
  62. expect(@bf.pointer_stack).to eq []
  63. expect(@bf.instruction_pointer).to eq 0
  64. end
  65. it "should finish iterating when the current memory value is = 0" do
  66. # Increment current memory position
  67. @bf.execute('+')
  68. # Start loop
  69. @bf.instruction_pointer = 1
  70. @bf.execute('[')
  71. # The pointer stack should have (instruction_pointer - 1) pushed on
  72. expect(@bf.pointer_stack).to eq [0]
  73. # Decrement current memory position, making it zero
  74. @bf.execute('-')
  75. # End of loop, should notice memory position is zero, then
  76. # - pop the last value from pointer_stack
  77. # - instruction_pointer should (remain) at index for ']' in @program
  78. @bf.instruction_pointer = 3
  79. @bf.execute(']')
  80. expect(@bf.pointer_stack).to eq []
  81. expect(@bf.instruction_pointer).to eq 3
  82. end
  83. it "should permit nested loops" do
  84. end
  85. it "should raise an exception for mismatched braces" do
  86. expect { @bf.execute(']') }.to raise_error 'Bracket mismatch'
  87. end
  88. end
  89. end
  90. describe "running programs" do
  91. it "should indicate when a program execution should end" do
  92. @bf = BrainFuck.new(StringIO.new(''))
  93. expect(@bf.ended?).to be false
  94. @bf.next_instruction
  95. expect(@bf.ended?).to be true
  96. end
  97. end
  98. describe "Translating and executing other dialects" do
  99. it 'translate brainfuck to Ook' do
  100. expect(BrainFuck.bf_to_ook('-')).to eq 'Ook! Ook!'
  101. end
  102. end
  103. end