passwd 0.1.5 → 0.2.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 +4 -4
- data/.travis.yml +4 -1
- data/CHANGELOG.md +30 -1
- data/Gemfile +0 -5
- data/LICENSE.txt +2 -1
- data/README.md +96 -156
- data/Rakefile +2 -1
- data/example/.gitignore +16 -0
- data/example/Gemfile +25 -0
- data/example/README.rdoc +28 -0
- data/example/Rakefile +6 -0
- data/example/app/assets/images/.keep +0 -0
- data/example/app/assets/javascripts/application.js +16 -0
- data/example/app/assets/stylesheets/application.css +16 -0
- data/example/app/controllers/application_controller.rb +10 -0
- data/example/app/controllers/concerns/.keep +0 -0
- data/example/app/controllers/profiles_controller.rb +28 -0
- data/example/app/controllers/root_controller.rb +5 -0
- data/example/app/controllers/sessions_controller.rb +29 -0
- data/example/app/helpers/application_helper.rb +2 -0
- data/example/app/mailers/.keep +0 -0
- data/example/app/models/.keep +0 -0
- data/example/app/models/concerns/.keep +0 -0
- data/example/app/models/user.rb +4 -0
- data/example/app/views/layouts/application.html.erb +15 -0
- data/example/app/views/profiles/edit.html.erb +14 -0
- data/example/app/views/profiles/show.html.erb +12 -0
- data/example/app/views/root/index.html.erb +5 -0
- data/example/app/views/sessions/new.html.erb +6 -0
- data/example/bin/bundle +3 -0
- data/example/bin/rails +4 -0
- data/example/bin/rake +4 -0
- data/example/config.ru +4 -0
- data/example/config/application.rb +40 -0
- data/example/config/boot.rb +4 -0
- data/example/config/database.yml +26 -0
- data/example/config/environment.rb +5 -0
- data/example/config/environments/development.rb +37 -0
- data/example/config/environments/production.rb +78 -0
- data/example/config/environments/test.rb +39 -0
- data/example/config/initializers/assets.rb +8 -0
- data/example/config/initializers/backtrace_silencers.rb +7 -0
- data/example/config/initializers/cookies_serializer.rb +3 -0
- data/example/config/initializers/filter_parameter_logging.rb +4 -0
- data/example/config/initializers/inflections.rb +16 -0
- data/example/config/initializers/mime_types.rb +4 -0
- data/example/config/initializers/passwd.rb +41 -0
- data/example/config/initializers/session_store.rb +3 -0
- data/example/config/initializers/wrap_parameters.rb +14 -0
- data/example/config/locales/en.yml +23 -0
- data/example/config/routes.rb +16 -0
- data/example/config/secrets.yml +22 -0
- data/example/db/migrate/20141122165914_create_users.rb +13 -0
- data/example/db/schema.rb +25 -0
- data/example/db/seeds.rb +7 -0
- data/example/lib/assets/.keep +0 -0
- data/example/lib/tasks/.keep +0 -0
- data/example/lib/tasks/user.rake +12 -0
- data/example/log/.keep +0 -0
- data/example/public/404.html +67 -0
- data/example/public/422.html +67 -0
- data/example/public/500.html +66 -0
- data/example/public/favicon.ico +0 -0
- data/example/public/robots.txt +5 -0
- data/example/vendor/assets/javascripts/.keep +0 -0
- data/example/vendor/assets/stylesheets/.keep +0 -0
- data/lib/generators/passwd/config_generator.rb +13 -0
- data/lib/generators/passwd/templates/passwd_config.rb +41 -0
- data/lib/passwd.rb +18 -3
- data/lib/passwd/action_controller_ext.rb +48 -0
- data/lib/passwd/active_record_ext.rb +65 -0
- data/lib/passwd/base.rb +17 -62
- data/lib/passwd/configuration.rb +82 -0
- data/lib/passwd/errors.rb +6 -13
- data/lib/passwd/password.rb +73 -25
- data/lib/passwd/policy.rb +28 -0
- data/lib/passwd/railtie.rb +19 -0
- data/lib/passwd/salt.rb +50 -0
- data/lib/passwd/version.rb +2 -1
- data/passwd.gemspec +8 -2
- data/spec/passwd/.keep +0 -0
- data/spec/passwd/active_record_ext_spec.rb +80 -0
- data/spec/passwd/base_spec.rb +55 -231
- data/spec/passwd/configuration_spec.rb +50 -0
- data/spec/passwd/password_spec.rb +129 -123
- data/spec/spec_helper.rb +14 -3
- data/spec/support/data_util.rb +11 -0
- data/spec/support/paths.rb +2 -0
- metadata +164 -30
- data/lib/passwd/active_record.rb +0 -62
- data/lib/passwd/configuration/abstract_config.rb +0 -37
- data/lib/passwd/configuration/config.rb +0 -24
- data/lib/passwd/configuration/policy.rb +0 -46
- data/lib/passwd/configuration/tmp_config.rb +0 -18
- data/spec/passwd/active_record_spec.rb +0 -163
- data/spec/passwd/configuration/config_spec.rb +0 -250
- data/spec/passwd/configuration/policy_spec.rb +0 -133
- data/spec/passwd/configuration/tmp_config_spec.rb +0 -265
data/lib/passwd/active_record.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Passwd
|
4
|
-
module ActiveRecord
|
5
|
-
module ClassMethods
|
6
|
-
def define_column(options={})
|
7
|
-
id_name = options.fetch(:id, :email)
|
8
|
-
salt_name = options.fetch(:salt, :salt)
|
9
|
-
password_name = options.fetch(:password, :password)
|
10
|
-
|
11
|
-
define_singleton_auth(id_name, salt_name, password_name)
|
12
|
-
define_instance_auth(id_name, salt_name, password_name)
|
13
|
-
define_set_password(id_name, salt_name, password_name)
|
14
|
-
define_update_password(salt_name, password_name)
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
def define_singleton_auth(id_name, salt_name, password_name)
|
19
|
-
define_singleton_method :authenticate do |id, pass|
|
20
|
-
user = self.where(id_name => id).first
|
21
|
-
user if user && Passwd.auth(pass, user.send(salt_name), user.send(password_name))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def define_instance_auth(id_name, salt_name, password_name)
|
26
|
-
define_method :authenticate do |pass|
|
27
|
-
Passwd.auth(pass, self.send(salt_name), self.send(password_name))
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def define_set_password(id_name, salt_name, password_name)
|
32
|
-
define_method :set_password do |pass=nil|
|
33
|
-
password = pass || Passwd.create
|
34
|
-
salt = self.send(salt_name) || Passwd.hashing("#{self.send(id_name)}#{Time.now.to_s}")
|
35
|
-
self.send("#{salt_name.to_s}=", salt)
|
36
|
-
self.send("#{password_name.to_s}=", Passwd.hashing("#{salt}#{password}"))
|
37
|
-
password
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def define_update_password(salt_name, password_name)
|
42
|
-
define_method :update_password do |old_pass, new_pass, policy_check=false|
|
43
|
-
if Passwd.auth(old_pass, self.send(salt_name), self.send(password_name))
|
44
|
-
if policy_check
|
45
|
-
raise Passwd::PolicyNotMatch, "Policy not match" unless Passwd.policy_check(new_pass)
|
46
|
-
end
|
47
|
-
|
48
|
-
set_password(new_pass)
|
49
|
-
else
|
50
|
-
raise Passwd::AuthError
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
class << self
|
57
|
-
def included(base)
|
58
|
-
base.extend ClassMethods
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Passwd
|
4
|
-
class AbstractConfig
|
5
|
-
VALID_OPTIONS_KEYS = [
|
6
|
-
:algorithm,
|
7
|
-
:length,
|
8
|
-
:lower,
|
9
|
-
:upper,
|
10
|
-
:number,
|
11
|
-
:letters_lower,
|
12
|
-
:letters_upper,
|
13
|
-
:letters_number
|
14
|
-
].freeze
|
15
|
-
|
16
|
-
attr_accessor *VALID_OPTIONS_KEYS
|
17
|
-
|
18
|
-
def configure
|
19
|
-
yield self
|
20
|
-
end
|
21
|
-
|
22
|
-
def merge(configs)
|
23
|
-
configs.keys.each do |k|
|
24
|
-
send("#{k}=", configs[k])
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def letters
|
29
|
-
chars = []
|
30
|
-
chars.concat(self.letters_lower) if self.lower
|
31
|
-
chars.concat(self.letters_upper) if self.upper
|
32
|
-
chars.concat(self.letters_number) if self.number
|
33
|
-
raise "letters is empty" if chars.empty?
|
34
|
-
chars
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require "passwd/configuration/abstract_config"
|
4
|
-
|
5
|
-
module Passwd
|
6
|
-
class Config < AbstractConfig
|
7
|
-
include Singleton
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
reset
|
11
|
-
end
|
12
|
-
|
13
|
-
def reset
|
14
|
-
self.algorithm = :sha512
|
15
|
-
self.length = 8
|
16
|
-
self.lower = true
|
17
|
-
self.upper = true
|
18
|
-
self.number = true
|
19
|
-
self.letters_lower = ("a".."z").to_a
|
20
|
-
self.letters_upper = ("A".."Z").to_a
|
21
|
-
self.letters_number = ("0".."9").to_a
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
module Passwd
|
4
|
-
class Policy
|
5
|
-
include Singleton
|
6
|
-
|
7
|
-
VALID_OPTIONS_KEYS = [
|
8
|
-
:min_length,
|
9
|
-
:require_lower,
|
10
|
-
:require_upper,
|
11
|
-
:require_number
|
12
|
-
].freeze
|
13
|
-
|
14
|
-
attr_accessor *VALID_OPTIONS_KEYS
|
15
|
-
|
16
|
-
def initialize
|
17
|
-
reset
|
18
|
-
end
|
19
|
-
|
20
|
-
def configure
|
21
|
-
yield self
|
22
|
-
end
|
23
|
-
|
24
|
-
def valid?(password, config)
|
25
|
-
return false if self.min_length > password.size
|
26
|
-
return false if self.require_lower && !include_char?(config.letters_lower, password)
|
27
|
-
return false if self.require_upper && !include_char?(config.letters_upper, password)
|
28
|
-
return false if self.require_number && !include_char?(config.letters_number, password)
|
29
|
-
true
|
30
|
-
end
|
31
|
-
|
32
|
-
def include_char?(letters, strings)
|
33
|
-
strings.each_char do |c|
|
34
|
-
return true if letters.include? c
|
35
|
-
end
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
|
-
def reset
|
40
|
-
self.min_length = 8
|
41
|
-
self.require_lower = true
|
42
|
-
self.require_upper = false
|
43
|
-
self.require_number = true
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require "passwd/configuration/abstract_config"
|
4
|
-
|
5
|
-
module Passwd
|
6
|
-
class TmpConfig < AbstractConfig
|
7
|
-
def initialize(config, options)
|
8
|
-
config.instance_variables.each do |v|
|
9
|
-
key = v.to_s.sub(/^@/, "").to_sym
|
10
|
-
if options.has_key? key
|
11
|
-
instance_variable_set v, options[key]
|
12
|
-
else
|
13
|
-
instance_variable_set v, config.instance_variable_get(v)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,163 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe Passwd::ActiveRecord do
|
6
|
-
class User
|
7
|
-
include Passwd::ActiveRecord
|
8
|
-
define_column
|
9
|
-
end
|
10
|
-
|
11
|
-
let(:salt) {Digest::SHA512.hexdigest("salt")}
|
12
|
-
let(:password_text) {"secret"}
|
13
|
-
let(:password_hash) {Digest::SHA512.hexdigest("#{salt}#{password_text}")}
|
14
|
-
|
15
|
-
describe ".#included" do
|
16
|
-
it "define singleton methods" do
|
17
|
-
expect(User.respond_to? :define_column).to be_true
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "extend methods" do
|
22
|
-
describe ".#define_column" do
|
23
|
-
let(:user) {User.new}
|
24
|
-
|
25
|
-
it "define singleton methods" do
|
26
|
-
expect(User.respond_to? :authenticate).to be_true
|
27
|
-
end
|
28
|
-
|
29
|
-
it "define authenticate method" do
|
30
|
-
expect(user.respond_to? :authenticate).to be_true
|
31
|
-
end
|
32
|
-
|
33
|
-
it "define set_password method" do
|
34
|
-
expect(user.respond_to? :set_password).to be_true
|
35
|
-
end
|
36
|
-
|
37
|
-
it "define update_password" do
|
38
|
-
expect(user.respond_to? :update_password).to be_true
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
describe "defined methods from define_column" do
|
44
|
-
describe ".#authenticate" do
|
45
|
-
let!(:record) {
|
46
|
-
record = double("record mock")
|
47
|
-
record.stub(:salt).and_return(salt)
|
48
|
-
record.stub(:password).and_return(password_hash)
|
49
|
-
response = [record]
|
50
|
-
User.stub(:where).and_return(response)
|
51
|
-
record
|
52
|
-
}
|
53
|
-
|
54
|
-
it "user should be returned if authentication is successful" do
|
55
|
-
User.should_receive(:where)
|
56
|
-
expect(User.authenticate("valid_id", password_text)).to eq(record)
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should return nil if authentication failed" do
|
60
|
-
User.should_receive(:where)
|
61
|
-
expect(User.authenticate("valid_id", "invalid_secret")).to be_nil
|
62
|
-
end
|
63
|
-
|
64
|
-
it "should return nil if user not found" do
|
65
|
-
User.should_receive(:where).with(:email => "invalid_id").and_return([])
|
66
|
-
expect(User.authenticate("invalid_id", password_text)).to be_nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "#authenticate" do
|
71
|
-
let!(:user) {
|
72
|
-
user = User.new
|
73
|
-
user.stub(:salt).and_return(salt)
|
74
|
-
user.stub(:password).and_return(password_hash)
|
75
|
-
user
|
76
|
-
}
|
77
|
-
|
78
|
-
it "should return true if authentication is successful" do
|
79
|
-
expect(user.authenticate(password_text)).to be_true
|
80
|
-
end
|
81
|
-
|
82
|
-
it "should return false if authentication failed" do
|
83
|
-
expect(user.authenticate("invalid_pass")).to be_false
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
describe "#set_password" do
|
88
|
-
let!(:user) {
|
89
|
-
user = User.new
|
90
|
-
user.stub(:salt).and_return(salt)
|
91
|
-
user
|
92
|
-
}
|
93
|
-
|
94
|
-
it "should return set password" do
|
95
|
-
user.should_receive(:salt=).with(salt)
|
96
|
-
user.should_receive(:password=).with(Passwd.hashing("#{salt}#{password_text}"))
|
97
|
-
expect(user.set_password(password_text)).to eq(password_text)
|
98
|
-
end
|
99
|
-
|
100
|
-
it "should set random password if not specified" do
|
101
|
-
user.should_receive(:salt=).with(salt)
|
102
|
-
random_password = Passwd.create
|
103
|
-
Passwd.should_receive(:create).and_return(random_password)
|
104
|
-
user.should_receive(:password=).with(Passwd.hashing("#{salt}#{random_password}"))
|
105
|
-
user.set_password
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should set salt if salt is nil" do
|
109
|
-
mail_addr = "foo@example.com"
|
110
|
-
time_now = Time.now
|
111
|
-
salt2 = Passwd.hashing("#{mail_addr}#{time_now.to_s}")
|
112
|
-
Time.stub(:now).and_return(time_now)
|
113
|
-
user.stub(:email).and_return(mail_addr)
|
114
|
-
user.should_receive(:salt).and_return(nil)
|
115
|
-
user.should_receive(:salt=).with(salt2)
|
116
|
-
user.should_receive(:password=).with(Passwd.hashing("#{salt2}#{password_text}"))
|
117
|
-
user.set_password(password_text)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
describe "#update_password" do
|
122
|
-
let!(:user) {
|
123
|
-
user = User.new
|
124
|
-
user.stub(:salt).and_return(salt)
|
125
|
-
user.stub(:password).and_return(password_hash)
|
126
|
-
user
|
127
|
-
}
|
128
|
-
|
129
|
-
context "without policy check" do
|
130
|
-
it "should return update password" do
|
131
|
-
pass = "new_password"
|
132
|
-
user.should_receive(:set_password).with(pass).and_return(pass)
|
133
|
-
expect(user.update_password(password_text, pass)).to eq(pass)
|
134
|
-
end
|
135
|
-
|
136
|
-
it "should generate exception if authentication failed" do
|
137
|
-
Passwd.should_receive(:auth).and_return(false)
|
138
|
-
user.should_not_receive(:set_password)
|
139
|
-
expect {
|
140
|
-
user.update_password("invalid_password", "new_password")
|
141
|
-
}.to raise_error(Passwd::AuthError)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
context "with policy check" do
|
146
|
-
it "should return update password" do
|
147
|
-
pass = "new_password"
|
148
|
-
Passwd.should_receive(:policy_check).and_return(true)
|
149
|
-
user.should_receive(:set_password).with(pass).and_return(pass)
|
150
|
-
expect(user.update_password(password_text, pass, true)).to eq(pass)
|
151
|
-
end
|
152
|
-
|
153
|
-
it "should generate exception if policy not match" do
|
154
|
-
pass = "new_password"
|
155
|
-
Passwd.should_receive(:policy_check).and_return(false)
|
156
|
-
expect {
|
157
|
-
user.update_password(password_text, pass, true)
|
158
|
-
}.to raise_error(Passwd::PolicyNotMatch)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
@@ -1,250 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe Passwd::Config do
|
6
|
-
let(:config) {Passwd::Config.instance}
|
7
|
-
|
8
|
-
describe "defined accessors" do
|
9
|
-
it "defined algorithm" do
|
10
|
-
expect(config.respond_to? :algorithm).to be_true
|
11
|
-
end
|
12
|
-
|
13
|
-
it "defined length" do
|
14
|
-
expect(config.respond_to? :length).to be_true
|
15
|
-
end
|
16
|
-
|
17
|
-
it "defined lower" do
|
18
|
-
expect(config.respond_to? :lower).to be_true
|
19
|
-
end
|
20
|
-
|
21
|
-
it "defined upper" do
|
22
|
-
expect(config.respond_to? :upper).to be_true
|
23
|
-
end
|
24
|
-
|
25
|
-
it "defined number" do
|
26
|
-
expect(config.respond_to? :number).to be_true
|
27
|
-
end
|
28
|
-
|
29
|
-
it "defined letters_lower" do
|
30
|
-
expect(config.respond_to? :letters_lower).to be_true
|
31
|
-
end
|
32
|
-
|
33
|
-
it "defined letters_upper" do
|
34
|
-
expect(config.respond_to? :letters_upper).to be_true
|
35
|
-
end
|
36
|
-
|
37
|
-
it "defined letters_number" do
|
38
|
-
expect(config.respond_to? :letters_number).to be_true
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe "#initialize" do
|
43
|
-
it "algorithm should be a default" do
|
44
|
-
expect(config.algorithm).to eq(:sha512)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "length should be a default" do
|
48
|
-
expect(config.length).to eq(8)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "lower should be a default" do
|
52
|
-
expect(config.lower).to be_true
|
53
|
-
end
|
54
|
-
|
55
|
-
it "upper should be a default" do
|
56
|
-
expect(config.upper).to be_true
|
57
|
-
end
|
58
|
-
|
59
|
-
it "number should be a default" do
|
60
|
-
expect(config.number).to be_true
|
61
|
-
end
|
62
|
-
|
63
|
-
it "letters_lower should be a default" do
|
64
|
-
expect(config.letters_lower).to eq(("a".."z").to_a)
|
65
|
-
end
|
66
|
-
|
67
|
-
it "letters_upper should be a default" do
|
68
|
-
expect(config.letters_upper).to eq(("A".."Z").to_a)
|
69
|
-
end
|
70
|
-
|
71
|
-
it "letters_number should be a default" do
|
72
|
-
expect(config.letters_number).to eq(("0".."9").to_a)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "#configure" do
|
77
|
-
before {
|
78
|
-
config.configure do |c|
|
79
|
-
c.length = 20
|
80
|
-
c.lower = false
|
81
|
-
c.upper = false
|
82
|
-
c.number = false
|
83
|
-
c.letters_lower = ["a"]
|
84
|
-
c.letters_upper = ["A"]
|
85
|
-
c.letters_number = ["0"]
|
86
|
-
end
|
87
|
-
}
|
88
|
-
|
89
|
-
it "set length from block" do
|
90
|
-
expect(config.length).to eq(20)
|
91
|
-
end
|
92
|
-
|
93
|
-
it "set lower from block" do
|
94
|
-
expect(config.lower).to be_false
|
95
|
-
end
|
96
|
-
|
97
|
-
it "set upper from block" do
|
98
|
-
expect(config.upper).to be_false
|
99
|
-
end
|
100
|
-
|
101
|
-
it "set number from block" do
|
102
|
-
expect(config.number).to be_false
|
103
|
-
end
|
104
|
-
|
105
|
-
it "set letters_lower from block" do
|
106
|
-
expect(config.letters_lower).to eq(["a"])
|
107
|
-
end
|
108
|
-
|
109
|
-
it "set letters_upper from block" do
|
110
|
-
expect(config.letters_upper).to eq(["A"])
|
111
|
-
end
|
112
|
-
|
113
|
-
it "set letters_number from block" do
|
114
|
-
expect(config.letters_number).to eq(["0"])
|
115
|
-
end
|
116
|
-
|
117
|
-
it "raise error unknown setting" do
|
118
|
-
expect {
|
119
|
-
config.configure do |c|
|
120
|
-
c.unknown = true
|
121
|
-
end
|
122
|
-
}.to raise_error
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
describe "#merge" do
|
127
|
-
it "set length from hash" do
|
128
|
-
config.merge(length: 10)
|
129
|
-
expect(config.length).to eq(10)
|
130
|
-
end
|
131
|
-
|
132
|
-
it "set lower from hash" do
|
133
|
-
config.merge(lower: false)
|
134
|
-
expect(config.lower).to be_false
|
135
|
-
end
|
136
|
-
|
137
|
-
it "set upper from hash" do
|
138
|
-
config.merge(upper: false)
|
139
|
-
expect(config.upper).to be_false
|
140
|
-
end
|
141
|
-
|
142
|
-
it "set number from hash" do
|
143
|
-
config.merge(number: false)
|
144
|
-
expect(config.number).to be_false
|
145
|
-
end
|
146
|
-
|
147
|
-
it "set letters_lower from hash" do
|
148
|
-
config.merge(letters_lower: ["a"])
|
149
|
-
expect(config.letters_lower).to eq(["a"])
|
150
|
-
end
|
151
|
-
|
152
|
-
it "set letters_upper from hash" do
|
153
|
-
config.merge(letters_upper: ["A"])
|
154
|
-
expect(config.letters_upper).to eq(["A"])
|
155
|
-
end
|
156
|
-
|
157
|
-
it "set letters_number from hash" do
|
158
|
-
config.merge(letters_number: ["0"])
|
159
|
-
expect(config.letters_number).to eq(["0"])
|
160
|
-
end
|
161
|
-
|
162
|
-
it "raise error unknown setting" do
|
163
|
-
expect {
|
164
|
-
config.merge(unknown: true)
|
165
|
-
}.to raise_error
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
describe "#letters" do
|
170
|
-
it "return Array object" do
|
171
|
-
expect(config.letters.is_a? Array).to be_true
|
172
|
-
end
|
173
|
-
|
174
|
-
it "all elements of the string" do
|
175
|
-
config.letters.each do |l|
|
176
|
-
expect(l.is_a? String).to be_true
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
it "return all letters" do
|
181
|
-
all_letters = ("a".."z").to_a.concat(("A".."Z").to_a).concat(("0".."9").to_a)
|
182
|
-
expect(config.letters).to eq(all_letters)
|
183
|
-
end
|
184
|
-
|
185
|
-
it "return except for the lower case" do
|
186
|
-
config.merge(lower: false)
|
187
|
-
expect(config.letters.include? "a").to be_false
|
188
|
-
end
|
189
|
-
|
190
|
-
it "return except for the upper case" do
|
191
|
-
config.merge(upper: false)
|
192
|
-
expect(config.letters.include? "A").to be_false
|
193
|
-
end
|
194
|
-
|
195
|
-
it "return except for the number case" do
|
196
|
-
config.merge(number: false)
|
197
|
-
expect(config.letters.include? "0").to be_false
|
198
|
-
end
|
199
|
-
|
200
|
-
it "raise error if letters is empty" do
|
201
|
-
config.merge(lower: false, upper: false, number: false)
|
202
|
-
expect {
|
203
|
-
config.letters
|
204
|
-
}.to raise_error
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
describe "#reset" do
|
209
|
-
before {
|
210
|
-
config.configure do |c|
|
211
|
-
c.length = 20
|
212
|
-
c.lower = false
|
213
|
-
c.upper = false
|
214
|
-
c.number = false
|
215
|
-
c.letters_lower = ["a"]
|
216
|
-
c.letters_upper = ["A"]
|
217
|
-
c.letters_number = ["0"]
|
218
|
-
end
|
219
|
-
config.reset
|
220
|
-
}
|
221
|
-
|
222
|
-
it "length should be a default" do
|
223
|
-
expect(config.length).to eq(8)
|
224
|
-
end
|
225
|
-
|
226
|
-
it "lower should be a default" do
|
227
|
-
expect(config.lower).to be_true
|
228
|
-
end
|
229
|
-
|
230
|
-
it "upper should be a default" do
|
231
|
-
expect(config.upper).to be_true
|
232
|
-
end
|
233
|
-
|
234
|
-
it "number should be a default" do
|
235
|
-
expect(config.number).to be_true
|
236
|
-
end
|
237
|
-
|
238
|
-
it "letters_lower should be a default" do
|
239
|
-
expect(config.letters_lower).to eq(("a".."z").to_a)
|
240
|
-
end
|
241
|
-
|
242
|
-
it "letters_upper should be a default" do
|
243
|
-
expect(config.letters_upper).to eq(("A".."Z").to_a)
|
244
|
-
end
|
245
|
-
|
246
|
-
it "letters_number should be a default" do
|
247
|
-
expect(config.letters_number).to eq(("0".."9").to_a)
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|