pontifex 1.0.1
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.
- data/.rvmrc +1 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +50 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +53 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/bin/pontifex +5 -0
- data/cucumber.yml +3 -0
- data/feature/pontifex_interactive.feature +161 -0
- data/feature/pontifex_with_files.feature +137 -0
- data/feature/support/env.rb +15 -0
- data/lib/pontifex/card.rb +70 -0
- data/lib/pontifex/cipher.rb +49 -0
- data/lib/pontifex/key_stream.rb +79 -0
- data/lib/pontifex.rb +114 -0
- data/pontifex.gemspec +99 -0
- data/spec/pontifex/card_spec.rb +84 -0
- data/spec/pontifex/cipher_spec.rb +23 -0
- data/spec/pontifex/key_stream_spec.rb +92 -0
- data/spec/pontifex/pontifex_spec.rb +4 -0
- data/spec/spec_helper.rb +12 -0
- data/vendor/cache/aruba-0.3.6.gem +0 -0
- data/vendor/cache/builder-3.0.0.gem +0 -0
- data/vendor/cache/childprocess-0.1.9.gem +0 -0
- data/vendor/cache/cucumber-0.10.3.gem +0 -0
- data/vendor/cache/diff-lcs-1.1.2.gem +0 -0
- data/vendor/cache/ffi-1.0.9.gem +0 -0
- data/vendor/cache/gherkin-2.3.9.gem +0 -0
- data/vendor/cache/git-1.2.5.gem +0 -0
- data/vendor/cache/jeweler-1.6.0.gem +0 -0
- data/vendor/cache/json-1.5.1.gem +0 -0
- data/vendor/cache/rake-0.9.0.gem +0 -0
- data/vendor/cache/rcov-0.9.9.gem +0 -0
- data/vendor/cache/rspec-2.6.0.gem +0 -0
- data/vendor/cache/rspec-core-2.6.3.gem +0 -0
- data/vendor/cache/rspec-expectations-2.6.0.gem +0 -0
- data/vendor/cache/rspec-mocks-2.6.0.gem +0 -0
- data/vendor/cache/term-ansicolor-1.0.5.gem +0 -0
- data/vendor/cache/trollop-1.16.2.gem +0 -0
- metadata +175 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'pontifex/card'
|
2
|
+
|
3
|
+
module Pontifex
|
4
|
+
|
5
|
+
DEFAULT_KEY = "Ac,2c,3c,4c,5c,6c,7c,8c,9c,Tc,Jc,Qc,Kc," +
|
6
|
+
"Ad,2d,3d,4d,5d,6d,7d,8d,9d,Td,Jd,Qd,Kd," +
|
7
|
+
"Ah,2h,3h,4h,5h,6h,7h,8h,9h,Th,Jh,Qh,Kh," +
|
8
|
+
"As,2s,3s,4s,5s,6s,7s,8s,9s,Ts,Js,Qs,Ks," +
|
9
|
+
"ja,jb"
|
10
|
+
|
11
|
+
class KeyStream
|
12
|
+
attr_reader :deck
|
13
|
+
JA = Card.new("ja")
|
14
|
+
JB = Card.new("jb")
|
15
|
+
|
16
|
+
def initialize(key=Pontifex::DEFAULT_KEY)
|
17
|
+
@deck = process_param(key)
|
18
|
+
end
|
19
|
+
|
20
|
+
def sequence!
|
21
|
+
move_down!("ja", 1)
|
22
|
+
move_down!("jb", 2)
|
23
|
+
triple_cut!
|
24
|
+
count_cut!
|
25
|
+
end
|
26
|
+
|
27
|
+
def letter
|
28
|
+
count = @deck.first.to_i
|
29
|
+
if result = @deck[count].to_c
|
30
|
+
result
|
31
|
+
else
|
32
|
+
sequence!
|
33
|
+
letter
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_key
|
38
|
+
@deck.map { |card| card.str }.join(",")
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
private
|
43
|
+
def process_param(str)
|
44
|
+
#TODO I need to raise an exception here if any 'Ja' jokers,
|
45
|
+
# as opposed to 'ja' jokers, (or 'Jb') are included in
|
46
|
+
# the key -- Or does this exception belong in Card?
|
47
|
+
key_ary = str.split(",")
|
48
|
+
key_ary.map { |param| Card.new(param) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def move_down!(card_str, num)
|
52
|
+
num.times do
|
53
|
+
index = @deck.index { |c| c.str == card_str }
|
54
|
+
unless @deck[index] == @deck.last
|
55
|
+
@deck[index], @deck[index + 1] = @deck[index + 1], @deck[index]
|
56
|
+
else
|
57
|
+
@deck.insert(1, @deck.pop)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def triple_cut!
|
63
|
+
ti, bi = @deck.index(JA), @deck.index(JB)
|
64
|
+
ti, bi = bi, ti if ti > bi
|
65
|
+
|
66
|
+
top = @deck[0...ti]
|
67
|
+
middle = @deck[ti..bi]
|
68
|
+
bottom = @deck[(bi + 1)..-1]
|
69
|
+
|
70
|
+
@deck.replace(bottom + middle + top)
|
71
|
+
end
|
72
|
+
|
73
|
+
def count_cut!
|
74
|
+
count = @deck.last.to_i
|
75
|
+
top = @deck.shift(count)
|
76
|
+
@deck.insert(-2, *top)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/pontifex.rb
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'trollop'
|
3
|
+
require 'pontifex/cipher'
|
4
|
+
|
5
|
+
|
6
|
+
module Pontifex
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def run
|
10
|
+
parse_options!
|
11
|
+
|
12
|
+
case @cmd
|
13
|
+
when "encrypt"
|
14
|
+
@output = @pontifex.encrypted
|
15
|
+
when "decrypt"
|
16
|
+
@output = @pontifex.decrypted
|
17
|
+
end
|
18
|
+
|
19
|
+
handle_output
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
private
|
24
|
+
def handle_output
|
25
|
+
if @cmd_options[:out_file]
|
26
|
+
File.open(@cmd_options[:out_file], 'w') {|f| f.write(@output) }
|
27
|
+
puts "Message #{@cmd}ed. You can find the results in the file: #{@cmd_options[:out_file]}\n"
|
28
|
+
else
|
29
|
+
puts @output
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
SUB_COMMANDS = %w[encrypt decrypt]
|
34
|
+
|
35
|
+
def parse_options!
|
36
|
+
version_str = File.exist?('VERSION') ? File.read('VERSION') : ""
|
37
|
+
|
38
|
+
Trollop::options do
|
39
|
+
banner <<-EOS
|
40
|
+
pontifex will encrypt, or decrypt messages.
|
41
|
+
|
42
|
+
Usage:
|
43
|
+
pontifex [options]
|
44
|
+
pontifex encrypt [options] [file ...]
|
45
|
+
pontifex decrypt [options] [file ...]
|
46
|
+
where [options] are:
|
47
|
+
EOS
|
48
|
+
version version_str
|
49
|
+
stop_on SUB_COMMANDS
|
50
|
+
end
|
51
|
+
|
52
|
+
@cmd = ARGV.shift
|
53
|
+
@cmd_options = case @cmd
|
54
|
+
when "encrypt"
|
55
|
+
Trollop::options do
|
56
|
+
banner <<-EOS
|
57
|
+
pontifex will encrypt messages from STDIN or from files.
|
58
|
+
|
59
|
+
Usage:
|
60
|
+
pontifex encrypt [options] [file ...]
|
61
|
+
where [options] are:
|
62
|
+
EOS
|
63
|
+
version version_str
|
64
|
+
opt :deck_key, "A file setting the key (a deck of cards) in a specific, initial order", :type => :string
|
65
|
+
opt :out_file, "An output file for the encrypted message", :type => :string
|
66
|
+
end
|
67
|
+
|
68
|
+
when "decrypt"
|
69
|
+
Trollop::options do
|
70
|
+
banner <<-EOS
|
71
|
+
pontifex will decrypt messages from STDIN or from files.
|
72
|
+
|
73
|
+
Usage:
|
74
|
+
pontifex decrypt [options] [file ...]
|
75
|
+
where [options] are:
|
76
|
+
EOS
|
77
|
+
version version_str
|
78
|
+
opt :deck_key, "A file setting the key (a deck of cards) in a specific, initial order", :type => :string
|
79
|
+
opt :out_file, "An output file for the decrypted message", :type => :string
|
80
|
+
end
|
81
|
+
|
82
|
+
else
|
83
|
+
Trollop::die "Either 'encrypt' or 'decrypt' must be passed as a sub-command"
|
84
|
+
end
|
85
|
+
|
86
|
+
key = ""
|
87
|
+
if @cmd_options[:deck_key]
|
88
|
+
Trollop::die "Can't find #{@cmd_options[:deck_key]} key file" unless File.exists?(@cmd_options[:deck_key])
|
89
|
+
|
90
|
+
File.open(@cmd_options[:deck_key], "r") do |infile|
|
91
|
+
while (line = infile.gets)
|
92
|
+
key << line.chomp
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if ARGV.empty?
|
98
|
+
puts "Enter the message to encrypt."
|
99
|
+
puts "enter 'Done' on a line by itself when you are done"
|
100
|
+
end
|
101
|
+
|
102
|
+
message = ""
|
103
|
+
while input = gets
|
104
|
+
break if input.nil? || input.chomp.downcase == "done"
|
105
|
+
message << input.chomp
|
106
|
+
end
|
107
|
+
|
108
|
+
if key.empty?
|
109
|
+
@pontifex = Cipher.new(message)
|
110
|
+
else
|
111
|
+
@pontifex = Cipher.new(message, key)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/pontifex.gemspec
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{pontifex}
|
8
|
+
s.version = "1.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Errin Larsen"]
|
12
|
+
s.date = %q{2011-06-01}
|
13
|
+
s.default_executable = %q{pontifex}
|
14
|
+
s.description = %q{This gem is a solution to ruby quiz #1: http://www.rubyquiz.com/quiz1.html}
|
15
|
+
s.email = %q{errinlarsen@gmail.com}
|
16
|
+
s.executables = ["pontifex"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE.txt",
|
19
|
+
"README.markdown"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".rvmrc",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.markdown",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"bin/pontifex",
|
30
|
+
"cucumber.yml",
|
31
|
+
"feature/pontifex_interactive.feature",
|
32
|
+
"feature/pontifex_with_files.feature",
|
33
|
+
"feature/support/env.rb",
|
34
|
+
"lib/pontifex.rb",
|
35
|
+
"lib/pontifex/card.rb",
|
36
|
+
"lib/pontifex/cipher.rb",
|
37
|
+
"lib/pontifex/key_stream.rb",
|
38
|
+
"pontifex.gemspec",
|
39
|
+
"spec/pontifex/card_spec.rb",
|
40
|
+
"spec/pontifex/cipher_spec.rb",
|
41
|
+
"spec/pontifex/key_stream_spec.rb",
|
42
|
+
"spec/pontifex/pontifex_spec.rb",
|
43
|
+
"spec/spec_helper.rb",
|
44
|
+
"vendor/cache/aruba-0.3.6.gem",
|
45
|
+
"vendor/cache/builder-3.0.0.gem",
|
46
|
+
"vendor/cache/childprocess-0.1.9.gem",
|
47
|
+
"vendor/cache/cucumber-0.10.3.gem",
|
48
|
+
"vendor/cache/diff-lcs-1.1.2.gem",
|
49
|
+
"vendor/cache/ffi-1.0.9.gem",
|
50
|
+
"vendor/cache/gherkin-2.3.9.gem",
|
51
|
+
"vendor/cache/git-1.2.5.gem",
|
52
|
+
"vendor/cache/jeweler-1.6.0.gem",
|
53
|
+
"vendor/cache/json-1.5.1.gem",
|
54
|
+
"vendor/cache/rake-0.9.0.gem",
|
55
|
+
"vendor/cache/rcov-0.9.9.gem",
|
56
|
+
"vendor/cache/rspec-2.6.0.gem",
|
57
|
+
"vendor/cache/rspec-core-2.6.3.gem",
|
58
|
+
"vendor/cache/rspec-expectations-2.6.0.gem",
|
59
|
+
"vendor/cache/rspec-mocks-2.6.0.gem",
|
60
|
+
"vendor/cache/term-ansicolor-1.0.5.gem",
|
61
|
+
"vendor/cache/trollop-1.16.2.gem"
|
62
|
+
]
|
63
|
+
s.homepage = %q{http://github.com/errinlarsen/pontifex}
|
64
|
+
s.licenses = ["MIT"]
|
65
|
+
s.require_paths = ["lib"]
|
66
|
+
s.rubygems_version = %q{1.6.2}
|
67
|
+
s.summary = %q{An implementation of the Solitaire Cipher in Ruby}
|
68
|
+
|
69
|
+
if s.respond_to? :specification_version then
|
70
|
+
s.specification_version = 3
|
71
|
+
|
72
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
73
|
+
s.add_runtime_dependency(%q<trollop>, [">= 0"])
|
74
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
|
75
|
+
s.add_development_dependency(%q<cucumber>, [">= 0"])
|
76
|
+
s.add_development_dependency(%q<aruba>, [">= 0"])
|
77
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
78
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.0"])
|
79
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
80
|
+
else
|
81
|
+
s.add_dependency(%q<trollop>, [">= 0"])
|
82
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
83
|
+
s.add_dependency(%q<cucumber>, [">= 0"])
|
84
|
+
s.add_dependency(%q<aruba>, [">= 0"])
|
85
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
86
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
87
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
88
|
+
end
|
89
|
+
else
|
90
|
+
s.add_dependency(%q<trollop>, [">= 0"])
|
91
|
+
s.add_dependency(%q<rspec>, ["~> 2.6.0"])
|
92
|
+
s.add_dependency(%q<cucumber>, [">= 0"])
|
93
|
+
s.add_dependency(%q<aruba>, [">= 0"])
|
94
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
95
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
96
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pontifex
|
4
|
+
describe Card do
|
5
|
+
describe "#new" do
|
6
|
+
describe "input validations" do
|
7
|
+
it "should raise an error with an input paramter that is less than 2 characters" do
|
8
|
+
expect { Card.new("5") }.to raise_error ArgumentError, "Cards must be 2 characters long"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should raise an error with an input paramter that is more than 2 characters" do
|
12
|
+
expect { Card.new("5As") }.to raise_error ArgumentError, "Cards must be 2 characters long"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should raise an error with an input parameter outside of the letters j,A,T,J,Q or K and the numbers 2-9 as the first character" do
|
16
|
+
expect { Card.new("bs") }.to raise_error ArgumentError, "first character of a card must be one of [2-9,j,A,T,J,Q,K]"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should raise an error with an input parameter outside of the letters c,d,h,s,a,b as the second character"do
|
20
|
+
expect { Card.new("9g") }.to raise_error ArgumentError, "second character of a card must be one of [a,b,c,d,h,s]"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise an error with a valid card value character, but with a suit of 'a' or 'b'" do
|
24
|
+
expect { Card.new("9b") }.to raise_error ArgumentError, "only Jokers may have a suit of 'a' or 'b'"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should raise an error with an input parameter of a Joker with a suit other than 'a' or 'b'" do
|
28
|
+
expect { Card.new("jd") }.to raise_error ArgumentError, "Jokers may not have a suit other than 'a' or 'b'"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "Card integer values" do
|
33
|
+
it "should create a card with a value of 2 if '2c' is input as a parameter" do
|
34
|
+
Card.new("2c").to_i.should == 2
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should create a card with a value of 25 if 'Qd' is input as a parameter" do
|
38
|
+
Card.new("Qd").to_i.should == 25
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should create a card with a value of 36 if 'Th' is input as a parameter" do
|
42
|
+
Card.new("Th").to_i.should == 36
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should create a card with a value of 40 if 'As' is input as a parameter" do
|
46
|
+
Card.new("As").to_i.should == 40
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should create a card with a value of 53 if 'ja' is input as a paramter" do
|
50
|
+
Card.new("ja").to_i.should == 53
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "Card letter values" do
|
55
|
+
it "should create a card with a letter of 'd' if '4c' is input as a parameter" do
|
56
|
+
Card.new("4c").to_c.should == "D"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should create a card with a letter of 'u' if 'Jd' is input as a parameter" do
|
60
|
+
Card.new("Jd").to_c.should == "X"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should create a card with a letter of 'j' if 'Th' is input as a parameter" do
|
64
|
+
Card.new("Th").to_c.should == "J"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should create a card with a letter of 'x' if 'Js' is input as a parameter" do
|
68
|
+
Card.new("Js").to_c.should == "X"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should create a card with a letter of NIL if 'Jb' is input as a paramter" do
|
72
|
+
Card.new("jb").to_c.should be_nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "Equality" do
|
77
|
+
it "should be equal to another card created with the same input as a parameter" do
|
78
|
+
param = "Qh"
|
79
|
+
Card.new(param).should == Card.new(param)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pontifex
|
4
|
+
describe Cipher do
|
5
|
+
let(:raw_unencrypted_msg) { "Code in Ruby, live longer!" }
|
6
|
+
let(:decrypted_msg) { "CODEI NRUBY LIVEL ONGER" }
|
7
|
+
let(:encrypted_msg) { "GLNCQ MJAFF FVOMB JIYCB" }
|
8
|
+
|
9
|
+
describe "#encrypted" do
|
10
|
+
it "should return an encrypted conversion of the input String paramter" do
|
11
|
+
msg = Cipher.new(raw_unencrypted_msg)
|
12
|
+
msg.encrypted.should == encrypted_msg
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#decrypted" do
|
17
|
+
it "should return a decrypted plain text conversion of the input String parameter" do
|
18
|
+
msg = Cipher.new(encrypted_msg)
|
19
|
+
msg.decrypted.should == decrypted_msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pontifex
|
4
|
+
describe KeyStream do
|
5
|
+
let(:default_key) do
|
6
|
+
"Ac,2c,3c,4c,5c,6c,7c,8c,9c,Tc,Jc,Qc,Kc," +
|
7
|
+
"Ad,2d,3d,4d,5d,6d,7d,8d,9d,Td,Jd,Qd,Kd," +
|
8
|
+
"Ah,2h,3h,4h,5h,6h,7h,8h,9h,Th,Jh,Qh,Kh," +
|
9
|
+
"As,2s,3s,4s,5s,6s,7s,8s,9s,Ts,Js,Qs,Ks," +
|
10
|
+
"ja,jb"
|
11
|
+
end
|
12
|
+
let(:key_stream) { KeyStream.new(default_key) }
|
13
|
+
|
14
|
+
it "should never contain more than one 'ja' or 'jb' joker" do
|
15
|
+
ks = key_stream
|
16
|
+
20.times { ks.sequence! }
|
17
|
+
ks.deck.select { |c| c.str =~/j[ab]/ }.count.should == 2
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should correctly generate new letters when continuously sequencing the deck" do
|
21
|
+
ks = key_stream
|
22
|
+
expected_string = "DWJXHYRFDGTMSHPUURXJ"
|
23
|
+
found_string = ""
|
24
|
+
while found_string.length < 20
|
25
|
+
ks.sequence!
|
26
|
+
next if ks.letter.nil?
|
27
|
+
found_string += ks.letter
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#new" do
|
32
|
+
it "should create a standard ordered deck by default" do
|
33
|
+
KeyStream.new.deck.should == default_key.split(",").map { |k| Card.new(k) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#deck" do
|
38
|
+
it "should return a representation of a deck of cards implemented with an Array" do
|
39
|
+
key_stream.deck.should be_an_instance_of(Array)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should contain nothing but Card instances" do
|
43
|
+
expected_count = key_stream.deck.count
|
44
|
+
key_stream.deck.select { |c| c.instance_of?(Card) }.count.should == expected_count
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should only contain each card once" do
|
48
|
+
expected_count = key_stream.deck.count
|
49
|
+
key_stream.deck.uniq.count.should == expected_count
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#sequence!" do
|
54
|
+
let(:expected_deck) do
|
55
|
+
key = "2c,3c,4c,5c,6c,7c,8c,9c,Tc,Jc,Qc,Kc," +
|
56
|
+
"Ad,2d,3d,4d,5d,6d,7d,8d,9d,Td,Jd,Qd,Kd," +
|
57
|
+
"Ah,2h,3h,4h,5h,6h,7h,8h,9h,Th,Jh,Qh,Kh," +
|
58
|
+
"As,2s,3s,4s,5s,6s,7s,8s,9s,Ts,Js,Qs,Ks," +
|
59
|
+
"ja,jb,Ac"
|
60
|
+
key.split(",").map { |str| Card.new(str) }
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should modify the deck" do
|
64
|
+
ks = KeyStream.new
|
65
|
+
ks.sequence!
|
66
|
+
ks.deck.should_not == KeyStream.new.deck
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should leave the deck modified according to the algorithm" do
|
70
|
+
ks = KeyStream.new
|
71
|
+
ks.sequence!
|
72
|
+
ks.deck.should == expected_deck
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#letter" do
|
77
|
+
it "should return a string" do
|
78
|
+
key_stream.letter.should be_an_instance_of(String)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should only return a single character" do
|
82
|
+
key_stream.letter.length.should == 1
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should return a 'D' after a single sequence of the default deck" do
|
86
|
+
key_stream.sequence!
|
87
|
+
key_stream.letter.should == 'D'
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require "pontifex"
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|