# Input / Output Tests

This is an example of how you can mock input values and test the output stream of student code.&#x20;

The student must use the `puts` function to prompt the user for their first name, then use `gets.chomp` to collect the first name without a newline attached, and again for their last name.  Then, print `Hello, firstname lastname!` including the person's first and last name.&#x20;

**Sample Run:**

```
What is your first name?
Jane
What is your last name?
Doe
Hello, Jane Doe!
```

It assumes the student's file name is `example.rb`.  Replace the `require` with whatever your student's file name is.&#x20;

*Note: This code converts the output to all lowercase and removes spaces to compare against the correct value.*

#### **Grading Tests:**

```ruby
require 'rspec'
require 'stringio'

student_code = File.read("/usercode/example.rb") 
new_student_code = student_code.gsub(" gets", " $stdin.gets") 
File.open("/usercode/example.rb", "w") do |f|
  f.write(new_student_code)
end

RSpec.describe "CodingRoomsUnitTests" do

    describe 'Giving code Jane and Doe as inputs' do
        it "output should equal 'Hello, Jane Doe!'" do
            input = StringIO.new()
            output = StringIO.new()
            input.puts "Jane"
            input.puts "Doe"
            input.rewind
            $stdin = input
            $stdout = output
            load '/usercode/example.rb'
            expect(output.string).to include("Hello, Jane Doe!")
            $stdin = STDIN
            $stdout = STDOUT
        end
    end

    describe 'Giving code Joe and Mazzone as inputs' do
        it "output should equal 'Hello, Joe Mazzone!'" do
            input = StringIO.new()
            output = StringIO.new()
            input.puts "Joe"
            input.puts "Mazzone"
            input.rewind
            $stdin = input
            $stdout = output
            load '/usercode/example.rb'
            expect(output.string).to include("Hello, Joe Mazzone!")
            $stdin = STDIN
            $stdout = STDOUT
        end
    end

end
```

RSpec, the unit testing framework we are using, seems to have a hard time replacing the standard input stream.  That is why you see this code at the beginning of our test file.

```ruby
student_code = File.read("/usercode/example.rb") 
new_student_code = student_code.gsub(" gets", " $stdin.gets") 
File.open("/usercode/example.rb", "w") do |f|
  f.write(new_student_code)
end
```

To allow RSpec to load a new standard input stream, we need to replace all instances of `gets` and use `$stdin.gets`. Instead of teaching students to not use `gets` and always use `$stdin.gets`, we can simply add the above code to replace all instances of `gets` with `$stdin.gets`.

***Note:** On Coding Rooms, the testing instance copies the student code so the above doesn't actually modify the student submission, it just changes it for the test.  Other platforms or your local may behave differently.*

#### Sample Solution:

{% code title="example.rb" %}

```ruby
puts 'What is your first name?'
firstname = gets.chomp

puts 'What is your last name?'
lastname = gets.chomp

puts 'Hello, ' + firstname + " " + lastname + "!"
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://auto-grade.joemazzone.net/ruby-examples/input-output-tests.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
