Skip to content

Commit

Permalink
a few tests to experiment with minitest
Browse files Browse the repository at this point in the history
  • Loading branch information
jamis committed Dec 20, 2010
1 parent 3fc4b50 commit 11f1afa
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 33 deletions.
32 changes: 20 additions & 12 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
require 'rake'
require 'rake/gempackagetask'
require 'rake/rdoctask'
require 'rake/testtask'

task :default => :test

Rake::TestTask.new do |t|
t.test_files = FileList["test/*.rb"]
t.verbose = true
end

spec = Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.summary = "Maze generator for Ruby"
s.name = 'theseus'
s.version = "1.0.0"
s.files = FileList["README.markdown", "Rakefile", "lib/**/*.rb", "bin/*"].to_a
s.executables << "theseus"
s.add_dependency "chunky_png", "~> 0.12.0"
s.requirements << "Ruby 1.9"
s.description = "Theseus is a library for building random mazes."
s.author = "Jamis Buck"
s.email = "jamis@jamisbuck.org"
s.homepage = "http://github.com/jamis/theseus"
s.platform = Gem::Platform::RUBY
s.summary = "Maze generator for Ruby"
s.name = 'theseus'
s.version = "1.0.0"
s.files = FileList["README.markdown", "Rakefile", "lib/**/*.rb", "bin/*"].to_a
s.executables << "theseus"
s.add_dependency "chunky_png", "~> 0.12.0"
s.requirements << "Ruby 1.9"
s.description = "Theseus is a library for building random mazes."
s.author = "Jamis Buck"
s.email = "jamis@jamisbuck.org"
s.homepage = "http://github.com/jamis/theseus"
end

Rake::GemPackageTask.new(spec) do |pkg|
Expand Down
53 changes: 32 additions & 21 deletions lib/theseus/maze.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ class Maze
# to the maze, and generally defaults to the lower-right corner.
attr_reader :exit

# The x-coordinate that the generation algorithm will consider next.
# This value is meaningless once a maze has been generated.
attr_reader :x

# The y-coordinate that the generation algorithm will consider next.
# This value is meaningless once a maze has been generated.
attr_reader :y

# A short-hand method for creating a new maze object and causing it to
# be generated, in one step. Returns the newly generated maze.
def self.generate(options={})
Expand Down Expand Up @@ -605,6 +613,30 @@ def relative_direction(from, to)
end
end

# Applies a move in the given direction to the cell at (x,y). The +direction+
# parameter may also be :under, in which case the cell is left-shifted so as
# to move the existing passages to the UNDER plane.
#
# This method also handles the application of symmetrical moves, in the case
# where #symmetry has been specified.
#
# You'll generally never call this method directly, except to construct grids
# yourself.
def apply_move_at(x, y, direction)
if direction == :under
@cells[y][x] <<= UNDER_SHIFT
else
@cells[y][x] |= direction
end

case @symmetry
when :x then move_symmetrically_in_x(x, y, direction)
when :y then move_symmetrically_in_y(x, y, direction)
when :xy then move_symmetrically_in_xy(x, y, direction)
when :radial then move_symmetrically_radially(x, y, direction)
end
end

# Returns the type of the maze as a string. OrthogonalMaze, for
# instance, is reported as "orthogonal".
def type
Expand Down Expand Up @@ -719,27 +751,6 @@ def next_direction #:nodoc:
end
end

# Applies a move in the given direction to the cell at (x,y). The +direction+
# parameter may also be :under, in which case the cell is left-shifted so as
# to move the existing passages to the UNDER plane.
#
# This method also handles the application of symmetrical moves, in the case
# where #symmetry has been specified.
def apply_move_at(x, y, direction) #:nodoc:
if direction == :under
@cells[y][x] <<= UNDER_SHIFT
else
@cells[y][x] |= direction
end

case @symmetry
when :x then move_symmetrically_in_x(x, y, direction)
when :y then move_symmetrically_in_y(x, y, direction)
when :xy then move_symmetrically_in_xy(x, y, direction)
when :radial then move_symmetrically_radially(x, y, direction)
end
end

def move_symmetrically_in_x(x, y, direction) #:nodoc:
row_width = @cells[y].length
if direction == :under
Expand Down
193 changes: 193 additions & 0 deletions test/maze_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
require 'minitest/autorun'
require 'theseus'

class MazeTest < MiniTest::Unit::TestCase
def test_maze_without_explicit_height_uses_width
maze = Theseus::OrthogonalMaze.new(width: 10)
assert_equal 10, maze.width
assert_equal maze.width, maze.height
end

def test_maze_without_explicit_width_uses_height
maze = Theseus::OrthogonalMaze.new(height: 10)
assert_equal 10, maze.height
assert_equal maze.height, maze.width
end

def test_maze_is_initially_blank
maze = Theseus::OrthogonalMaze.new(width: 10)
assert !maze.generated?

zeros = 0
maze.height.times do |y|
maze.width.times do |x|
zeros += 1if maze[x, y] == 0
end
end

assert_equal 100, zeros
end

def test_maze_created_with_generate_is_identical_to_maze_created_with_step
srand(14)
maze1 = Theseus::OrthogonalMaze.generate(width: 10)
assert maze1.generated?

srand(14)
maze2 = Theseus::OrthogonalMaze.new(width: 10)
maze2.step until maze2.generated?

assert_equal maze1.width, maze2.width
assert_equal maze1.height, maze2.height

differences = 0

maze1.width.times do |x|
maze1.height.times do |y|
differences += 1 unless maze1[x,y] == maze2[x,y]
end
end

assert_equal 0, differences
end

def test_apply_move_at_should_combine_direction_with_existing_directions
maze = Theseus::OrthogonalMaze.new(width: 10)

maze[5,5] = Theseus::Maze::E
maze.apply_move_at(5, 5, Theseus::Maze::N)
assert_equal (Theseus::Maze::N | Theseus::Maze::E), maze[5,5]
end

def test_apply_move_at_with_under_should_move_existing_directions_to_under_plane
maze = Theseus::OrthogonalMaze.new(width: 10)

maze[5,5] = Theseus::Maze::E
maze.apply_move_at(5, 5, :under)
assert_equal (Theseus::Maze::E << Theseus::Maze::UNDER_SHIFT), maze[5,5]
end

def test_apply_move_at_with_x_symmetry_should_populate_x_mirror
maze = Theseus::OrthogonalMaze.new(width: 10, symmetry: :x)

maze.apply_move_at(1, 2, Theseus::Maze::E)
assert_equal Theseus::Maze::W, maze[8, 2]

maze.apply_move_at(2, 1, Theseus::Maze::NE)
assert_equal Theseus::Maze::NW, maze[7, 1]

maze.apply_move_at(2, 3, Theseus::Maze::N)
assert_equal Theseus::Maze::N, maze[7, 3]
end

def test_apply_move_at_with_y_symmetry_should_populate_y_mirror
maze = Theseus::OrthogonalMaze.new(width: 10, symmetry: :y)

maze.apply_move_at(1, 2, Theseus::Maze::S)
assert_equal Theseus::Maze::N, maze[1, 7]

maze.apply_move_at(2, 1, Theseus::Maze::SW)
assert_equal Theseus::Maze::NW, maze[2, 8]

maze.apply_move_at(2, 3, Theseus::Maze::W)
assert_equal Theseus::Maze::W, maze[2, 6]
end

def test_apply_move_at_with_xy_symmetry_should_populate_xy_mirror
maze = Theseus::OrthogonalMaze.new(width: 10, symmetry: :xy)

maze.apply_move_at(1, 2, Theseus::Maze::S)
assert_equal Theseus::Maze::N, maze[1, 7]
assert_equal Theseus::Maze::S, maze[8, 2]
assert_equal Theseus::Maze::N, maze[8, 7]

maze.apply_move_at(2, 1, Theseus::Maze::SW)
assert_equal Theseus::Maze::NW, maze[2, 8]
assert_equal Theseus::Maze::SE, maze[7, 1]
assert_equal Theseus::Maze::NE, maze[7, 8]

maze.apply_move_at(2, 3, Theseus::Maze::W)
assert_equal Theseus::Maze::W, maze[2, 6]
assert_equal Theseus::Maze::E, maze[7, 3]
assert_equal Theseus::Maze::E, maze[7, 6]
end

def test_apply_move_at_with_radial_symmetry_should_populate_radial_mirror
maze = Theseus::OrthogonalMaze.new(width: 10, symmetry: :radial)

maze.apply_move_at(1, 2, Theseus::Maze::S)
assert_equal Theseus::Maze::E, maze[2, 8]
assert_equal Theseus::Maze::W, maze[7, 1]
assert_equal Theseus::Maze::N, maze[8, 7]

maze.apply_move_at(2, 1, Theseus::Maze::SW)
assert_equal Theseus::Maze::SE, maze[1, 7]
assert_equal Theseus::Maze::NW, maze[8, 2]
assert_equal Theseus::Maze::NE, maze[7, 8]

maze.apply_move_at(2, 3, Theseus::Maze::W)
assert_equal Theseus::Maze::S, maze[3, 7]
assert_equal Theseus::Maze::N, maze[6, 2]
assert_equal Theseus::Maze::E, maze[7, 6]
end

def test_dx_east_should_increase
maze = Theseus::OrthogonalMaze.new(width: 10)
assert_equal 1, maze.dx(Theseus::Maze::E)
assert_equal 1, maze.dx(Theseus::Maze::NE)
assert_equal 1, maze.dx(Theseus::Maze::SE)
end

def test_dx_west_should_decrease
maze = Theseus::OrthogonalMaze.new(width: 10)
assert_equal -1, maze.dx(Theseus::Maze::W)
assert_equal -1, maze.dx(Theseus::Maze::NW)
assert_equal -1, maze.dx(Theseus::Maze::SW)
end

def test_dy_south_should_increase
maze = Theseus::OrthogonalMaze.new(width: 10)
assert_equal 1, maze.dy(Theseus::Maze::S)
assert_equal 1, maze.dy(Theseus::Maze::SE)
assert_equal 1, maze.dy(Theseus::Maze::SW)
end

def test_dy_north_should_decrease
maze = Theseus::OrthogonalMaze.new(width: 10)
assert_equal -1, maze.dy(Theseus::Maze::N)
assert_equal -1, maze.dy(Theseus::Maze::NE)
assert_equal -1, maze.dy(Theseus::Maze::NW)
end

def test_opposite_should_report_inverse_direction
maze = Theseus::OrthogonalMaze.new(width: 10)
assert_equal Theseus::Maze::N, maze.opposite(Theseus::Maze::S)
assert_equal Theseus::Maze::NE, maze.opposite(Theseus::Maze::SW)
assert_equal Theseus::Maze::E, maze.opposite(Theseus::Maze::W)
assert_equal Theseus::Maze::SE, maze.opposite(Theseus::Maze::NW)
assert_equal Theseus::Maze::S, maze.opposite(Theseus::Maze::N)
assert_equal Theseus::Maze::SW, maze.opposite(Theseus::Maze::NE)
assert_equal Theseus::Maze::W, maze.opposite(Theseus::Maze::E)
assert_equal Theseus::Maze::NW, maze.opposite(Theseus::Maze::SE)
end

def test_step_should_populate_current_cell_and_next_cell
maze = Theseus::OrthogonalMaze.new(width: 10)

cx, cy = maze.x, maze.y
assert cx >= 0 && cx < maze.width
assert cy >= 0 && cy < maze.height
assert_equal 0, maze[cx, cy]

assert maze.step

direction = maze[cx, cy]
refute_equal 0, direction

nx, ny = maze.move(cx, cy, direction)
refute_equal [nx, ny], [cx, cy]
assert_equal [nx, ny], [maze.x, maze.y]

assert_equal maze.opposite(direction), maze[nx, ny]
end
end

0 comments on commit 11f1afa

Please sign in to comment.