cockpit 0.0.1.7 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,125 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ class StoreTest < ActiveSupport::TestCase
4
+
5
+ context "Store" do
6
+
7
+ context "ActiveRecord" do
8
+ setup do
9
+ @settings = Cockpit "active_record" do
10
+ site do
11
+ title "My Site"
12
+ time_zone lambda { "Hawaii" }
13
+ feed do
14
+ per_page 10
15
+ formats %w(rss atom)
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ should "get/set values" do
22
+ assert_equal "My Site", @settings["site.title"]
23
+ @settings["site.title"] = "Another Site"
24
+ assert_equal 1, Moneta::Adapters::ActiveRecord::Store.count
25
+ assert_equal "Another Site", @settings["site.title"]
26
+ end
27
+
28
+ should "have user settings" do
29
+ assert_equal %w(red green blue), User.cockpit["favorite.colors"]
30
+ assert_equal "Lance", User.cockpit["appelation"]
31
+ end
32
+
33
+ end
34
+
35
+ context "MongoDB" do
36
+ setup do
37
+ @settings = Cockpit "mongodb" do
38
+ site do
39
+ title "My Site"
40
+ time_zone lambda { "Hawaii" }
41
+ feed do
42
+ per_page 10
43
+ formats %w(rss atom)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ should "get/set values" do
50
+ assert_equal "My Site", @settings["site.title"]
51
+ @settings["site.title"] = "Another Site"
52
+ assert_equal "Another Site", @settings["site.title"]
53
+ end
54
+ end
55
+
56
+ context "File" do
57
+ setup do
58
+ @settings = Cockpit "file" do
59
+ site do
60
+ title "My Site"
61
+ time_zone lambda { "Hawaii" }
62
+ feed do
63
+ per_page 10
64
+ formats %w(rss atom)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ should "get/set values" do
71
+ assert_equal "My Site", @settings["site.title"]
72
+ @settings["site.title"] = "Another Site"
73
+ assert_equal "Another Site", @settings["site.title"]
74
+ end
75
+ end
76
+
77
+ context "Memory" do
78
+ setup do
79
+ @settings = Cockpit "memory" do
80
+ site do
81
+ title "My Site"
82
+ time_zone lambda { "Hawaii" }
83
+ feed do
84
+ per_page 10
85
+ formats %w(rss atom)
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ should "get/set values" do
92
+ assert_equal "My Site", @settings["site.title"]
93
+ @settings["site.title"] = "Another Site"
94
+ assert_equal "Another Site", @settings["site.title"]
95
+ end
96
+ end
97
+
98
+ context "Redis" do
99
+ setup do
100
+ @settings = Cockpit "redis" do
101
+ site do
102
+ title "My Site"
103
+ time_zone lambda { "Hawaii" }
104
+ feed do
105
+ per_page 10
106
+ formats %w(rss atom)
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ should "get/set values" do
113
+ assert_equal "My Site", @settings["site.title"]
114
+ @settings["site.title"] = "Another Site"
115
+ assert_equal "Another Site", @settings["site.title"]
116
+ end
117
+ end
118
+
119
+ teardown do
120
+ Cockpit::Settings.clear
121
+ end
122
+
123
+ end
124
+
125
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cockpit
3
3
  version: !ruby/object:Gem::Version
4
- hash: 69
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 0
9
8
  - 1
10
- - 7
11
- version: 0.0.1.7
9
+ - 1
10
+ version: 0.1.1
12
11
  platform: ruby
13
12
  authors:
14
13
  - Lance Pollard
@@ -16,11 +15,24 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2010-07-02 00:00:00 -07:00
18
+ date: 2010-09-13 00:00:00 -05:00
20
19
  default_executable:
21
- dependencies: []
22
-
23
- description: Super DRY Configuration for Ruby, Rails, and Sinatra Apps
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: moneta
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: Super DRY Configuration for Ruby, Rails, and Sinatra Apps. With Pluggable NoSQL/SQL backends using Moneta
24
36
  email: lancejpollard@gmail.com
25
37
  executables: []
26
38
 
@@ -31,24 +43,23 @@ extra_rdoc_files: []
31
43
  files:
32
44
  - README.markdown
33
45
  - Rakefile
34
- - init.rb
35
46
  - MIT-LICENSE
36
- - lib/cockpit/cockpit.rb
37
- - lib/cockpit/configuration.rb
38
- - lib/cockpit/definition.rb
39
- - lib/cockpit/extensions.rb
40
- - lib/cockpit/helper.rb
41
- - lib/cockpit/store.rb
42
- - lib/cockpit/tree_hash.rb
47
+ - lib/cockpit/core/definition.rb
48
+ - lib/cockpit/core/definitions.rb
49
+ - lib/cockpit/core/include.rb
50
+ - lib/cockpit/core/settings.rb
51
+ - lib/cockpit/core/store.rb
52
+ - lib/cockpit/many/include.rb
53
+ - lib/cockpit/many/settings.rb
54
+ - lib/cockpit/moneta/active_record.rb
55
+ - lib/cockpit/moneta/simple_active_record.rb
43
56
  - lib/cockpit.rb
44
- - rails/init.rb
45
57
  - test/lib/database.rb
46
58
  - test/lib/user.rb
59
+ - test/test_active_record.rb
47
60
  - test/test_helper.rb
48
- - test/test_settings.rb
49
- - test/test_settings_in_database.rb
50
- - test/test_settings_on_model.rb
51
- - app/models/setting.rb
61
+ - test/test_mongo.rb
62
+ - test/test_stores.rb
52
63
  has_rdoc: true
53
64
  homepage: http://github.com/viatropos/cockpit
54
65
  licenses: []
@@ -82,6 +93,6 @@ rubyforge_project: cockpit
82
93
  rubygems_version: 1.3.7
83
94
  signing_key:
84
95
  specification_version: 3
85
- summary: "Cockpit: Super DRY Configuration for Ruby, Rails, and Sinatra Apps"
96
+ summary: Super DRY Configuration Management for Ruby, Rails, and Sinatra Apps. With Pluggable NoSQL/SQL backends using Moneta
86
97
  test_files: []
87
98
 
@@ -1,59 +0,0 @@
1
- class Setting < ActiveRecord::Base
2
- acts_as_settable
3
-
4
- # set_table_name 'settings'
5
- # attr_protected :is_proc, :interpolations
6
-
7
- # serialize :value
8
- # serialize :interpolations, Array
9
-
10
- def save_with_setting
11
- if save_without_setting
12
- # update hash, eventually, just in case
13
- end
14
- end
15
- alias_method_chain :save, :setting
16
-
17
- class << self
18
- # adjust the arguments, so we find automatically by key
19
- def find(*args)
20
- key = args.first
21
- unless key.to_s =~ /^(all|first|last)$/
22
- args[0] = :first
23
- options = args.extract_options!
24
- options[:conditions] = {:key => key.to_s} if key
25
- args << options
26
- end
27
- result = super(*args)
28
- # sync the global hash if necessary
29
- sync_settings_hash(result)
30
-
31
- result
32
- end
33
-
34
- def scoped(options = {}, &block)
35
- result = super(options, &block)
36
- sync_settings_hash(result)
37
- result
38
- end
39
-
40
- def sync_settings_hash(result)
41
- return unless result
42
- if result.is_a?(Array) || (defined?(ActiveRecord::Relation) && result.is_a?(ActiveRecord::Relation))
43
- result.each do |record|
44
- sync_setting(record)
45
- end
46
- else
47
- sync_setting(result)
48
- end
49
- end
50
-
51
- def sync_setting(record)
52
- record.value = Cockpit.type_cast(record.value, record.cast_as)
53
- if record.respond_to?(:key) && record.configurable.nil?
54
- Settings.store.set_one_without_database(record.key, record.value)
55
- end
56
- end
57
- end
58
-
59
- end
data/init.rb DELETED
@@ -1 +0,0 @@
1
- File.dirname(__FILE__) + "/rails/init.rb"
@@ -1,101 +0,0 @@
1
- module Cockpit
2
-
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
6
-
7
- module ClassMethods
8
- # can be "unique_by_key"
9
- # settings :text do
10
- # ...
11
- # settings :social do
12
- # ...
13
- def acts_as_configurable(*args, &block)
14
- options = args.extract_options!
15
- settings_name = (args.shift || "settings").to_s
16
- clazz_name = self.to_s.downcase.split("::").last
17
-
18
- class_inheritable_accessor settings_name
19
- has_many settings_name, :class_name => "Setting", :as => :configurable
20
-
21
- Settings { send(clazz_name, &block) }
22
-
23
- self.send("#{settings_name}=", ::Settings.for(clazz_name))
24
-
25
- define_method settings_name do |*value|
26
- unless @settings
27
- @settings = self.class.send(settings_name).dup
28
- @settings.configurable = self
29
- end
30
-
31
- unless value.empty?
32
- @settings[value.first]
33
- else
34
- @settings
35
- end
36
- # model-dependent settings.
37
- # requires refactoring the Settings module
38
- # so none of it uses class methods...
39
- end
40
-
41
- end
42
- alias configurable acts_as_configurable
43
- alias settings acts_as_configurable
44
-
45
- def acts_as_settable
46
- belongs_to :configurable, :polymorphic => true
47
- end
48
- end
49
-
50
- def self.get_type(object)
51
- result = case object
52
- when Fixnum
53
- :integer
54
- when Array
55
- :array
56
- when Float # decimal
57
- :float
58
- when String
59
- :string
60
- when Proc
61
- :proc
62
- when TrueClass
63
- :boolean
64
- when FalseClass
65
- :boolean
66
- when DateTime
67
- :datetime
68
- when Time
69
- :time
70
- else
71
- :string
72
- end
73
- end
74
-
75
- def self.type_cast(object, type)
76
- return object if type.nil?
77
- result = case type.to_sym
78
- when :integer
79
- object.to_i
80
- when :array
81
- object.to_a
82
- when :float, :decimal # decimal
83
- object.to_f
84
- when :string, :text
85
- object.to_s
86
- when :boolean
87
- if object == "true" || object == true || object == "1" || object == 1 || object == "t"
88
- true
89
- else
90
- false
91
- end
92
- when :datetime, :timestamp
93
- object.is_a?(String) ? DateTime.parse(object) : object
94
- when :time
95
- object.is_a?(String) ? Time.parse(object) : object
96
- else
97
- object.to_s
98
- end
99
- end
100
-
101
- end
@@ -1,218 +0,0 @@
1
- module Cockpit
2
- module Configuration
3
-
4
- def self.included(base)
5
- base.extend ClassMethods
6
- base.class_eval do
7
- include InstanceMethods
8
- end
9
- end
10
-
11
- module InstanceMethods
12
-
13
- attr_accessor :setting_class, :configurable
14
-
15
- def setting_class
16
- @setting_class ||= ::Setting
17
- end
18
-
19
- def initialize(*args, &block)
20
- store.tree = args.extract_options!
21
- value = args
22
- build(&block)
23
- end
24
-
25
- def build(&block)
26
- tree.instance_eval(&block) if block_given?
27
- end
28
-
29
- def configurable=(object)
30
- @configurable = object
31
- store.configurable = object
32
- end
33
-
34
- # something like this
35
- # Settings.for(@user.id).set(:allow_email => params[:allow_email])
36
- # or
37
- # @user.settings(:allow_email => params[:allow_email])
38
- def for(configurable_id)
39
- self
40
- end
41
-
42
- def each_setting(&block)
43
- tree.each_setting(&block)
44
- end
45
-
46
- def tree
47
- store.tree
48
- end
49
-
50
- def defaults
51
- store.defaults
52
- end
53
-
54
- def store
55
- self.store = :memory if @store.nil?
56
- @store
57
- end
58
-
59
- def empty?
60
- tree.empty?
61
- end
62
-
63
- def store=(value)
64
- options = {:configurable => configurable}
65
- options[:tree] = @store.tree unless @store.nil?
66
- @store = case value
67
- when :memory
68
- Cockpit::Store::Memory.new(self, options)
69
- when :db
70
- Cockpit::Store::Database.new(self, options)
71
- else
72
- value
73
- end
74
- end
75
-
76
- def get(path)
77
- store.get(path)
78
- end
79
- alias_method :[], :get
80
-
81
- def get!(path)
82
- store.get!(path)
83
- end
84
-
85
- def set(value)
86
- store.set(value)
87
- end
88
-
89
- def set!(value)
90
- store.set!(value)
91
- end
92
-
93
- def []=(key, value)
94
- store.set(key => value)
95
- end
96
-
97
- def clear(options = {})
98
- store.clear(options)
99
- end
100
-
101
- def inspect
102
- "<##{self.class.to_s} @tree=#{tree.inspect}/>"
103
- end
104
-
105
- def to_yaml
106
- to_hash.to_yaml
107
- end
108
-
109
- def to_hash
110
- store.tree.to_hash
111
- end
112
-
113
- def method_missing(meth, *args, &block)
114
- if args.empty?
115
- store.get(meth)
116
- else
117
- store.set(meth, args.first)
118
- end
119
- end
120
-
121
- end
122
-
123
- module ClassMethods
124
-
125
- def setting_class
126
- global.setting_class
127
- end
128
-
129
- def global(&block)
130
- @global ||= new
131
- @global.build(&block)
132
- @global
133
- end
134
-
135
- def define!(*args, &block)
136
- options = args.extract_options!
137
- path = args.first
138
- if path && !path.is_a?(Hash) && !block_given?
139
- global[path]
140
- elsif !options.empty?
141
- global.set(options)
142
- else
143
- global(&block)
144
- end
145
- end
146
-
147
- # something like this
148
- # Settings.for(@user.id).set(:allow_email => params[:allow_email])
149
- # or
150
- # @user.settings(:allow_email => params[:allow_email])
151
- def for(name)
152
- Settings.new(get(name).dup)
153
- end
154
-
155
- def tree
156
- global.tree
157
- end
158
-
159
- def defaults
160
- global.defaults
161
- end
162
-
163
- def store
164
- global.store
165
- end
166
-
167
- def store=(value)
168
- global.store = value
169
- end
170
-
171
- def get(path)
172
- global.get(path)
173
- end
174
- alias_method :[], :get
175
-
176
- def get!(path)
177
- global.get!(path)
178
- end
179
-
180
- def set(value)
181
- global.set(value)
182
- end
183
-
184
- def set!(value)
185
- global.set!(value)
186
- end
187
-
188
- def []=(key, value)
189
- global.set(key => value)
190
- end
191
-
192
- def clear(options = {})
193
- global.clear(options)
194
- end
195
-
196
- def empty?
197
- global.empty?
198
- end
199
-
200
- def inspect
201
- global.inspect
202
- end
203
-
204
- def to_yaml
205
- global.to_yaml
206
- end
207
-
208
- def to_hash
209
- global.to_hash
210
- end
211
-
212
- def method_missing(meth, *args, &block)
213
- global.method_missing(meth, *args, &block)
214
- end
215
-
216
- end
217
- end
218
- end
@@ -1,55 +0,0 @@
1
- module Cockpit
2
- # Represents the definition of a preference for a particular model
3
- class Definition
4
- # The data type for the content stored in this preference type
5
- attr_reader :type
6
-
7
- def initialize(name, *args) #:nodoc:
8
- options = args.extract_options!
9
-
10
- @type = args.first ? args.first.to_sym : :boolean
11
-
12
- # Create a column that will be responsible for typecasting
13
- @column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == :any ? nil : @type.to_s)
14
-
15
- @group_defaults = (options[:group_defaults] || {}).inject({}) do |defaults, (group, default)|
16
- defaults[group.is_a?(Symbol) ? group.to_s : group] = type_cast(default)
17
- defaults
18
- end
19
- end
20
-
21
- # The name of the preference
22
- def name
23
- @column.name
24
- end
25
-
26
- # The default value to use for the preference in case none have been
27
- # previously defined
28
- def default_value(group = nil)
29
- @group_defaults.include?(group) ? @group_defaults[group] : @column.default
30
- end
31
-
32
- # Determines whether column backing this preference stores numberic values
33
- def number?
34
- @column.number?
35
- end
36
-
37
- # Typecasts the value based on the type of preference that was defined.
38
- # This uses ActiveRecord's typecast functionality so the same rules for
39
- # typecasting a model's columns apply here.
40
- def type_cast(value)
41
- @type == :any ? value : @column.type_cast(value)
42
- end
43
-
44
- # Typecasts the value to true/false depending on the type of preference
45
- def query(value)
46
- if !(value = type_cast(value))
47
- false
48
- elsif number?
49
- !value.zero?
50
- else
51
- !value.blank?
52
- end
53
- end
54
- end
55
- end
@@ -1,25 +0,0 @@
1
- class Hash
2
- def recursively_symbolize_keys!
3
- self.symbolize_keys!
4
- self.values.each do |v|
5
- if v.is_a? Hash
6
- v.recursively_symbolize_keys!
7
- elsif v.is_a? Array
8
- v.recursively_symbolize_keys!
9
- end
10
- end
11
- self
12
- end
13
- end
14
-
15
- class Array
16
- def recursively_symbolize_keys!
17
- self.each do |item|
18
- if item.is_a? Hash
19
- item.recursively_symbolize_keys!
20
- elsif item.is_a? Array
21
- item.recursively_symbolize_keys!
22
- end
23
- end
24
- end
25
- end