bitmapped 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +4 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/ChangeLog.rdoc +4 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +20 -0
- data/README.md +65 -0
- data/Rakefile +42 -0
- data/bin/bitmapped +11 -0
- data/bitmapped.gemspec +23 -0
- data/lib/bitmapped/bitmap.rb +122 -0
- data/lib/bitmapped/cli.rb +28 -0
- data/lib/bitmapped/exceptions.rb +4 -0
- data/lib/bitmapped/validators/validate_column_row_input.rb +21 -0
- data/lib/bitmapped/validators/validate_fill_input.rb +24 -0
- data/lib/bitmapped/validators/validate_segment_input.rb +24 -0
- data/lib/bitmapped/validators/validation_helper.rb +18 -0
- data/lib/bitmapped/version.rb +4 -0
- data/lib/bitmapped.rb +1 -0
- data/spec/bitmap_spec.rb +210 -0
- data/spec/bitmapped_spec.rb +8 -0
- data/spec/exceptions_spec.rb +20 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/validators/validate_column_row_input_spec.rb +28 -0
- data/spec/validators/validate_fill_input_spec.rb +28 -0
- data/spec/validators/validate_helper_spec.rb +28 -0
- data/spec/validators/validate_segment_input_spec.rb +28 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 99702c03528a066944f878c4b91150111a57109c
|
4
|
+
data.tar.gz: bb7495610f144df0ed5ebbbf4073846add4a7984
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 310a13fb27eb9a4124623c7088e2de83bf4e323fe414e2721c35bff6ddaa6e9067e95bb48296b6562410816eca7ad31455ab5ece03416b9a58262bad8ae604c1
|
7
|
+
data.tar.gz: 84f16acd5af696546e80aba724afa45d966dc0e1f7aed02643cf158c94b54d63b20acbfb21f98605fa868dc208eb6728b4d1283f86bca1ec9d16d853461daf42
|
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/.travis.yml
ADDED
data/ChangeLog.rdoc
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2015 Ashley Connor
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# bitmapped
|
2
|
+
|
3
|
+
[](https://codeclimate.com/github/ashleyconnor/bitmapped) [](https://travis-ci.org/ashleyconnor/bitmapped)
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
Bitmapped is an command-line editor which allows you to create and edit bitmap-like text images.
|
8
|
+
|
9
|
+
## Features
|
10
|
+
|
11
|
+
Bitmapped accepts various commands to create and edit bitmap-like text images:
|
12
|
+
|
13
|
+
| Command | Description | Key | Parameters |
|
14
|
+
|---------------------|------------------------------------------------------------|-----|----------------------------------------|
|
15
|
+
| Initiate Bitmap | Initiates a Bitmap of the given size | I | Columns:Int, Rows:Int |
|
16
|
+
| Clear | Clears the Bitmap setting all cells to "0" | C | |
|
17
|
+
| Color Cell | Colors the cell at the given co-ordinates | L | Column:Int, Row:Int, Color:String |
|
18
|
+
| Vertically Line | Colors multiple cells on specified column between rows X Y | V | Column:Int, Row:X, Row:Y, Color:String |
|
19
|
+
| Horizontal Line | Colors multiple cells on specified row between rows X Y | H | Row:X, Row:Y, Row:Int, Color:String |
|
20
|
+
| Fill (Paint Bucket) | Fills a given cell and surrounding cells of the same color | F | Column:Int, Row:Int, Color:String |
|
21
|
+
| Exit | Exits the program | X | |
|
22
|
+
|
23
|
+
|
24
|
+
## Examples
|
25
|
+
bundle exec bitmapped
|
26
|
+
> I 5 6
|
27
|
+
> L 2 3 A
|
28
|
+
> S
|
29
|
+
+---+---+---+---+---+
|
30
|
+
| 0 | 0 | 0 | 0 | 0 |
|
31
|
+
| 0 | 0 | 0 | 0 | 0 |
|
32
|
+
| 0 | 0 | 0 | 0 | 0 |
|
33
|
+
| 0 | 0 | 0 | 0 | 0 |
|
34
|
+
| 0 | 0 | 0 | 0 | 0 |
|
35
|
+
| 0 | 0 | 0 | 0 | 0 |
|
36
|
+
+---+---+---+---+---+
|
37
|
+
> F 3 3 J
|
38
|
+
> V 2 3 4 W
|
39
|
+
> H 3 4 2 Z
|
40
|
+
> S
|
41
|
+
+---+---+---+---+---+
|
42
|
+
| J | J | J | J | J |
|
43
|
+
| J | J | Z | Z | J |
|
44
|
+
| J | W | J | J | J |
|
45
|
+
| J | W | J | J | J |
|
46
|
+
| J | J | J | J | J |
|
47
|
+
| J | J | J | J | J |
|
48
|
+
+---+---+---+---+---+
|
49
|
+
|
50
|
+
## Requirements
|
51
|
+
Ruby 2.0+
|
52
|
+
## Install
|
53
|
+
|
54
|
+
$ gem install bitmapped
|
55
|
+
|
56
|
+
## TODO
|
57
|
+
|
58
|
+
* Custom commands
|
59
|
+
* Refactor Bitmap commands into objects with tests
|
60
|
+
|
61
|
+
### Copyright
|
62
|
+
|
63
|
+
Copyright (c) 2015 **Ashley Connor**
|
64
|
+
|
65
|
+
See LICENSE.txt for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'bundler'
|
7
|
+
rescue LoadError => e
|
8
|
+
warn e.message
|
9
|
+
warn "Run `gem install bundler` to install Bundler."
|
10
|
+
exit -1
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
Bundler.setup(:development)
|
15
|
+
rescue Bundler::BundlerError => e
|
16
|
+
warn e.message
|
17
|
+
warn "Run `bundle install` to install missing gems."
|
18
|
+
exit e.status_code
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake'
|
22
|
+
|
23
|
+
require 'rubygems/tasks'
|
24
|
+
Gem::Tasks.new
|
25
|
+
|
26
|
+
require 'rdoc/task'
|
27
|
+
RDoc::Task.new do |rdoc|
|
28
|
+
rdoc.title = "bitmapped"
|
29
|
+
end
|
30
|
+
task :doc => :rdoc
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'rspec/core/rake_task'
|
34
|
+
RSpec::Core::RakeTask.new
|
35
|
+
rescue LoadError
|
36
|
+
task :spec do
|
37
|
+
abort "Please run `gem install rspec` to install RSpec."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :spec
|
42
|
+
task :default => :spec
|
data/bin/bitmapped
ADDED
data/bitmapped.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path('../lib/bitmapped/version', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "bitmapped"
|
7
|
+
gem.version = Bitmapped::VERSION
|
8
|
+
gem.platform = Gem::Platform::RUBY
|
9
|
+
gem.summary = %q{Bitmap CLI program}
|
10
|
+
gem.description = %q{Bitmap CLI program}
|
11
|
+
gem.license = "MIT"
|
12
|
+
gem.authors = ["Ashley Connor"]
|
13
|
+
gem.email = "ashconnor@me.com"
|
14
|
+
gem.homepage = "https://rubygems.org/gems/bitmapped"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ['lib']
|
20
|
+
|
21
|
+
gem.required_ruby_version = ">= 2.0.0"
|
22
|
+
gem.add_runtime_dependency 'terminal-table', '~> 1.4', '>= 1.4.5'
|
23
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
Dir[File.join(File.dirname(__FILE__), 'validators', '*.rb')].each {|file| require file }
|
2
|
+
|
3
|
+
require 'terminal-table'
|
4
|
+
require 'bitmapped/exceptions'
|
5
|
+
|
6
|
+
module Bitmapped
|
7
|
+
class Bitmap
|
8
|
+
|
9
|
+
attr_accessor :pixels, :table, :rows, :columns
|
10
|
+
|
11
|
+
def command(input)
|
12
|
+
begin
|
13
|
+
case input.shift
|
14
|
+
when "I"
|
15
|
+
self.columns, self.rows = Validators::ValidateColumnRowInput.parse_and_validate(input)
|
16
|
+
self.pixels = populate_pixels(self.columns, self.rows)
|
17
|
+
when "X"
|
18
|
+
raise Interrupt
|
19
|
+
when bitmap_available("C")
|
20
|
+
self.pixels = populate_pixels(self.columns, self.rows)
|
21
|
+
when bitmap_available("L")
|
22
|
+
column, row, color = Validators::ValidateFillInput.parse_and_validate(input)
|
23
|
+
color_command(column, row, color)
|
24
|
+
when bitmap_available("V")
|
25
|
+
column, start, finish, color = Validators::ValidateSegmentInput.parse_and_validate(input)
|
26
|
+
vertical_command(column, start, finish, color)
|
27
|
+
when bitmap_available("H")
|
28
|
+
start, finish, row, color = Validators::ValidateSegmentInput.parse_and_validate(input)
|
29
|
+
horizontal_command(start, finish, row, color)
|
30
|
+
when bitmap_available("F")
|
31
|
+
column, row, color = Validators::ValidateFillInput.parse_and_validate(input)
|
32
|
+
fill_command(column, row, color)
|
33
|
+
when bitmap_available("S")
|
34
|
+
formatted_table
|
35
|
+
when "C", "L", "V", "H", "F", "S"
|
36
|
+
"Bitmap has not been initialised, run command 'I' with valid arguments"
|
37
|
+
else
|
38
|
+
"Invalid Command"
|
39
|
+
end
|
40
|
+
rescue ParsingError => e
|
41
|
+
"Invalid parameters"
|
42
|
+
rescue InvalidCoordinatesError => e
|
43
|
+
"Invalid co-ordinates"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def populate_pixels(x, y)
|
49
|
+
Array.new(self.rows) { Array.new(self.columns) { "0" } }
|
50
|
+
end
|
51
|
+
|
52
|
+
def bitmap_available(command)
|
53
|
+
lambda { |option| option == command && self.pixels }
|
54
|
+
end
|
55
|
+
|
56
|
+
def formatted_table
|
57
|
+
self.table ||= Terminal::Table.new
|
58
|
+
self.table.rows = self.pixels
|
59
|
+
self.table
|
60
|
+
# self.pixels.each { |row| puts row.join("") } # no fancy table
|
61
|
+
end
|
62
|
+
|
63
|
+
def color_command(x, y, color)
|
64
|
+
x, y = coordinates_to_array_indexes(x, y)
|
65
|
+
self.pixels[y][x] = color
|
66
|
+
end
|
67
|
+
|
68
|
+
def vertical_command(column, x, y, color)
|
69
|
+
raise InvalidCoordinatesError unless (0 < column && column <= self.columns)
|
70
|
+
x, y = coordinates_to_array_indexes(x, y)
|
71
|
+
column = column - 1
|
72
|
+
self.pixels[x..y].each { |row| row[column] = color }
|
73
|
+
end
|
74
|
+
|
75
|
+
def horizontal_command(x, y, row, color)
|
76
|
+
raise InvalidCoordinatesError unless (0 < row && row <= self.rows)
|
77
|
+
x, y = coordinates_to_array_indexes(x, y)
|
78
|
+
row = row - 1
|
79
|
+
self.pixels[row][x..y] = Array.new((x..y).size, color)
|
80
|
+
end
|
81
|
+
|
82
|
+
def fill_command(x, y, replacement_color)
|
83
|
+
x, y = coordinates_to_array_indexes(x, y)
|
84
|
+
target_color = self.pixels[x][y]
|
85
|
+
queue = [[x,y]]
|
86
|
+
|
87
|
+
until queue.empty?
|
88
|
+
x, y = queue.pop
|
89
|
+
next if (!valid_cooridinates(x+1, y+1) || self.pixels[x][y] != target_color)
|
90
|
+
self.pixels[x][y] = replacement_color
|
91
|
+
queue << [x+1, y] # east
|
92
|
+
queue << [x-1, y] # west
|
93
|
+
queue << [x, y+1] # south
|
94
|
+
queue << [x, y-1] # north
|
95
|
+
|
96
|
+
# and if we are doing 8-direction flood-fill...
|
97
|
+
# queue << [x+1, y-1] # north-east
|
98
|
+
# queue << [x-1, y-1] # north-west
|
99
|
+
# queue << [x+1, y+1] # south-east
|
100
|
+
# queue << [x-1, y+1] # south-west
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def valid_cooridinates(x, y)
|
105
|
+
if (0 <= x && x <= self.columns) && (0 <= y && y <= self.rows)
|
106
|
+
true
|
107
|
+
else
|
108
|
+
false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def coordinates_to_array_indexes(x, y)
|
113
|
+
x = x.to_i - 1
|
114
|
+
y = y.to_i - 1
|
115
|
+
if valid_cooridinates(x, y)
|
116
|
+
[x, y]
|
117
|
+
else
|
118
|
+
raise InvalidCoordinatesError
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bitmapped/bitmap'
|
2
|
+
|
3
|
+
require 'readline'
|
4
|
+
|
5
|
+
module Bitmapped
|
6
|
+
class Cli
|
7
|
+
class << self
|
8
|
+
def start
|
9
|
+
begin
|
10
|
+
bitmap = Bitmap.new
|
11
|
+
puts "Bitmapped Command Centre (Ctrl+C to exit):"
|
12
|
+
|
13
|
+
loop do
|
14
|
+
input = split_input(Readline.readline("> "))
|
15
|
+
puts bitmap.command(input)
|
16
|
+
end
|
17
|
+
rescue Interrupt => interrupt
|
18
|
+
puts "\nExiting..."
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def split_input(input)
|
24
|
+
input.strip.split(' ')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bitmapped/exceptions'
|
2
|
+
|
3
|
+
module Bitmapped
|
4
|
+
module Validators
|
5
|
+
class ValidateColumnRowInput
|
6
|
+
class << self
|
7
|
+
def parse_and_validate(input)
|
8
|
+
begin
|
9
|
+
raise ArgumentError unless input.size == 2
|
10
|
+
|
11
|
+
columns = Integer(input[0])
|
12
|
+
rows = Integer(input[1])
|
13
|
+
[columns, rows]
|
14
|
+
rescue ArgumentError => ae
|
15
|
+
raise ParsingError
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bitmapped/exceptions'
|
2
|
+
require 'bitmapped/validators/validation_helper'
|
3
|
+
|
4
|
+
module Bitmapped
|
5
|
+
module Validators
|
6
|
+
class ValidateFillInput
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def parse_and_validate(input)
|
10
|
+
begin
|
11
|
+
raise ArgumentError unless input.size == 3
|
12
|
+
|
13
|
+
columns = Integer(input[0])
|
14
|
+
rows = Integer(input[1])
|
15
|
+
color = ValidationHelper.parse_color(input[2].strip)
|
16
|
+
[columns, rows, color]
|
17
|
+
rescue ArgumentError => ae
|
18
|
+
raise ParsingError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bitmapped/exceptions'
|
2
|
+
require 'bitmapped/validators/validation_helper'
|
3
|
+
|
4
|
+
module Bitmapped
|
5
|
+
module Validators
|
6
|
+
class ValidateSegmentInput
|
7
|
+
class << self
|
8
|
+
def parse_and_validate(input)
|
9
|
+
begin
|
10
|
+
raise ArgumentError unless input.size == 4
|
11
|
+
|
12
|
+
segement_a = Integer(input[0])
|
13
|
+
segement_b = Integer(input[1])
|
14
|
+
segement_c = Integer(input[2])
|
15
|
+
color = ValidationHelper.parse_color(input[3].strip)
|
16
|
+
[segement_a, segement_b, segement_c, color]
|
17
|
+
rescue ArgumentError => ae
|
18
|
+
raise ParsingError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bitmapped/exceptions'
|
2
|
+
|
3
|
+
module Bitmapped
|
4
|
+
module Validators
|
5
|
+
module ValidationHelper
|
6
|
+
class << self
|
7
|
+
def parse_color(color)
|
8
|
+
color = color.strip
|
9
|
+
if [*'A'..'Z'].include?(color)
|
10
|
+
color
|
11
|
+
else
|
12
|
+
raise ParsingError
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/bitmapped.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bitmapped/version'
|
data/spec/bitmap_spec.rb
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'bitmapped/bitmap'
|
4
|
+
|
5
|
+
describe Bitmap do
|
6
|
+
|
7
|
+
subject { Bitmap.new }
|
8
|
+
|
9
|
+
shared_examples_for "a command requiring an initialised bitmap" do |arg|
|
10
|
+
it "returns an error message" do
|
11
|
+
expect(subject.command([arg])).to eq("Bitmap has not been initialised, run command 'I' with valid arguments")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'the I command' do
|
16
|
+
it 'initializes a grid of that size' do
|
17
|
+
args = ["I", "2", "3"]
|
18
|
+
pixels = [["0", "0"],
|
19
|
+
["0", "0"],
|
20
|
+
["0", "0"]]
|
21
|
+
|
22
|
+
subject.command(args)
|
23
|
+
|
24
|
+
expect(subject.columns).to eq(2)
|
25
|
+
expect(subject.rows).to eq(3)
|
26
|
+
expect(subject.pixels).to eq(pixels)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'overwrites the old bitmap given the I command again' do
|
30
|
+
first_args = ["I", "2", "3"]
|
31
|
+
second_args = ["I", "3", "2"]
|
32
|
+
pixels = [["0", "0", "0"],
|
33
|
+
["0", "0", "0"]]
|
34
|
+
|
35
|
+
subject.command(first_args)
|
36
|
+
subject.command(second_args)
|
37
|
+
|
38
|
+
expect(subject.columns).to eq(3)
|
39
|
+
expect(subject.rows).to eq(2)
|
40
|
+
expect(subject.pixels).to eq(pixels)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'the X command' do
|
45
|
+
it 'raises an Interrupt exception' do
|
46
|
+
expect{ subject.command(["X"]) } .to raise_error(Interrupt)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'the C command' do
|
51
|
+
it_should_behave_like "a command requiring an initialised bitmap", "C"
|
52
|
+
|
53
|
+
context 'when the bitmap is initialised' do
|
54
|
+
it 'replaces all of the bitmap colors with "0"' do
|
55
|
+
setup_pixels(subject, 3, 2, "X")
|
56
|
+
subject.command(["C"])
|
57
|
+
|
58
|
+
expect(subject.pixels).to eq([["0", "0", "0"],
|
59
|
+
["0", "0", "0"]])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'the L command' do
|
65
|
+
it_should_behave_like "a command requiring an initialised bitmap", "L"
|
66
|
+
|
67
|
+
context 'when the bitmap is initialised' do
|
68
|
+
before(:example) do
|
69
|
+
setup_pixels(subject, 3, 2)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'replaces the color at those coordinates' do
|
73
|
+
subject.command(["L", "1", "2", "Z"])
|
74
|
+
subject.command(["L", "2", "1", "Z"])
|
75
|
+
|
76
|
+
expect(subject.pixels).to eq([["0", "Z", "0"],
|
77
|
+
["Z", "0", "0"]])
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns an error when the coordinates are not valid' do
|
81
|
+
expect(subject.command(["L", "4", "4", "Z"])).to eq("Invalid co-ordinates")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'the V command' do
|
87
|
+
it_should_behave_like "a command requiring an initialised bitmap", "V"
|
88
|
+
|
89
|
+
context 'when the bitmap is initialised' do
|
90
|
+
before(:example) do
|
91
|
+
setup_pixels(subject, 4, 4)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should draw a vertical color segment between the 2 rows' do
|
95
|
+
subject.command(["V", "3", "2", "4", "X"])
|
96
|
+
subject.command(["V", "1", "1", "3", "Z"])
|
97
|
+
|
98
|
+
expect(subject.pixels).to eq([["Z","0","0","0"],
|
99
|
+
["Z","0","X","0"],
|
100
|
+
["Z","0","X","0"],
|
101
|
+
["0","0","X","0"]]
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns an error when the coordinates are invalid' do
|
106
|
+
[["V", "10", "1", "3", "Z"], ["V", "1", "10", "3", "Z"], ["V", "1", "1", "10", "Z"]].each do |args|
|
107
|
+
expect(subject.command(args)).to eq("Invalid co-ordinates")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'returns an error when the parameters are invalid' do
|
112
|
+
[["V", "10", "3", "Z"], ["V", "Z", "10", "3", "3"], ["V", "1", "1", "10", "1"]].each do |args|
|
113
|
+
expect(subject.command(args)).to eq("Invalid parameters")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'the H command' do
|
120
|
+
it_should_behave_like "a command requiring an initialised bitmap", "H"
|
121
|
+
|
122
|
+
context 'when the bitmap is initialised' do
|
123
|
+
before(:example) do
|
124
|
+
setup_pixels(subject, 4, 4)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should draw a horizontal color segment between the 2 columns' do
|
128
|
+
subject.command(["H", "2", "4", "2", "X"])
|
129
|
+
subject.command(["H", "1", "4", "4", "Z"])
|
130
|
+
|
131
|
+
expect(subject.pixels).to eq([["0","0","0","0"],
|
132
|
+
["0","X","X","X"],
|
133
|
+
["0","0","0","0"],
|
134
|
+
["Z","Z","Z","Z"]]
|
135
|
+
)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'returns an error when the coordinates are invalid' do
|
139
|
+
[["H", "10", "1", "3", "Z"], ["H", "1", "10", "3", "Z"], ["H", "1", "1", "10", "Z"]].each do |args|
|
140
|
+
expect(subject.command(args)).to eq("Invalid co-ordinates")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'returns an error when the parameters are invalid' do
|
145
|
+
[["H", "10", "3", "Z"], ["H", "Z", "10", "3", "3"], ["H", "1", "1", "10", "1", "Z"]].each do |args|
|
146
|
+
expect(subject.command(args)).to eq("Invalid parameters")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe 'the F command' do
|
153
|
+
it_should_behave_like "a command requiring an initialised bitmap", "F"
|
154
|
+
|
155
|
+
context 'when the bitmap is initialised' do
|
156
|
+
|
157
|
+
before(:example) do
|
158
|
+
setup_pixels(subject, 4, 4)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should fill region on the bitmap with the color given' do
|
162
|
+
subject.command(["F", "3", "3", "J"])
|
163
|
+
expect(subject.pixels).to eq([["J","J","J","J"],
|
164
|
+
["J","J","J","J"],
|
165
|
+
["J","J","J","J"],
|
166
|
+
["J","J","J","J"]])
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe 'the S command' do
|
172
|
+
it_should_behave_like "a command requiring an initialised bitmap", "S"
|
173
|
+
|
174
|
+
context 'when the bitmap is initialised' do
|
175
|
+
before(:example) do
|
176
|
+
setup_pixels(subject, 4, 4)
|
177
|
+
end
|
178
|
+
|
179
|
+
let(:formatted_table) { %{+---+---+---+---+
|
180
|
+
| 0 | 0 | 0 | 0 |
|
181
|
+
| 0 | 0 | 0 | 0 |
|
182
|
+
| 0 | 0 | 0 | 0 |
|
183
|
+
| 0 | 0 | 0 | 0 |
|
184
|
+
+---+---+---+---+}.gsub(/[^\S\n]{2,}/, '')}
|
185
|
+
|
186
|
+
let(:filled_formatted_table) {%{+---+---+---+---+
|
187
|
+
| J | J | J | J |
|
188
|
+
| J | J | J | J |
|
189
|
+
| J | J | J | J |
|
190
|
+
| J | J | J | J |
|
191
|
+
+---+---+---+---+}.gsub(/[^\S\n]{2,}/, '')}
|
192
|
+
|
193
|
+
it 'should output a formatted table' do
|
194
|
+
expect(subject.command(["S"]).to_s).to eq(formatted_table)
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'should output a correctly formatted table after fill command' do
|
198
|
+
subject.command(["F", "3", "3", "J"])
|
199
|
+
|
200
|
+
expect(subject.command(["S"]).to_s).to eq(filled_formatted_table)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def setup_pixels(subject, columns, rows, color="0")
|
206
|
+
subject.columns = columns
|
207
|
+
subject.rows = rows
|
208
|
+
subject.pixels = Array.new(rows) { Array.new(columns) { color } }
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'bitmapped/exceptions'
|
4
|
+
|
5
|
+
describe ParsingError do
|
6
|
+
subject { ParsingError }
|
7
|
+
|
8
|
+
it 'inherits from StandardError' do
|
9
|
+
expect(subject.superclass).to eq(StandardError)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe InvalidCoordinatesError do
|
14
|
+
subject { InvalidCoordinatesError }
|
15
|
+
|
16
|
+
it 'inherits from StandardError' do
|
17
|
+
expect(subject.superclass).to eq(StandardError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'bitmapped/exceptions'
|
4
|
+
|
5
|
+
describe Validators::ValidateColumnRowInput do
|
6
|
+
context 'given valid input' do
|
7
|
+
|
8
|
+
let(:valid_inputs) { [["2", "2"], ["2", "3"], ["10", "99"]] }
|
9
|
+
let(:outputs) { [[2, 2], [2, 3], [10, 99]] }
|
10
|
+
|
11
|
+
it 'should return an array of parsed values' do
|
12
|
+
valid_inputs.each_with_index do |input, index|
|
13
|
+
expect(Validators::ValidateColumnRowInput.parse_and_validate(input)).to eq(outputs[index])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'given invalid input' do
|
19
|
+
|
20
|
+
let(:invalid_inputs) { [["A", "2"], ["2", "Z"], ["99"]] }
|
21
|
+
|
22
|
+
it 'should return an error' do
|
23
|
+
invalid_inputs.each do |input|
|
24
|
+
expect{Validators::ValidateColumnRowInput.parse_and_validate(input)}.to raise_error(ParsingError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'bitmapped/exceptions'
|
4
|
+
|
5
|
+
describe Validators::ValidateFillInput do
|
6
|
+
context 'given valid input' do
|
7
|
+
|
8
|
+
let(:valid_inputs) { [["2", "2", "C"], ["2", "3", "X"], ["10", "99", "Y"]] }
|
9
|
+
let(:outputs) { [[2, 2, "C"], [2, 3, "X"], [10, 99, "Y"]] }
|
10
|
+
|
11
|
+
it 'should return an array of parsed values' do
|
12
|
+
valid_inputs.each_with_index do |input, index|
|
13
|
+
expect(Validators::ValidateFillInput.parse_and_validate(input)).to eq(outputs[index])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'given invalid input' do
|
19
|
+
|
20
|
+
let(:invalid_inputs) { [["A", "2", "2"], ["2", "Z", "A"], ["99", "Z"]] }
|
21
|
+
|
22
|
+
it 'should return an error' do
|
23
|
+
invalid_inputs.each do |input|
|
24
|
+
expect{Validators::ValidateFillInput.parse_and_validate(input)}.to raise_error(ParsingError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'bitmapped/exceptions'
|
4
|
+
|
5
|
+
describe Validators::ValidationHelper do
|
6
|
+
context 'given valid input' do
|
7
|
+
|
8
|
+
let(:valid_inputs) { [" A", "B", "C "] }
|
9
|
+
let(:outputs) { ["A", "B", "C"] }
|
10
|
+
|
11
|
+
it 'should return an array of parsed values' do
|
12
|
+
valid_inputs.each_with_index do |input, index|
|
13
|
+
expect(Validators::ValidationHelper.parse_color(input)).to eq(outputs[index])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'given invalid input' do
|
19
|
+
|
20
|
+
let(:invalid_inputs) { ["2", "!", "a"] }
|
21
|
+
|
22
|
+
it 'should return an error' do
|
23
|
+
invalid_inputs.each do |input|
|
24
|
+
expect{Validators::ValidationHelper.parse_color(input)}.to raise_error(ParsingError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'bitmapped/exceptions'
|
4
|
+
|
5
|
+
describe Validators::ValidateSegmentInput do
|
6
|
+
context 'given valid input' do
|
7
|
+
|
8
|
+
let(:valid_inputs) { [["2", "2", "2", "C"], ["2", "3", "3", "X"], ["10", "99", "1000", "Y"]] }
|
9
|
+
let(:outputs) { [[2, 2, 2, "C"], [2, 3, 3, "X"], [10, 99, 1000, "Y"]] }
|
10
|
+
|
11
|
+
it 'should return an array of parsed values' do
|
12
|
+
valid_inputs.each_with_index do |input, index|
|
13
|
+
expect(Validators::ValidateSegmentInput.parse_and_validate(input)).to eq(outputs[index])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'given invalid input' do
|
19
|
+
|
20
|
+
let(:invalid_inputs) { [["A", "2", "2", "2"], ["2", "2", "2", "2"], ["99", "50","Z"]] }
|
21
|
+
|
22
|
+
it 'should return an error' do
|
23
|
+
invalid_inputs.each do |input|
|
24
|
+
expect{Validators::ValidateSegmentInput.parse_and_validate(input)}.to raise_error(ParsingError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bitmapped
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ashley Connor
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: terminal-table
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.4.5
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.4'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.4.5
|
33
|
+
description: Bitmap CLI program
|
34
|
+
email: ashconnor@me.com
|
35
|
+
executables:
|
36
|
+
- bitmapped
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
files:
|
40
|
+
- ".document"
|
41
|
+
- ".gitignore"
|
42
|
+
- ".rspec"
|
43
|
+
- ".travis.yml"
|
44
|
+
- ChangeLog.rdoc
|
45
|
+
- Gemfile
|
46
|
+
- LICENSE.txt
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- bin/bitmapped
|
50
|
+
- bitmapped.gemspec
|
51
|
+
- lib/bitmapped.rb
|
52
|
+
- lib/bitmapped/bitmap.rb
|
53
|
+
- lib/bitmapped/cli.rb
|
54
|
+
- lib/bitmapped/exceptions.rb
|
55
|
+
- lib/bitmapped/validators/validate_column_row_input.rb
|
56
|
+
- lib/bitmapped/validators/validate_fill_input.rb
|
57
|
+
- lib/bitmapped/validators/validate_segment_input.rb
|
58
|
+
- lib/bitmapped/validators/validation_helper.rb
|
59
|
+
- lib/bitmapped/version.rb
|
60
|
+
- spec/bitmap_spec.rb
|
61
|
+
- spec/bitmapped_spec.rb
|
62
|
+
- spec/exceptions_spec.rb
|
63
|
+
- spec/spec_helper.rb
|
64
|
+
- spec/validators/validate_column_row_input_spec.rb
|
65
|
+
- spec/validators/validate_fill_input_spec.rb
|
66
|
+
- spec/validators/validate_helper_spec.rb
|
67
|
+
- spec/validators/validate_segment_input_spec.rb
|
68
|
+
homepage: https://rubygems.org/gems/bitmapped
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 2.0.0
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.2.2
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Bitmap CLI program
|
92
|
+
test_files:
|
93
|
+
- spec/bitmap_spec.rb
|
94
|
+
- spec/bitmapped_spec.rb
|
95
|
+
- spec/exceptions_spec.rb
|
96
|
+
- spec/spec_helper.rb
|
97
|
+
- spec/validators/validate_column_row_input_spec.rb
|
98
|
+
- spec/validators/validate_fill_input_spec.rb
|
99
|
+
- spec/validators/validate_helper_spec.rb
|
100
|
+
- spec/validators/validate_segment_input_spec.rb
|