The team I work with is hiring and I thought I’d attempt the code challenge they’re using for candidates.

The requirements include simulating a popular card game, and reporting statistics on the average number of hands and time it takes to complete a game.

As I pondered how to begin, I realized that I don’t really know how a Ruby project is supposed to be structured. What is the equivalent of “mvn archetype:create …” from Java and Maven? Where do you put your code and your tests? What else is typically in there?

A few ideas from searching…

I settled on creating a gem by executing…

$ bundle gem mygame
      create  mygame/Gemfile
      create  mygame/Rakefile
      create  mygame/LICENSE.txt
      create  mygame/README.md
      create  mygame/.gitignore
      create  mygame/mygame.gemspec
      create  mygame/lib/mygame.rb
      create  mygame/lib/mygame/version.rb
Initializing git repo in /Users/wsmoak/projects/mygame
$

Interesting! My next step was going to be to get this under version control, but it looks like that’s already done.

$ cd mygame/
$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached [file]..." to unstage)

	new file:   .gitignore
	new file:   Gemfile
	new file:   LICENSE.txt
	new file:   README.md
	new file:   Rakefile
	new file:   lib/mygame.rb
	new file:   lib/mygame/version.rb
	new file:   mygame.gemspec

$ 

The git repository has been initialized and the files have been added, all that remains is to commit:

$ git commit -m "Add initial project structure from 'bundle gem mygame'"
[master (root-commit) d9b1ec0] Add initial project structure from 'bundle gem mygame'
 8 files changed, 104 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 Gemfile
 create mode 100644 LICENSE.txt
 create mode 100644 README.md
 create mode 100644 Rakefile
 create mode 100644 lib/mygame.rb
 create mode 100644 lib/mygame/version.rb
 create mode 100644 mygame.gemspec
$ 

It just needs a little cleanup to capitalize MyGame properly and fix the version number so that we do not build a ‘real’ version over and over locally. From prerelease-gems it looks like .pre is the convention, so we’ll go with that. (This appears to be roughly the equivalent of the -SNAPSHOT suffix that Maven uses on version numbers in Java projects.)

So that gets me a project structure and a hint about where my project code should go (in the lib directory) but there’s nothing here about tests.

I’m pretty sure I want to use RSpec, and a quick search turns up https://relishapp.com/rspec/rspec-core/v/3-2/docs/command-line and

$ rspec --init
  create   spec/spec_helper.rb
  create   .rspec
$

A bit more clicking around leads me to believe I need a spec/mygame_spec.rb file, so I’ll add that, with the contents…

describe MyGame do

end

Now how to run it? Just running rspec complains

$ rspec 
/Users/wsmoak/projects/mygame/spec/mygame_spec.rb:1:in `<top (required)>': uninitialized constant MyGame (NameError)

That looks like it needs a require statement somewhere…

This appears to have the best advice: http://stackoverflow.com/questions/4398262/setup-rspec-to-test-a-gem-not-rails

AND it looks like I could have used --test=rspec with the bundler gem mygame command.

I generated a new project with that switch and after some fussing around trying to compare them and add the missing bits to my original project, I elected to just delete everything and start over…

$ bundler gem --test=rspec mygame
      create  mygame/Gemfile
      create  mygame/Rakefile
      create  mygame/LICENSE.txt
      create  mygame/README.md
      create  mygame/.gitignore
      create  mygame/mygame.gemspec
      create  mygame/lib/mygame.rb
      create  mygame/lib/mygame/version.rb
      create  mygame/.rspec
      create  mygame/spec/spec_helper.rb
      create  mygame/spec/mygame_spec.rb
      create  mygame/.travis.yml
Initializing git repo in /Users/wsmoak/projects/mygame
$

…and then do the initial commit, and repeat the fixes for the version number and capitalization.

Much better!

Now bundle exec rspec works. The project skeleton comes complete with a failing test, so the output is:

$ bundle exec rspec

MyGame
  has a version number
  does something useful (FAILED - 1)

Failures:

  1) MyGame does something useful
     Failure/Error: expect(false).to eq(true)
       
       expected: true
            got: false
       
       (compared using ==)
     # ./spec/mygame_spec.rb:9:in `block (2 levels) in <top (required)>'

Finished in 0.00155 seconds (files took 0.09872 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/mygame_spec.rb:8 # MyGame does something useful

Next up: writing a real failing test and the first bit of code for the game.