pontifex 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|