settingson 1.6.0 → 1.6.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/.travis.yml CHANGED
@@ -11,3 +11,6 @@ rvm:
11
11
  gemfile:
12
12
  - gemfiles/4.2.gemfile
13
13
  - gemfiles/5.0.gemfile
14
+
15
+ env:
16
+ - CODECLIMATE_REPO_TOKEN=620b22e287791de2c9f8a522182ddf57098302ff8958768f8192eaaa7d8a685d
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in settingson.gemspec
4
4
  gemspec
5
+
6
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/settingson.svg)](http://badge.fury.io/rb/settingson)
2
2
  [![Build Status](https://travis-ci.org/daanforever/settingson.svg?branch=master)](https://travis-ci.org/daanforever/settingson)
3
3
  [![Code Climate](https://codeclimate.com/github/daanforever/settingson/badges/gpa.svg)](https://codeclimate.com/github/daanforever/settingson)
4
+ [![Test Coverage](https://codeclimate.com/github/daanforever/settingson/badges/coverage.svg)](https://codeclimate.com/github/daanforever/settingson/coverage)
4
5
 
5
6
  # Settingson
6
7
 
@@ -111,23 +112,15 @@ end
111
112
  New way:
112
113
  in config/initializers/settingson.rb
113
114
  ```ruby
114
- Settings.defaults do
115
- Settings.server.smtp.host? || Settings.server.smtp.host = 'host'
116
- Settings.server.smtp.port? || Settings.server.smtp.port = 25
115
+ Settings.defaults do |conf|
116
+ conf.server.smtp.host = 'host'
117
+ conf.server.smtp.port = 25
117
118
  end
118
119
  ```
119
120
 
120
- Old way:
121
- in config/initializers/settingson.rb
122
121
  ```ruby
123
- Rails.application.config.after_initialize do
124
- begin
125
- Settings.server.smtp.host? || Settings.server.smtp.host = 'host'
126
- Settings.server.smtp.port? || Settings.server.smtp.port = '25'
127
- rescue
128
- Rails.logger.warn('Something goes wrong')
129
- end
130
- end
122
+ conf.server.smtp.host # => 'host'
123
+ conf.server.smtp.port # => 25
131
124
  ```
132
125
 
133
126
  ## Contributing
@@ -11,9 +11,8 @@ module Settingson::Base
11
11
  #
12
12
  # # or
13
13
  #
14
- # Settings.configure.expires = 600
15
- # Settings.configure.enabled = true
16
-
14
+ # Settings.configure.cache.expires = 600
15
+ # Settings.configure.cache.enabled = true
17
16
  def configure
18
17
  @_settings ||= ::Settingson::Config.new
19
18
  yield @_settings if block_given?
@@ -24,32 +23,15 @@ module Settingson::Base
24
23
  # settings.server.host = 'host'
25
24
  # settings.server.port = 80
26
25
  # end
27
- # FIXME: not ready yet
28
26
  def defaults
27
+ return unless block_given?
29
28
  Rails.application.config.after_initialize do
30
- begin
31
- yield new(settingson: 'defaults') if block_given?
32
- rescue
33
- Rails.logger.warn('Settingson::defaults failed')
34
- end
29
+ yield Settingson::Store.new( klass: self, path: '__defaults' )
35
30
  end
36
- true
37
- end
38
-
39
- # Settings.delete_all
40
- # Delete cached items before super
41
- def delete_all
42
- Rails.cache.delete_matched(/#{self.configure.cache.namespace}/)
43
- super
44
31
  end
45
32
 
46
33
  # Settings.from_hash('smtp.host' => 'host')
47
-
48
- def cached(*args)
49
- ActiveSupport::Deprecation.warn('Now caching is enabled by default')
50
- self.new
51
- end
52
-
34
+ # Settings.smtp.host
53
35
  def from_hash(attributes)
54
36
  case attributes
55
37
  when Hash
@@ -61,102 +43,29 @@ module Settingson::Base
61
43
  end
62
44
  end
63
45
 
64
- def method_missing(symbol, *args)
46
+ # Custom hook for clear cache before delete_all
47
+ #
48
+ def delete_all
65
49
  super
66
- rescue NameError
67
- self.new.send(symbol, *args)
68
- rescue NoMethodError
69
- self.new.send(symbol, *args)
50
+ Rails.cache.delete_matched(/#{self.configure.cache.namespace}/)
70
51
  end
71
52
 
53
+ def method_missing(symbol, *args)
54
+ super
55
+ rescue NameError, NoMethodError
56
+ Settingson::Store.new(klass: self).send(symbol, args.first)
57
+ end
72
58
 
73
59
  end # module ClassMethods
74
60
 
75
61
  included do
76
- attr_accessor :settingson
77
62
  serialize :value
78
63
  before_destroy :__delete_cached
79
64
  end
80
65
 
81
- def __debug(message)
82
- Rails.logger.debug(message) if self.class.configure.debug
83
- end
84
-
85
66
  def __delete_cached
86
67
  cache_key = "#{self.class.configure.cache.namespace}/#{self.key}"
87
68
  Rails.cache.delete(cache_key)
88
- __debug("#{self.class.name}: delete '#{self.key}' '#{cache_key}'")
89
- end
90
-
91
- def to_s
92
- self.new_record? ? '' : super
93
- end
94
-
95
- def inspect
96
- self.new_record? ? '""' : super
97
- end
98
-
99
- def to_i
100
- self.new_record? ? 0 : super
101
- end
102
-
103
- def nil?
104
- self.new_record? ? true : super
105
- end
106
-
107
- alias empty? nil?
108
-
109
- def method_missing(symbol, *args)
110
- super
111
- rescue NameError
112
- __rescue_action(symbol.to_s, args.first)
113
- rescue NoMethodError
114
- __rescue_action(symbol.to_s, args.first)
115
- end # method_missing
116
-
117
- protected
118
-
119
- def __cached_key
120
- [ self.class.configure.cache.namespace, @settingson ].join('/')
121
- end
122
-
123
- def __rescue_action(key, value)
124
- case key
125
- when /(.+)=/ # setter
126
- @settingson = [@settingson, $1].compact.join('.')
127
- record = self.class.find_or_create_by!(key: @settingson)
128
- record.update!(value: value)
129
- Rails.cache.write(__cached_key, value)
130
- __debug("#{self.class.name}##{__method__} setter '#{__cached_key}'")
131
- record.value
132
- else # returns values or self
133
- @settingson = [@settingson, key].compact.join('.')
134
- __debug("#{self.class.name}##{__method__} getter '#{@settingson}'")
135
- __cached_value_or_self
136
- end
137
- end
138
-
139
- def __cached_value_or_self
140
- result = __cached_value
141
- result.is_a?(ActiveRecord::RecordNotFound) ? self : result
142
- end
143
-
144
- def __cached_value
145
- __debug("#{self.class.name}##{__method__} '#{@settingson}'")
146
- Rails.cache.fetch(
147
- __cached_key,
148
- expires_in: self.class.configure.cache.expires,
149
- race_condition_ttl: self.class.configure.cache.race_condition_ttl
150
- ) do
151
- __debug("#{self.class.name}: fresh '#{@settingson}'")
152
- __fresh_value
153
- end
154
- end
155
-
156
- def __fresh_value
157
- self.class.find_by!(key: @settingson).value
158
- rescue ActiveRecord::RecordNotFound
159
- ActiveRecord::RecordNotFound.new
160
69
  end
161
70
 
162
71
  end # Settingson::Base
data/gemfiles/4.2.gemfile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "codeclimate-test-reporter", :group => :test, :require => nil
5
6
  gem "rails", "~> 4.2.0"
6
7
 
7
8
  gemspec :path => "../"
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- settingson (1.5.14)
4
+ settingson (1.6.0)
5
5
  rails (>= 4.0)
6
6
 
7
7
  GEM
@@ -48,9 +48,12 @@ GEM
48
48
  thor (>= 0.14.0)
49
49
  arel (6.0.3)
50
50
  builder (3.2.2)
51
+ codeclimate-test-reporter (0.6.0)
52
+ simplecov (>= 0.7.1, < 1.0.0)
51
53
  concurrent-ruby (1.0.2)
52
54
  database_cleaner (1.5.3)
53
55
  diff-lcs (1.2.5)
56
+ docile (1.1.5)
54
57
  erubis (2.7.0)
55
58
  faker (1.6.6)
56
59
  i18n (~> 0.5)
@@ -122,6 +125,11 @@ GEM
122
125
  rspec-mocks (~> 3.5.0)
123
126
  rspec-support (~> 3.5.0)
124
127
  rspec-support (3.5.0)
128
+ simplecov (0.12.0)
129
+ docile (~> 1.1.0)
130
+ json (>= 1.8, < 3)
131
+ simplecov-html (~> 0.10.0)
132
+ simplecov-html (0.10.0)
125
133
  spring (1.7.2)
126
134
  spring-commands-rspec (1.0.4)
127
135
  spring (>= 0.9.1)
@@ -144,6 +152,7 @@ PLATFORMS
144
152
  DEPENDENCIES
145
153
  appraisal
146
154
  bundler (>= 1.6)
155
+ codeclimate-test-reporter
147
156
  database_cleaner
148
157
  faker
149
158
  rails (~> 4.2.0)
data/gemfiles/5.0.gemfile CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "codeclimate-test-reporter", :group => :test, :require => nil
5
6
  gem "rails", "~> 5.0.0"
6
7
 
7
8
  gemspec :path => "../"
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../
3
3
  specs:
4
- settingson (1.5.14)
4
+ settingson (1.6.0)
5
5
  rails (>= 4.0)
6
6
 
7
7
  GEM
@@ -50,15 +50,19 @@ GEM
50
50
  thor (>= 0.14.0)
51
51
  arel (7.1.2)
52
52
  builder (3.2.2)
53
+ codeclimate-test-reporter (0.6.0)
54
+ simplecov (>= 0.7.1, < 1.0.0)
53
55
  concurrent-ruby (1.0.2)
54
56
  database_cleaner (1.5.3)
55
57
  diff-lcs (1.2.5)
58
+ docile (1.1.5)
56
59
  erubis (2.7.0)
57
60
  faker (1.6.6)
58
61
  i18n (~> 0.5)
59
62
  globalid (0.3.7)
60
63
  activesupport (>= 4.1.0)
61
64
  i18n (0.7.0)
65
+ json (2.0.2)
62
66
  loofah (2.0.3)
63
67
  nokogiri (>= 1.5.9)
64
68
  mail (2.6.4)
@@ -124,6 +128,11 @@ GEM
124
128
  rspec-mocks (~> 3.5.0)
125
129
  rspec-support (~> 3.5.0)
126
130
  rspec-support (3.5.0)
131
+ simplecov (0.12.0)
132
+ docile (~> 1.1.0)
133
+ json (>= 1.8, < 3)
134
+ simplecov-html (~> 0.10.0)
135
+ simplecov-html (0.10.0)
127
136
  spring (1.7.2)
128
137
  spring-commands-rspec (1.0.4)
129
138
  spring (>= 0.9.1)
@@ -149,6 +158,7 @@ PLATFORMS
149
158
  DEPENDENCIES
150
159
  appraisal
151
160
  bundler (>= 1.6)
161
+ codeclimate-test-reporter
152
162
  database_cleaner
153
163
  faker
154
164
  rails (~> 5.0.0)
@@ -1,4 +1,108 @@
1
- module Settingson::Store
1
+ class Settingson::Store
2
2
 
3
+ def initialize(klass:, path: nil)
4
+ @__klass = klass
5
+ @__path = path
6
+ end
7
+
8
+ def to_s
9
+ self.new_record? ? '' : super
10
+ end
11
+
12
+ def to_i
13
+ self.new_record? ? 0 : super
14
+ end
15
+
16
+ def nil?
17
+ self.new_record? ? true : super
18
+ end
19
+
20
+ alias empty? nil?
21
+
22
+ def method_missing(symbol, *args)
23
+ __rescue_action(symbol.to_s, args.first)
24
+ end # method_missing
25
+
26
+ protected
27
+
28
+ def __debug(message)
29
+ message = sprintf("%s#%-32s: %s",
30
+ self.class.name,
31
+ caller_locations.first.label,
32
+ message)
33
+ Rails.logger.debug(message) if @__klass.configure.debug
34
+ end
35
+
36
+ def __rescue_action(key, value)
37
+ case key
38
+ when /(.+)=/ # setter
39
+ __debug("set '#{$1}' value '#{value}' path '#{@__path}'")
40
+ __set($1, value)
41
+ else # returns values or self
42
+ __debug("get '#{key}' value '#{value}' path '#{@__path}'")
43
+ __get(key)
44
+ end
45
+ end
46
+
47
+ def __set(key, value)
48
+ __update_search_path(key)
49
+ if record = @__klass.find_by(key: @__path)
50
+ record.update!(value: value)
51
+ else
52
+ @__klass.create!(key: @__path, value: value)
53
+ end
54
+ Rails.cache.write(__cache_key(@__path), value)
55
+ value
56
+ end
57
+
58
+ def __get(key)
59
+ __update_search_path(key)
60
+ result = __cached_or_default_value(@__path)
61
+
62
+ if result.is_a?(ActiveRecord::RecordNotFound)
63
+ __debug("return self with path: #{@__path}")
64
+ self
65
+ else
66
+ __debug("return result")
67
+ result
68
+ end
69
+ end
70
+
71
+ def __update_search_path(key)
72
+ @__path = [@__path, key].compact.join('.')
73
+ end
74
+
75
+ def __cached_or_default_value(key)
76
+ result = __cached_value(key)
77
+
78
+ if result.is_a?(ActiveRecord::RecordNotFound) # Try defaults
79
+ __cached_value('__defaults.' + key)
80
+ else
81
+ result
82
+ end
83
+ end
84
+
85
+ def __cache_key(key)
86
+ [ @__klass.configure.cache.namespace, key ].join('/')
87
+ end
88
+
89
+ def __cached_value(key)
90
+ __debug("looking in cache '#{__cache_key(key)}'")
91
+ Rails.cache.fetch(
92
+ __cache_key(key),
93
+ expires_in: @__klass.configure.cache.expires,
94
+ race_condition_ttl: @__klass.configure.cache.race_condition_ttl
95
+ ) do
96
+ __debug("ask DB '#{key}'")
97
+ __get_from_db(key)
98
+ end
99
+ end
100
+
101
+ def __get_from_db(key)
102
+ @__klass.find_by!(key: key).value
103
+ rescue ActiveRecord::RecordNotFound
104
+ __debug("not found")
105
+ ActiveRecord::RecordNotFound.new
106
+ end
3
107
 
4
108
  end
@@ -1,3 +1,3 @@
1
1
  module Settingson
2
- VERSION = "1.6.0"
2
+ VERSION = "1.6.1"
3
3
  end
@@ -0,0 +1 @@
1
+ Settings.configure.debug = true
@@ -2,9 +2,32 @@ require 'spec_helper'
2
2
 
3
3
  describe Settings do
4
4
 
5
- describe 'Settings.defaults' do
6
- it 'not raises errors' do
7
- expect{ Settings.default {} }.to_not raise_error
5
+ describe '::defaults' do
6
+ it 'not raises errors without parameters' do
7
+ expect{ Settings.defaults {} }.to_not raise_error
8
+ end
9
+
10
+ it 'returns default value for simple value' do
11
+ word = Faker::Lorem.word
12
+ Settings.defaults{|s| s.cached_key = word}
13
+ expect( Settings.cached_key ).to eq(word)
14
+ end
15
+
16
+ it 'returns default value for complex value' do
17
+ word = Faker::Lorem.word
18
+ Settings.defaults{|s| s.some.key = word}
19
+ expect( Settings.some.key ).to eq(word)
20
+ end
21
+ end
22
+
23
+ describe '::from_hash' do
24
+ it 'accessable by hash key' do
25
+ Settings.from_hash(hello: :world)
26
+ expect( Settings.hello ).to eq(:world)
27
+ end
28
+
29
+ it 'raises error when not Hash' do
30
+ expect{Settings.from_hash([:hello, :world])}.to raise_error(ArgumentError)
8
31
  end
9
32
  end
10
33
 
@@ -15,11 +38,13 @@ describe Settings do
15
38
  it 'not raises error on create new element' do
16
39
  expect{ Settings.hello = Faker::Lorem.word }.to_not raise_error
17
40
  end
18
- it 'returns same Fixnum' do
19
- word = Faker::Lorem.word
41
+ it 'returns same Fixnum #1' do
20
42
  Settings.number = 100
21
43
  expect( Settings.number ).to eq(100)
22
44
  end
45
+ it 'returns 0 when key not found' do
46
+ expect( Settings.not_found.to_i ).to eq(0)
47
+ end
23
48
  it 'returns same String' do
24
49
  word = Faker::Lorem.word
25
50
  Settings.hello = word
@@ -27,13 +52,18 @@ describe Settings do
27
52
  end
28
53
  it 'returns same value for complex key #1' do
29
54
  word = Faker::Lorem.word
30
- Settings.hello.hello = word
31
- expect( Settings.hello.hello ).to eq(word)
55
+ Settings.hello1.hello2 = word
56
+ expect( Settings.hello1.hello2 ).to eq(word)
32
57
  end
33
58
  it 'returns same value for complex key #2' do
34
59
  word = Faker::Lorem.word
35
- Settings.i.hello = word
36
- expect( Settings.i.hello ).to eq(word)
60
+ Settings.hello.key = word
61
+ expect( Settings.hello.key ).to eq(word)
62
+ end
63
+ it 'returns same value for complex key #3' do
64
+ word = Faker::Lorem.word
65
+ Settings.hello.hello = word
66
+ expect( Settings.hello.hello ).to eq(word)
37
67
  end
38
68
  it 'not destroys record with nil value #1' do
39
69
  word = Faker::Lorem.word
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  ENV["RAILS_ENV"] ||= 'test'
2
2
 
3
+ require "codeclimate-test-reporter"
4
+ CodeClimate::TestReporter.start
5
+
3
6
  require ::File.expand_path('../dummy/config/environment', __FILE__)
4
7
  require 'rspec/rails'
5
8
  require 'database_cleaner'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: settingson
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - dan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-16 00:00:00.000000000 Z
11
+ date: 2016-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -157,8 +157,10 @@ executables: []
157
157
  extensions: []
158
158
  extra_rdoc_files: []
159
159
  files:
160
+ - ".codeclimate.yml"
160
161
  - ".gitignore"
161
162
  - ".rspec"
163
+ - ".rubocop.yml"
162
164
  - ".travis.yml"
163
165
  - Appraisals
164
166
  - Gemfile
@@ -212,6 +214,7 @@ files:
212
214
  - spec/dummy/config/initializers/inflections.rb
213
215
  - spec/dummy/config/initializers/mime_types.rb
214
216
  - spec/dummy/config/initializers/session_store.rb
217
+ - spec/dummy/config/initializers/settingson.rb
215
218
  - spec/dummy/config/initializers/wrap_parameters.rb
216
219
  - spec/dummy/config/locales/en.yml
217
220
  - spec/dummy/config/routes.rb
@@ -286,6 +289,7 @@ test_files:
286
289
  - spec/dummy/config/initializers/inflections.rb
287
290
  - spec/dummy/config/initializers/mime_types.rb
288
291
  - spec/dummy/config/initializers/session_store.rb
292
+ - spec/dummy/config/initializers/settingson.rb
289
293
  - spec/dummy/config/initializers/wrap_parameters.rb
290
294
  - spec/dummy/config/locales/en.yml
291
295
  - spec/dummy/config/routes.rb