tunable 0.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/README.md +115 -0
- data/Rakefile +8 -0
- data/generators/tunable_migration/templates/migration.rb +23 -0
- data/generators/tunable_migration/tunable_migration_generator.rb +7 -0
- data/lib/tunable/core_ext.rb +41 -0
- data/lib/tunable/emoji_fix.rb +5 -0
- data/lib/tunable/hasher.rb +30 -0
- data/lib/tunable/model.rb +260 -0
- data/lib/tunable/normalizer.rb +34 -0
- data/lib/tunable/setting.rb +59 -0
- data/lib/tunable/version.rb +5 -0
- data/lib/tunable.rb +6 -0
- data/spec/schema.rb +17 -0
- data/spec/spec_helper.rb +40 -0
- data/spec/tunable/defaults_spec.rb +143 -0
- data/spec/tunable/normalization_spec.rb +344 -0
- data/spec/tunable/querying_spec.rb +259 -0
- data/spec/tunable/setters_spec.rb +63 -0
- data/tunable.gemspec +27 -0
- metadata +153 -0
@@ -0,0 +1,259 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe 'setting on/off?' do
|
4
|
+
|
5
|
+
VALUE_TYPES = {
|
6
|
+
:main => {
|
7
|
+
:truthy => 'true',
|
8
|
+
:falsy => 'false',
|
9
|
+
:t => 't',
|
10
|
+
:f => 'f',
|
11
|
+
:foo => 'foo',
|
12
|
+
:empty => ''
|
13
|
+
},
|
14
|
+
:numbers => {
|
15
|
+
:number_0 => '0',
|
16
|
+
:number_1 => '1',
|
17
|
+
:number_of_the_beast => '666'
|
18
|
+
},
|
19
|
+
:onoffs => {
|
20
|
+
:on => 'on',
|
21
|
+
:off => 'off'
|
22
|
+
},
|
23
|
+
:yesnoes => {
|
24
|
+
:yes => 'yes',
|
25
|
+
:no => 'no',
|
26
|
+
:y => 'y',
|
27
|
+
:n => 'n',
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
before :all do
|
32
|
+
load_main_settings!
|
33
|
+
@model = TunableModel.create(name: "Yay, I'm settable!")
|
34
|
+
|
35
|
+
# Raw values (not normalized) need to be stored into db
|
36
|
+
# to check if settings on/off is backwards compatible
|
37
|
+
def insert_into_db(id, context, key, val)
|
38
|
+
keys = %w(settable_type settable_id context key value)
|
39
|
+
values = "'" + ['TunableModel', id, "#{context}", key, val].join("','") + "'"
|
40
|
+
sql = "REPLACE INTO `settings` (#{keys.join(', ')}) VALUES (#{values});"
|
41
|
+
ActiveRecord::Base.connection.execute(sql)
|
42
|
+
end
|
43
|
+
|
44
|
+
VALUE_TYPES.each do |context, values|
|
45
|
+
values.each do |key, val|
|
46
|
+
insert_into_db(@model.id, context, key, val)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'setting_on?' do
|
52
|
+
|
53
|
+
describe 'with nonexisting key' do
|
54
|
+
|
55
|
+
it 'returns nil' do
|
56
|
+
@model.setting_on?(:main, :not_a_real_key).should === false
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'with empty value' do
|
62
|
+
|
63
|
+
it 'returns nil' do
|
64
|
+
@model.setting_on?(:main, :empty).should === false
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'with foo value' do
|
70
|
+
|
71
|
+
it 'returns false' do
|
72
|
+
@model.setting_on?(:main, :foo).should === false
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'with numeric value other than 0/1' do
|
78
|
+
|
79
|
+
it 'returns false' do
|
80
|
+
@model.setting_on?(:numbers, :number_of_the_beast).should === false
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'with falsy value' do
|
86
|
+
|
87
|
+
describe 'false' do
|
88
|
+
it 'returns false' do
|
89
|
+
@model.setting_on?(:main, :falsy).should === false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '0' do
|
94
|
+
it 'returns false' do
|
95
|
+
@model.setting_on?(:numbers, :number_0).should === false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe 'off' do
|
100
|
+
it 'returns false' do
|
101
|
+
@model.setting_on?(:onoffs, :off).should === false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'no' do
|
106
|
+
it 'returns false' do
|
107
|
+
@model.setting_on?(:yesnoes, :no).should === false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe 'n' do
|
112
|
+
it 'returns false' do
|
113
|
+
@model.setting_on?(:yesnoes, :n).should === false
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
describe 'with truthy value' do
|
120
|
+
|
121
|
+
describe 'true' do
|
122
|
+
it 'returns true' do
|
123
|
+
@model.setting_on?(:main, :truthy).should === true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe '1' do
|
128
|
+
it 'returns true' do
|
129
|
+
@model.setting_on?(:numbers, :number_1).should === true
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe 'on' do
|
134
|
+
it 'returns true' do
|
135
|
+
@model.setting_on?(:onoffs, :on).should === true
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe 'yes' do
|
140
|
+
it 'returns true' do
|
141
|
+
@model.setting_on?(:yesnoes, :yes).should === true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe 'y' do
|
146
|
+
it 'returns true' do
|
147
|
+
@model.setting_on?(:yesnoes, :y).should === true
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'setting_off?' do
|
156
|
+
|
157
|
+
describe 'with nonexisting key' do
|
158
|
+
|
159
|
+
it 'returns nil' do
|
160
|
+
@model.setting_off?(:main, :not_a_real_key).should === false
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
describe 'with empty value' do
|
166
|
+
|
167
|
+
it 'returns nil' do
|
168
|
+
@model.setting_off?(:main, :empty).should === false
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
describe 'with foo value' do
|
174
|
+
|
175
|
+
it 'returns false' do
|
176
|
+
@model.setting_off?(:main, :foo).should === false
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
describe 'with numeric value other than 0/1' do
|
182
|
+
|
183
|
+
it 'returns false' do
|
184
|
+
@model.setting_off?(:numbers, :number_of_the_beast).should === false
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
describe 'with falsy value' do
|
190
|
+
|
191
|
+
describe 'false' do
|
192
|
+
it 'returns true' do
|
193
|
+
@model.setting_off?(:main, :falsy).should === true
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe '0' do
|
198
|
+
it 'returns true' do
|
199
|
+
@model.setting_off?(:numbers, :number_0).should === true
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe 'off' do
|
204
|
+
it 'returns true' do
|
205
|
+
@model.setting_off?(:onoffs, :off).should === true
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe 'no' do
|
210
|
+
it 'returns true' do
|
211
|
+
@model.setting_off?(:yesnoes, :no).should === true
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
describe 'n' do
|
216
|
+
it 'returns true' do
|
217
|
+
@model.setting_off?(:yesnoes, :n).should === true
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
describe 'with truthy value' do
|
224
|
+
|
225
|
+
describe 'true' do
|
226
|
+
it 'returns false' do
|
227
|
+
@model.setting_off?(:main, :truthy).should === false
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '1' do
|
232
|
+
it 'returns false' do
|
233
|
+
@model.setting_off?(:numbers, :number_1).should === false
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe 'on' do
|
238
|
+
it 'returns false' do
|
239
|
+
@model.setting_off?(:onoffs, :on).should === false
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe 'yes' do
|
244
|
+
it 'returns false' do
|
245
|
+
@model.setting_off?(:yesnoes, :yes).should === false
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe 'y' do
|
250
|
+
it 'returns false' do
|
251
|
+
@model.setting_off?(:yesnoes, :y).should === false
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
end
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe 'main_setting setters' do
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
load_main_settings!
|
7
|
+
@model = TunableModel.create(name: "Yay, I'm settable!")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'if key does not exist' do
|
11
|
+
|
12
|
+
it 'saves new settings' do
|
13
|
+
ActiveRecord::Base.connection.should_receive(:execute)
|
14
|
+
@model.update_attribute(:boolean_setting, true)
|
15
|
+
@model.reload
|
16
|
+
# expect(@model.boolean_setting).to equal(true)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'if key exists' do
|
22
|
+
|
23
|
+
describe 'and value is exactly the same' do
|
24
|
+
|
25
|
+
before do
|
26
|
+
@model.update_attribute(:boolean_setting, true)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'does not save any new settings' do
|
30
|
+
ActiveRecord::Base.connection.should_not_receive(:execute)
|
31
|
+
@model.update_attribute(:boolean_setting, true)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'and value is different but truthy' do
|
37
|
+
|
38
|
+
before do
|
39
|
+
@model.update_attribute(:boolean_setting, true)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does not save any new settings' do
|
43
|
+
ActiveRecord::Base.connection.should_not_receive(:execute)
|
44
|
+
@model.update_attribute(:boolean_setting, 'on')
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'and value is different and falsy' do
|
50
|
+
|
51
|
+
before do
|
52
|
+
@model.update_attribute(:boolean_setting, true)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'saves new setting' do
|
56
|
+
ActiveRecord::Base.connection.should_receive(:execute).once
|
57
|
+
@model.update_attribute(:boolean_setting, 'off')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/tunable.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/tunable/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "tunable"
|
6
|
+
s.version = Tunable::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ['Tomás Pollak']
|
9
|
+
s.email = ['tomas@forkhq.com']
|
10
|
+
s.homepage = "https://github.com/tomas/tunable"
|
11
|
+
s.summary = "Pluggable settings for your AR models."
|
12
|
+
s.description = "Pluggable settings for your AR models."
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
# s.rubyforge_project = "tunable"
|
16
|
+
|
17
|
+
s.add_runtime_dependency "activerecord", "~> 4.0"
|
18
|
+
s.add_runtime_dependency "activesupport", "~> 4.0"
|
19
|
+
|
20
|
+
s.add_development_dependency "bundler", '~> 1.0', '>= 1.0.0'
|
21
|
+
s.add_development_dependency "rspec", '~> 3.0', '>= 3.0.0'
|
22
|
+
s.add_development_dependency "sqlite3", '~> 1.0', '>= 1.0.0'
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
26
|
+
s.require_path = 'lib'
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tunable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tomás Pollak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.0.0
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.0'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.0.0
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.0'
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 3.0.0
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - "~>"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '3.0'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 3.0.0
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: sqlite3
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '1.0'
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 1.0.0
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '1.0'
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.0.0
|
101
|
+
description: Pluggable settings for your AR models.
|
102
|
+
email:
|
103
|
+
- tomas@forkhq.com
|
104
|
+
executables: []
|
105
|
+
extensions: []
|
106
|
+
extra_rdoc_files: []
|
107
|
+
files:
|
108
|
+
- ".gitignore"
|
109
|
+
- Gemfile
|
110
|
+
- README.md
|
111
|
+
- Rakefile
|
112
|
+
- generators/tunable_migration/templates/migration.rb
|
113
|
+
- generators/tunable_migration/tunable_migration_generator.rb
|
114
|
+
- lib/tunable.rb
|
115
|
+
- lib/tunable/core_ext.rb
|
116
|
+
- lib/tunable/emoji_fix.rb
|
117
|
+
- lib/tunable/hasher.rb
|
118
|
+
- lib/tunable/model.rb
|
119
|
+
- lib/tunable/normalizer.rb
|
120
|
+
- lib/tunable/setting.rb
|
121
|
+
- lib/tunable/version.rb
|
122
|
+
- spec/schema.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
- spec/tunable/defaults_spec.rb
|
125
|
+
- spec/tunable/normalization_spec.rb
|
126
|
+
- spec/tunable/querying_spec.rb
|
127
|
+
- spec/tunable/setters_spec.rb
|
128
|
+
- tunable.gemspec
|
129
|
+
homepage: https://github.com/tomas/tunable
|
130
|
+
licenses: []
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 1.3.6
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.2.0
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Pluggable settings for your AR models.
|
152
|
+
test_files: []
|
153
|
+
has_rdoc:
|