passphrase 0.1.0 → 1.0.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
- checksums.yaml.gz.sig +1 -0
- data.tar.gz.sig +1 -0
- data/CHANGELOG.md +35 -0
- data/LICENSE +19 -0
- data/README.md +178 -0
- data/bin/passphrase +3 -10
- data/lib/passphrase.rb +11 -0
- data/lib/passphrase/CLI.rb +76 -0
- data/lib/passphrase/default.rb +15 -0
- data/lib/passphrase/diceware_method.rb +67 -0
- data/lib/passphrase/diceware_random.rb +117 -0
- data/lib/passphrase/language_query.rb +26 -0
- data/lib/passphrase/passphrase.rb +80 -0
- data/lib/passphrase/version.rb +3 -12
- data/lib/passphrase/word_query.rb +21 -0
- data/lib/passphrase/wordlist/words.sqlite3 +0 -0
- data/spec/passphrase/cli_spec.rb +47 -0
- data/spec/passphrase/diceware_method_spec.rb +61 -0
- data/spec/passphrase/diceware_random_spec.rb +124 -0
- data/spec/passphrase/language_query_spec.rb +48 -0
- data/spec/passphrase/passphrase_spec.rb +118 -0
- data/spec/passphrase/word_query_spec.rb +30 -0
- data/spec/spec_helper.rb +91 -0
- metadata +168 -148
- metadata.gz.sig +0 -0
- data/Gemfile +0 -14
- data/Gemfile.lock +0 -16
- data/LICENSE.txt +0 -20
- data/README.rdoc +0 -62
- data/Rakefile +0 -33
- data/VERSION +0 -1
- data/lib/passphrase/data.rb +0 -1632
- data/lib/passphrase/generator.rb +0 -81
- data/lib/passphrase/options.rb +0 -65
- data/lib/passphrase/random.rb +0 -56
- data/lib/passphrase/wordlist.rb +0 -30
- data/test/test_options.rb +0 -33
- data/test/test_wordlist.rb +0 -17
@@ -0,0 +1,26 @@
|
|
1
|
+
module Passphrase
|
2
|
+
# This class encapsulates the {#count} and {#[]} queries against the
|
3
|
+
# "languages" table in the "words" SQLite 3 database.
|
4
|
+
class LanguageQuery
|
5
|
+
def initialize(db)
|
6
|
+
@db = db
|
7
|
+
end
|
8
|
+
|
9
|
+
# @return [Integer] the number of rows in the languages table
|
10
|
+
def count
|
11
|
+
sql = "SELECT COUNT(*) AS count FROM languages"
|
12
|
+
@db.get_first_value(sql)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param index [Integer] selects a specific row in the languages table
|
16
|
+
# @return [String] the language corresponding to the given index
|
17
|
+
def [](index)
|
18
|
+
sql = "SELECT language FROM languages"
|
19
|
+
unless @languages
|
20
|
+
@languages = []
|
21
|
+
@db.execute(sql).each { |lang| @languages << lang.first }
|
22
|
+
end
|
23
|
+
@languages[index]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Passphrase
|
2
|
+
# This is the main class of the Passphrase library for generating
|
3
|
+
# passphrases. It's initialized with a two-element hash that specifies the
|
4
|
+
# number of words in the resulting passphrase and a flag to use the
|
5
|
+
# RANDOM.ORG site as a source of random numbers.
|
6
|
+
# @example
|
7
|
+
# require "passphrase"
|
8
|
+
# p = Passphrase::Passphrase.new(number_of_words: 4, use_random_org: nil)
|
9
|
+
# puts p.generate
|
10
|
+
class Passphrase
|
11
|
+
|
12
|
+
# @return [String] the passphrase string
|
13
|
+
attr_reader :passphrase
|
14
|
+
|
15
|
+
# @param options [Hash] characteristics for a new Passphrase object
|
16
|
+
# @yieldparam obj [self] the Passphrase object
|
17
|
+
def initialize(options={})
|
18
|
+
@options = Default.options.merge(options)
|
19
|
+
@passphrase = ""
|
20
|
+
@languages = []
|
21
|
+
@die_rolls = []
|
22
|
+
@words = []
|
23
|
+
yield self if block_given?
|
24
|
+
end
|
25
|
+
|
26
|
+
# Invokes the Diceware method by running {DicewareMethod.run}. The three
|
27
|
+
# resulting arrays are accumulated into instance variables. The words
|
28
|
+
# array is formatted into a single passphrase string and stored in another
|
29
|
+
# instance variable. The method returns itself to allow method chaining.
|
30
|
+
# @return [self] a Passphrase object
|
31
|
+
def generate
|
32
|
+
@languages, @die_rolls, @words = DicewareMethod.run(@options)
|
33
|
+
@passphrase = @words.join(" ")
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# This virtual attribute accessor returns the number of words in the
|
38
|
+
# generated passphrase.
|
39
|
+
# @return [Integer] the number of words in the passphrase
|
40
|
+
def number_of_words
|
41
|
+
@words.size
|
42
|
+
end
|
43
|
+
|
44
|
+
# A predicate method that returns true if the Passphrase object is
|
45
|
+
# initialized to use RANDOM.ORG
|
46
|
+
# @return [Boolean] returns true of RANDOM.ORG is being used
|
47
|
+
def using_random_org?
|
48
|
+
@options[:use_random_org]
|
49
|
+
end
|
50
|
+
|
51
|
+
# String representation of a Passphrase object
|
52
|
+
# @return [String] the passphrase string
|
53
|
+
def to_s
|
54
|
+
@passphrase
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns details for the Passphrase object as a hash.
|
58
|
+
# @return [Hash] the details of a Passphrase object
|
59
|
+
def inspect
|
60
|
+
{
|
61
|
+
passphrase: @passphrase,
|
62
|
+
number_of_words: @words.size,
|
63
|
+
word_origins: word_origins
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def word_origins
|
70
|
+
word_origins = {}
|
71
|
+
@words.each_index do |index|
|
72
|
+
word_origins[@words[index]] = {
|
73
|
+
language: @languages[index],
|
74
|
+
die_rolls: @die_rolls[index]
|
75
|
+
}
|
76
|
+
end
|
77
|
+
word_origins
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/passphrase/version.rb
CHANGED
@@ -1,14 +1,5 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
|
3
1
|
module Passphrase
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# http://docs.rubygems.org/read/chapter/7
|
8
|
-
MAJOR = 0
|
9
|
-
MINOR = 1
|
10
|
-
BUILD = 0
|
11
|
-
|
12
|
-
STRING = [MAJOR, MINOR, BUILD].compact.join('.')
|
13
|
-
end
|
2
|
+
# Version numbers are bumped according to {http://semver.org Semantic
|
3
|
+
# Versioning}.
|
4
|
+
VERSION = "1.0.0"
|
14
5
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Passphrase
|
2
|
+
# This class encapsulates the {#where} query against the "words" table in
|
3
|
+
# the "words" SQLite 3 database. The filter parameter must be a hash that
|
4
|
+
# specifies a language and sequence of die rolls.
|
5
|
+
# @example
|
6
|
+
# {language: "afrikaans", die_rolls: "11111"}
|
7
|
+
class WordQuery
|
8
|
+
def initialize(db)
|
9
|
+
@db = db
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param filter [Hash] specifies the language/die_roll combination
|
13
|
+
# @return [String] the selected words from the wordlist
|
14
|
+
def where(filter)
|
15
|
+
sql = "SELECT words " +
|
16
|
+
"FROM words " +
|
17
|
+
"WHERE language = :language AND die_rolls = :die_rolls"
|
18
|
+
@db.get_first_value(sql, filter)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "passphrase"
|
2
|
+
require "optparse"
|
3
|
+
|
4
|
+
module Passphrase
|
5
|
+
RSpec.describe CLI, "implements the command line interface" do
|
6
|
+
it "responds to class method parse() with one argument" do
|
7
|
+
expect(CLI).to respond_to(:parse).with(1).argument
|
8
|
+
end
|
9
|
+
|
10
|
+
it "does not respond to class method validate_number_of_words() (private)" do
|
11
|
+
expect(CLI).not_to respond_to(:validate_number_of_words)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "does not respond to class method handle_error() (private)" do
|
15
|
+
expect(CLI).not_to respond_to(:handle_error)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "emits an error when an invalid option is supplied" do
|
19
|
+
# For some reason, :handle_error doesn't need to be stubbed
|
20
|
+
expect(CLI).to receive(:handle_error)
|
21
|
+
.with(kind_of(OptionParser::InvalidOption))
|
22
|
+
bad_option = ["-x"]
|
23
|
+
CLI.parse(bad_option)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "emits an error when a mandatory argument is missing" do
|
27
|
+
# For some reason, :handle_error doesn't need to be stubbed
|
28
|
+
expect(CLI).to receive(:handle_error).twice
|
29
|
+
.with(kind_of(OptionParser::MissingArgument))
|
30
|
+
[["-n"], ["--num-words"]].each { |bad_option| CLI.parse(bad_option) }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "emits an error when the number of words is out of range" do
|
34
|
+
under_range = (Default.number_range.min - 1).to_s
|
35
|
+
over_range = (Default.number_range.max + 1).to_s
|
36
|
+
# For some reason, :handle_error doesn't need to be stubbed
|
37
|
+
expect(CLI).to receive(:handle_error).exactly(4).times
|
38
|
+
.with(kind_of(RuntimeError))
|
39
|
+
["-n", "--num-words"].each do |opt|
|
40
|
+
[under_range, over_range].each do |arg|
|
41
|
+
bad_option = [opt, arg]
|
42
|
+
CLI.parse(bad_option)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "passphrase"
|
2
|
+
|
3
|
+
module Passphrase
|
4
|
+
RSpec.describe DicewareMethod, "implements the Diceware method" do
|
5
|
+
it "responds to the class method run() with one argument" do
|
6
|
+
expect(DicewareMethod).to respond_to(:run).with(1).argument
|
7
|
+
end
|
8
|
+
|
9
|
+
context "initialized with given options" do
|
10
|
+
before do
|
11
|
+
@number_of_words = 5
|
12
|
+
options = { number_of_words: @number_of_words, use_random_org: nil }
|
13
|
+
@diceware = DicewareMethod.new(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "responds to the run() method with no arguments" do
|
17
|
+
expect(@diceware).to respond_to(:run)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "does not respond to the setup_database() method (private)" do
|
21
|
+
expect(@diceware).not_to respond_to(:setup_database)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "does not respond to the setup_queries() method (private)" do
|
25
|
+
expect(@diceware).not_to respond_to(:setup_queries)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "does not respond to the get_random_languages() method (private)" do
|
29
|
+
expect(@diceware).not_to respond_to(:get_random_languages)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not respond to the get_random_random_die_rolls() method (private)" do
|
33
|
+
expect(@diceware).not_to respond_to(:get_random_random_die_rolls)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "does not respond to the select_words_from_wordlist() method (private)" do
|
37
|
+
expect(@diceware).not_to respond_to(:select_words_from_wordlist)
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#run" do
|
41
|
+
before do
|
42
|
+
@result = @diceware.run
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns an array of three arrays" do
|
46
|
+
expect(@result).to contain_exactly(
|
47
|
+
an_instance_of(Array),
|
48
|
+
an_instance_of(Array),
|
49
|
+
an_instance_of(Array)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "each array is of size given by the number of words specified" do
|
54
|
+
@result.each do |result|
|
55
|
+
expect(result.size).to eq(@number_of_words)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require "passphrase"
|
2
|
+
|
3
|
+
module Passphrase
|
4
|
+
RSpec.shared_examples "DicewareRandom object" do
|
5
|
+
it "responds to the indices() method with 2 args" do
|
6
|
+
expect(@random).to respond_to(:indices).with(2).arguments
|
7
|
+
end
|
8
|
+
|
9
|
+
it "responds to the die_rolls() method with 1 arg" do
|
10
|
+
expect(@random).to respond_to(:die_rolls).with(1).arguments
|
11
|
+
end
|
12
|
+
|
13
|
+
it "does not respond to the setup_remote_generator() method (private)" do
|
14
|
+
expect(@random).not_to respond_to(:setup_remote_generator)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "does not respond to the setup_local_generator() method (private)" do
|
18
|
+
expect(@random).not_to respond_to(:setup_local_generator)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "does not respond to the generate_random_numbers() method (private)" do
|
22
|
+
expect(@random).not_to respond_to(:generate_random_numbers)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "does not respond to the group_die_rolls() method (private)" do
|
26
|
+
expect(@random).not_to respond_to(:group_die_rolls)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#indices(4, 15)" do
|
30
|
+
before do
|
31
|
+
@result = @random.indices(4, 15)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns an array" do
|
35
|
+
expect(@result).to be_an_instance_of(Array)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "of size 4" do
|
39
|
+
expect(@result.size).to eq(4)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "all Fixnum items" do
|
43
|
+
expect(@result).to all be_an_instance_of(Fixnum)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "each one in the range 0...15" do
|
47
|
+
expect(@result).to all be_between(0, 14)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#die_rolls(6)" do
|
52
|
+
before do
|
53
|
+
@result = @random.die_rolls(6)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "returns an array" do
|
57
|
+
expect(@result).to be_an_instance_of(Array)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "of size 6" do
|
61
|
+
expect(@result.size).to eq(6)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "all String items" do
|
65
|
+
expect(@result).to all be_an_instance_of(String)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "each one five characters long" do
|
69
|
+
expect(@result.map(&:length)).to all eq(5)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "that match the pattern /^[123456]+$/" do
|
73
|
+
expect(@result).to all match(/^[123456]+$/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
RSpec.describe DicewareRandom, "generates and formats arrays of random numbers" do
|
79
|
+
it "responds to the attribute reader method random_org_requests()" do
|
80
|
+
expect(DicewareRandom).to respond_to(:random_org_requests)
|
81
|
+
end
|
82
|
+
|
83
|
+
context "initialized by default to use the local Ruby random number generator" do
|
84
|
+
before do
|
85
|
+
@random = DicewareRandom.new
|
86
|
+
end
|
87
|
+
|
88
|
+
include_examples "DicewareRandom object"
|
89
|
+
end
|
90
|
+
|
91
|
+
context "initialized to use random numbers from RANDOM.ORG" do
|
92
|
+
before do
|
93
|
+
@random = DicewareRandom.new(:use_random_org)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "initially has a zero random.org request count" do
|
97
|
+
expect(DicewareRandom.random_org_requests).to eq(0)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "increments the random.org request count on indices()" do
|
101
|
+
expect {
|
102
|
+
@random.indices(4, 15)
|
103
|
+
}.to change(DicewareRandom, :random_org_requests).by(1)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "increments the RANDOM.ORG request count on die_rolls()" do
|
107
|
+
expect {
|
108
|
+
@random.die_rolls(4)
|
109
|
+
}.to change(DicewareRandom, :random_org_requests).by(1)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "does not respond to the check_random_org_quota() method (private)" do
|
113
|
+
expect(@random).not_to respond_to(:check_random_org_quota)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "raises an exception when a network error occurs (e.g. wrong address)" do
|
117
|
+
@random.instance_eval { @random_org_uri = "https://www.randomx.org" }
|
118
|
+
expect { @random.indices(4, 15) }.to raise_error
|
119
|
+
end
|
120
|
+
|
121
|
+
include_examples "DicewareRandom object"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "passphrase"
|
2
|
+
|
3
|
+
module Passphrase
|
4
|
+
RSpec.describe LanguageQuery, "queries the languages table in a valid wordlist database" do
|
5
|
+
before do
|
6
|
+
wordlist_file = "../../lib/passphrase/wordlist/words.sqlite3"
|
7
|
+
wordlist_path = File.join(File.dirname(__FILE__), wordlist_file)
|
8
|
+
db = SQLite3::Database.new(wordlist_path, readonly: true)
|
9
|
+
@languages = LanguageQuery.new(db)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "responds to the count() method with no arguments" do
|
13
|
+
expect(@languages).to respond_to(:count).with(0).arguments
|
14
|
+
end
|
15
|
+
|
16
|
+
it "responds to the []() method with one argument" do
|
17
|
+
expect(@languages).to respond_to(:[]).with(1).argument
|
18
|
+
end
|
19
|
+
|
20
|
+
context "#count" do
|
21
|
+
before do
|
22
|
+
@count = @languages.count
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns an integer" do
|
26
|
+
expect(@count).to be_an_instance_of(Fixnum)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "greater than zero" do
|
30
|
+
expect(@count).to be > 0
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "#[](0)" do
|
35
|
+
before do
|
36
|
+
@language = @languages[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns a string" do
|
40
|
+
expect(@language).to be_an_instance_of(String)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "that is not empty" do
|
44
|
+
expect(@language).not_to be_empty
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require "passphrase"
|
2
|
+
|
3
|
+
module Passphrase
|
4
|
+
RSpec.describe Passphrase, "for generating passphrase objects" do
|
5
|
+
it "yields itself during instantiation" do
|
6
|
+
expect { |b| Passphrase.new(Default.options, &b) }.to yield_with_args(Passphrase)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Dependence on RANDOM.ORG only affects the DicewareRandom class.
|
10
|
+
# Therefore, only need to test the case where RANDOM.ORG is not used.
|
11
|
+
context "initialized to generate a passphrase with 1 word, not using RANDOM.ORG" do
|
12
|
+
before do
|
13
|
+
@passphrase = Passphrase.new(number_of_words: 1, use_random_org: nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "responds to the generate() method with zero arguments" do
|
17
|
+
expect(@passphrase).to respond_to(:generate).with(0).arguments
|
18
|
+
end
|
19
|
+
|
20
|
+
it "responds to the to_s() method" do
|
21
|
+
expect(@passphrase).to respond_to(:to_s)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "responds to the inspect() method with zero arguments" do
|
25
|
+
expect(@passphrase).to respond_to(:inspect).with(0).arguments
|
26
|
+
end
|
27
|
+
|
28
|
+
it "responds to attribute reader method passphrase()" do
|
29
|
+
expect(@passphrase).to respond_to(:passphrase)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "responds to predicate method using_random_org?()" do
|
33
|
+
expect(@passphrase).to respond_to(:using_random_org?)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "responds to virtual attribute reader method number_of_words()" do
|
37
|
+
expect(@passphrase).to respond_to(:number_of_words).with(0).arguments
|
38
|
+
end
|
39
|
+
|
40
|
+
it "does not respond to the word_origins() method (private)" do
|
41
|
+
expect(@passphrase).not_to respond_to(:word_origins)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "initially contains an empty passphrase string" do
|
45
|
+
expect(@passphrase.passphrase).to be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
it "initially contains zero words" do
|
49
|
+
expect(@passphrase.number_of_words).to eq(0)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should not be using RANDOM.ORG" do
|
53
|
+
expect(@passphrase).not_to be_using_random_org
|
54
|
+
end
|
55
|
+
|
56
|
+
context "after executing the generate() method" do
|
57
|
+
before do
|
58
|
+
dwr = [["language"], ["11111"], ["passphrase"]]
|
59
|
+
allow(DicewareMethod).to receive(:run).and_return(dwr)
|
60
|
+
@result = @passphrase.generate
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns itself" do
|
64
|
+
expect(@result).to equal(@passphrase)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "contains the passphrase string" do
|
68
|
+
expect(@result.passphrase).to eq("passphrase")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "contains a number of words equal to one" do
|
72
|
+
expect(@result.number_of_words).to eq(1)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "returns the passphrase when printed" do
|
76
|
+
sio = StringIO.new("")
|
77
|
+
$stdout = sio
|
78
|
+
expect { puts @result }.to change { sio.string.chomp }
|
79
|
+
.from("").to(@result.passphrase)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "can be inspected" do
|
83
|
+
expect(@result.inspect).to match(
|
84
|
+
passphrase: "passphrase",
|
85
|
+
number_of_words: 1,
|
86
|
+
word_origins: { "passphrase" => {
|
87
|
+
language: "language",
|
88
|
+
die_rolls: "11111"
|
89
|
+
}
|
90
|
+
}
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "initialized to use RANDOM.ORG" do
|
97
|
+
it "the predicate method should confirm it is using RANDOM.ORG" do
|
98
|
+
passphrase = Passphrase.new(number_of_words: 3, use_random_org: true)
|
99
|
+
expect(passphrase).to be_using_random_org
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "initialized with default options" do
|
104
|
+
before do
|
105
|
+
@passphrase = Passphrase.new
|
106
|
+
@passphrase.generate
|
107
|
+
end
|
108
|
+
|
109
|
+
it "return a passphrase with the default number of words" do
|
110
|
+
expect(@passphrase.number_of_words).to eq(Default.options[:number_of_words])
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should not be using RANDOM.ORG" do
|
114
|
+
expect(@passphrase).not_to be_using_random_org
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|