dionysus 0.0.0.pre1 → 0.1.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.
data/README.md CHANGED
@@ -17,6 +17,11 @@ Installation
17
17
 
18
18
  gem install dionysus
19
19
 
20
+ Usage
21
+ -----
22
+
23
+ First, add "dionysus" to your Gemfile or whatever other dependency system you're using. Then, you'll need to require each file as you need them. Dionysus is setup *à la carte* since parts are bound to conflict with something you're using at some point.
24
+
20
25
  Resources
21
26
  ---------
22
27
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.0.pre1
1
+ 0.1.0
@@ -0,0 +1,60 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{dionysus}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Travis D. Warlick, Jr."]
12
+ s.date = %q{2010-03-15}
13
+ s.email = %q{warlickt@operissystems.com}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.md"
17
+ ]
18
+ s.files = [
19
+ ".document",
20
+ ".gitignore",
21
+ "LICENSE",
22
+ "README.md",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "dionysus.gemspec",
26
+ "lib/dionysus.rb",
27
+ "lib/dionysus/configuration.rb",
28
+ "spec/configuration_spec.rb",
29
+ "spec/dionysus_spec.rb",
30
+ "spec/spec.opts",
31
+ "spec/spec_helper.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/tekwiz/dionysus}
34
+ s.rdoc_options = ["--charset=UTF-8"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.3.6}
37
+ s.summary = %q{A helpful set of utility classes, generators, and command-line tools.}
38
+ s.test_files = [
39
+ "spec/configuration_spec.rb",
40
+ "spec/dionysus_spec.rb",
41
+ "spec/spec_helper.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
49
+ s.add_runtime_dependency(%q<activesupport>, ["= 3.0.0.beta"])
50
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
51
+ else
52
+ s.add_dependency(%q<activesupport>, ["= 3.0.0.beta"])
53
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
54
+ end
55
+ else
56
+ s.add_dependency(%q<activesupport>, ["= 3.0.0.beta"])
57
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
58
+ end
59
+ end
60
+
@@ -3,7 +3,7 @@ gem 'activesupport', '3.0.0.beta'
3
3
  require 'active_support/all'
4
4
 
5
5
  ##
6
- # The top-level for Phoebe
6
+ # The top-level for Dionysus
7
7
  module Dionysus
8
8
  # The current version
9
9
  VERSION = File.read(File.join(File.dirname(__FILE__), '..', 'VERSION')).strip
@@ -0,0 +1,193 @@
1
+ ##
2
+ # = Configuration
3
+ #
4
+ # require 'dionysus/configuration'
5
+ #
6
+ # A simple configuration system that can work in a "hard-keys" or "soft-keys"
7
+ # mode. In the "hard-keys" mode, the configuration will only allow a specific
8
+ # set of keys given on initialization. In "soft-keys" mode, the configuration
9
+ # will accept any keys, at any time, as long as they are valid.
10
+ #
11
+ # == Soft Keys Example:
12
+ #
13
+ # config = Configuration.new(false, :a_key => 'some value')
14
+ # config.soft_keys? #=> true
15
+ # config.hard_keys? #=> false
16
+ # config.a_key = 'new value'
17
+ # config.a_key #=> 'new value'
18
+ # config.another_key = 'some value'
19
+ # config.anoter_key #=> 'some value'
20
+ #
21
+ # == Hard Keys Example:
22
+ #
23
+ # config = Configuration.new(:foo, :bar, {:wowsers => 'wow', :foo => 'fooey'})
24
+ # config.hard_keys? #=> true
25
+ # config.soft_keys? #=> false
26
+ # config.a_key #=> raises NoMethodError
27
+ # config[:a_key] #=> raises ArgumentError
28
+ # config.foo = 'fooey'
29
+ # config.bar #=> nil
30
+ # config.wowsers #=> 'wow'
31
+ #
32
+ # == Multi Access
33
+ #
34
+ # Values are accessible through the "magic" methods, get() and set() methods,
35
+ # and hash brackets. These will all give the same result:
36
+ # config.a_key
37
+ # config[:a_key]
38
+ # config['a_key']
39
+ # config.get(:a_key)
40
+ # config.get('a_key')
41
+ #
42
+ # == Object Keys
43
+ #
44
+ # All keys are converted to strings and then to symbols:
45
+ # o = Object.new
46
+ # config.set(o, 'foo')
47
+ # config.get(o) #=> 'foo'
48
+ # config.keys #=> [:'#<Object:0x190544c>']
49
+ class Configuration
50
+ # Regex to define a valid key
51
+ VALID_KEY = '[A-Za-z0-9\-_]+'
52
+
53
+ ##
54
+ # Create the configuration.
55
+ #
56
+ # Soft Keys mode:: Pass +false+ as the first argument.
57
+ # Hard Keys mode:: Default, or pass +true+ as the first argument.
58
+ def initialize( *args )
59
+ defaults = (args.last.is_a?(Hash) ? args.pop : {})
60
+
61
+ if _hard_keys?(defaults, args)
62
+ @keys = _normalize_hard_keys(defaults, args)
63
+ raise ArgumentError, 'Cannot have a hard keys configuration with no keys' if @keys.empty?
64
+ else
65
+ @keys = nil
66
+ raise ArgumentError, 'Cannot define hard keys in soft keys mode' if args.any?
67
+ end
68
+
69
+ _initialize_config(defaults)
70
+ end
71
+
72
+ ##
73
+ # +true+ if the configuration is limited to a specific set of keys.
74
+ def hard_keys?() !!@keys; end
75
+
76
+ ##
77
+ # +true+ if the configuration is NOT limited to a specific set of keys.
78
+ # (Inverse) of +hard_keys?+
79
+ def soft_keys?() !@keys; end
80
+
81
+ ##
82
+ # The set of keys for the configuration. If this is a hard keys
83
+ # configuration, it returns the possible keys. Otherwise, it returns the
84
+ # set keys.
85
+ def keys() @keys || @config.keys; end
86
+
87
+ ##
88
+ # +false+ if there are any values set.
89
+ def empty?() @config.empty?; end
90
+
91
+ ##
92
+ # The number of configurations set.
93
+ def size() @config.size; end
94
+
95
+ ##
96
+ # Set the configuration key to the given value.
97
+ def set(key, value) validate_key(key); @config[_normalize_key(key)] = value; end
98
+ alias_method :'[]=', :set
99
+
100
+ ##
101
+ # Get the configuration value.
102
+ def get(key) validate_key(key); @config[_normalize_key(key)]; end
103
+ alias_method :'[]', :get
104
+
105
+ ##
106
+ # Delete the configuration value.
107
+ def delete(key) @config.delete(key); end
108
+
109
+ ##
110
+ # Convert the configuration to a hash.
111
+ def to_hash() @config.to_hash; end
112
+
113
+ ##
114
+ # +true+ if the key is valid.
115
+ def valid_key?( key )
116
+ return false if key.blank?
117
+ key = _normalize_key(key).to_s
118
+ key =~ /^#{VALID_KEY}$/ and !self.methods.include?(key)
119
+ end
120
+
121
+ ##
122
+ # +true+ if the key is allowed.
123
+ def allowed_key?( key )
124
+ @keys.nil? ? true : @keys.include?(_normalize_key(key))
125
+ end
126
+
127
+ private
128
+
129
+ ##
130
+ # If the key is invalid, it raises an error.
131
+ def validate_key( key )
132
+ return true if valid_key?(key) and allowed_key?(key)
133
+ raise ArgumentError, "Invalid key: #{key}"
134
+ end
135
+
136
+ ##
137
+ # Determine if the set of arguments is requesting a hard keys configuration.
138
+ #
139
+ # This is a hard key configuration set if
140
+ # 1) the first argument is NOT false
141
+ # 2) there are explicit keys defined
142
+ # 3) there is a default set of arguments
143
+ def _hard_keys?( defaults, args )
144
+ if args.first == true or args.first == false
145
+ args.shift
146
+ else
147
+ args.any? or (defaults and defaults.any?)
148
+ end
149
+ end
150
+
151
+ ##
152
+ # Normalize the keys and keys from the defaults hash into the hard keys
153
+ # array.
154
+ def _normalize_hard_keys( defaults, keys )
155
+ returning [] do |keys_|
156
+ (keys + defaults.keys).uniq.collect {|k| k.to_s}.sort.each do |key|
157
+ raise ArgumentError, "Invalid key: '#{key}'" unless valid_key?(key)
158
+ keys_ << _normalize_key(key)
159
+ end
160
+ end.freeze
161
+ end
162
+
163
+ ##
164
+ # Normalize a key by converting it to a string and then a symbol.
165
+ def _normalize_key( key )
166
+ key.to_s.to_sym
167
+ end
168
+
169
+ ##
170
+ # Initialize the default config hash
171
+ def _initialize_config( defaults )
172
+ @config = {}
173
+ defaults.each { |key, value| set(key, value) }
174
+ @config
175
+ end
176
+
177
+ ##
178
+ # The magic. Enables +config.foo+ and +config.foo=+ to map to the getters
179
+ # and setters.
180
+ def method_missing( method_name, *args, &block )
181
+ match = method_name.to_s.match(/^(#{VALID_KEY})(=)??\Z/)
182
+ key, setter = _normalize_key(match[1]), (match[2] == '=')
183
+
184
+ if allowed_key?(key) and !block_given?
185
+ if setter and args.length == 1
186
+ return set(key, args.first)
187
+ elsif match[1] and match[2].nil? and args.length == 0
188
+ return get(key)
189
+ end
190
+ end
191
+ super
192
+ end
193
+ end
@@ -0,0 +1,176 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'dionysus/configuration'
3
+
4
+ describe Configuration do
5
+ describe "basics" do
6
+ before(:each) { @c = Configuration.new(false) }
7
+
8
+ it "should be empty when no defaults" do
9
+ @c.size.should == 0
10
+ @c.should be_empty
11
+ end
12
+
13
+ it "should be accessible by hash brackets" do
14
+ @c[:something] = 'a value'
15
+ @c['something-else'] = 'b value'
16
+ @c.should_not be_empty
17
+ @c[:something].should == 'a value'
18
+ @c['something'].should == 'a value'
19
+ @c[:'something-else'].should == 'b value'
20
+ @c['something-else'].should == 'b value'
21
+ end
22
+
23
+ it "should be accessible by method name" do
24
+ @c.something = 'a value'
25
+ @c.should_not be_empty
26
+ @c.something.should == 'a value'
27
+ end
28
+
29
+ it "should be accessible by get/set methods" do
30
+ @c.set(:something, 'a value')
31
+ @c.set('something-else', 'b value')
32
+ @c.should_not be_empty
33
+ @c.get(:something).should == 'a value'
34
+ @c.get('something').should == 'a value'
35
+ @c.get(:'something-else').should == 'b value'
36
+ @c.get('something-else').should == 'b value'
37
+ end
38
+
39
+ it "should not allow keys with the same name as defined methods." do
40
+ lambda { @c.set(:set, 'wowsers') }.should raise_error(ArgumentError, "Invalid key: set")
41
+ @c.to_hash[:set].should be_nil
42
+ lambda { @c[:set] = 'wowsers' }.should raise_error(ArgumentError, "Invalid key: set")
43
+ @c.to_hash[:set].should be_nil
44
+ lambda { @c.set = 'wowsers' }.should raise_error(ArgumentError, "Invalid key: set")
45
+ @c.to_hash[:set].should be_nil
46
+ end
47
+
48
+ it "should not allow keys that do not conform to the allowed regex." do
49
+ lambda { @c.set('^&^&*^&*', 'wowsers') }.should raise_error(ArgumentError, "Invalid key: ^&^&*^&*")
50
+ lambda { @c.set('', 'wowsers') }.should raise_error(ArgumentError, "Invalid key: ")
51
+ lambda { @c.set(nil, 'wowsers') }.should raise_error(ArgumentError, "Invalid key: ")
52
+ lambda { @c.set(Object.new, 'wowsers') }.should raise_error(ArgumentError, /^Invalid key: #<Object:0x[a-fA-F0-9]+>$/)
53
+ end
54
+
55
+ it "should revert to the normal method_missing with a block" do
56
+ lambda { @c.not_a_key { 1+1 } }.should raise_error(NoMethodError)
57
+ end
58
+
59
+ it "should revert to the normal method_missing with any arguments" do
60
+ lambda { @c.not_a_key('fooey') }.should raise_error(NoMethodError)
61
+ lambda { @c.not_a_key(nil) }.should raise_error(NoMethodError)
62
+ end
63
+
64
+ it "should revert to normal method_missing with a setter and more than 1 argument" do
65
+ lambda { @c.send(:not_a_key=, 'fooey', nil) }.should raise_error(NoMethodError)
66
+ end
67
+ end
68
+
69
+ describe "with soft keys" do
70
+ before(:each) { @c = Configuration.new(false) }
71
+
72
+ it 'should be soft keys' do
73
+ @c.should be_soft_keys
74
+ end
75
+
76
+ it 'should initialize empty' do
77
+ @c.size.should == 0
78
+ @c.should be_empty
79
+ end
80
+
81
+ it "should take defaults" do
82
+ @c = Configuration.new(false, :a_val => 'some value')
83
+ @c.should be_soft_key
84
+ @c.a_val.should == 'some value'
85
+ @c.size.should == 1
86
+ @c.should_not be_empty
87
+ end
88
+
89
+ it "should remove the key on delete" do
90
+ @c.foo = 'fooey'
91
+ @c.keys.should == [:foo]
92
+
93
+ @c.delete :foo
94
+ @c.foo.should be_nil
95
+ @c.keys.should be_empty
96
+ end
97
+
98
+ it "should not remove the key on set nil" do
99
+ @c.foo = 'fooey'
100
+ @c.keys.should == [:foo]
101
+
102
+ @c.foo = nil
103
+ @c.foo.should be_nil
104
+ @c.keys.should == [:foo]
105
+ end
106
+
107
+ it "should allow any key" do
108
+ @c.allowed_key?('fjdasfiodsaifo').should be_true
109
+ @c.allowed_key?('^&*%^*9789').should be_true
110
+ @c.allowed_key?(Object.new).should be_true
111
+ end
112
+
113
+ it "should not allow setting hard keys" do
114
+ lambda { @c = Configurat.new(false, :a_hard_key, :a_val => 'some_value') }.should
115
+ raise_error(ArgumentError, 'Cannot define hard keys in soft keys mode')
116
+
117
+ end
118
+ end
119
+
120
+ describe "with hard keys" do
121
+ before(:each) { @c = Configuration.new(:foo, :bar) }
122
+
123
+ it "should be hard keys" do
124
+ @c.should be_hard_keys
125
+ end
126
+
127
+ it "should initialize empty" do
128
+ @c.size.should == 0
129
+ @c.should be_empty
130
+ @c.keys.should == [:bar, :foo]
131
+ end
132
+
133
+ it "should take defaults" do
134
+ @c = Configuration.new(:foo, :bar, {'wowsers' => 'wow', :bar => 'fooey'})
135
+ @c.keys.should == [:bar, :foo, :wowsers]
136
+ @c.size.should == 2
137
+ @c.foo.should == nil
138
+ @c.bar.should == 'fooey'
139
+ @c[:wowsers].should == 'wow'
140
+ end
141
+
142
+ it "should not remove the key on delete" do
143
+ @c.foo = 'fooey'
144
+ @c.keys.should include(:foo)
145
+ @c.size.should == 1
146
+
147
+ @c.delete :foo
148
+ @c.foo.should be_nil
149
+ @c.keys.should include(:foo)
150
+ @c.size.should == 0
151
+ end
152
+
153
+ it "should not remove the key on set nil" do
154
+ @c.foo = 'fooey'
155
+ @c.keys.should include(:foo)
156
+ @c.size.should == 1
157
+
158
+ @c.foo = nil
159
+ @c.foo.should be_nil
160
+ @c.keys.should include(:foo)
161
+ @c.size.should == 1
162
+ end
163
+
164
+ it "should allow only the hard keys" do
165
+ @c.allowed_key?('fjdasfiodsaifo').should be_false
166
+ @c.allowed_key?('^&*%^*9789').should be_false
167
+ @c.allowed_key?(Object.new).should be_false
168
+ @c.allowed_key?(:foo).should be_true
169
+ @c.allowed_key?('foo').should be_true
170
+ end
171
+
172
+ it "should revert to the normal method_missing an unallowed key" do
173
+ lambda { @c.not_a_key }.should raise_error(NoMethodError)
174
+ end
175
+ end
176
+ end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dionysus
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: true
4
+ prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 0
9
- - pre1
10
- version: 0.0.0.pre1
9
+ version: 0.1.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Travis D. Warlick, Jr.
@@ -63,7 +62,10 @@ files:
63
62
  - README.md
64
63
  - Rakefile
65
64
  - VERSION
65
+ - dionysus.gemspec
66
66
  - lib/dionysus.rb
67
+ - lib/dionysus/configuration.rb
68
+ - spec/configuration_spec.rb
67
69
  - spec/dionysus_spec.rb
68
70
  - spec/spec.opts
69
71
  - spec/spec_helper.rb
@@ -85,13 +87,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
87
  version: "0"
86
88
  required_rubygems_version: !ruby/object:Gem::Requirement
87
89
  requirements:
88
- - - ">"
90
+ - - ">="
89
91
  - !ruby/object:Gem::Version
90
92
  segments:
91
- - 1
92
- - 3
93
- - 1
94
- version: 1.3.1
93
+ - 0
94
+ version: "0"
95
95
  requirements: []
96
96
 
97
97
  rubyforge_project:
@@ -100,5 +100,6 @@ signing_key:
100
100
  specification_version: 3
101
101
  summary: A helpful set of utility classes, generators, and command-line tools.
102
102
  test_files:
103
+ - spec/configuration_spec.rb
103
104
  - spec/dionysus_spec.rb
104
105
  - spec/spec_helper.rb