dsl_accessor 0.3.3 → 0.4.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.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 [maiha@wota.jp]
1
+ Copyright (c) 2010 [maiha@wota.jp]
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,30 +1,3 @@
1
- require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
4
-
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
-
8
- desc 'Test the dsl_accessor plugin.'
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.pattern = 'test/**/*_test.rb'
12
- t.verbose = true
13
- end
14
-
15
- desc 'Generate documentation for the dsl_accessor plugin.'
16
- Rake::RDocTask.new(:rdoc) do |rdoc|
17
- rdoc.rdoc_dir = 'rdoc'
18
- rdoc.title = 'DslAccessor'
19
- rdoc.options << '--line-numbers' << '--inline-source'
20
- rdoc.rdoc_files.include('README')
21
- rdoc.rdoc_files.include('lib/**/*.rb')
22
- end
23
-
24
-
25
- ######################################################################
26
- ### for gem
27
-
28
1
  require 'rubygems'
29
2
  require 'rake/gempackagetask'
30
3
 
@@ -33,22 +6,24 @@ AUTHOR = "maiha"
33
6
  EMAIL = "maiha@wota.jp"
34
7
  HOMEPAGE = "http://github.com/maiha/dsl_accessor"
35
8
  SUMMARY = "This plugin gives hybrid accessor class methods to classes by DSL like definition"
36
- GEM_VERSION = "0.3.3"
9
+ GEM_VERSION = "0.4.0"
37
10
 
38
11
  spec = Gem::Specification.new do |s|
39
- # s.rubyforge_project = 'merb'
40
- s.name = GEM_NAME
41
- s.version = GEM_VERSION
42
- s.platform = Gem::Platform::RUBY
43
- s.has_rdoc = true
44
- s.extra_rdoc_files = ["README", "LICENSE"]
45
- s.summary = SUMMARY
46
- s.description = s.summary
47
- s.author = AUTHOR
48
- s.email = EMAIL
49
- s.homepage = HOMEPAGE
50
- s.require_path = 'lib'
51
- s.files = %w(LICENSE README Rakefile) + Dir.glob("{core_ext,lib,spec,tasks,test}/**/*")
12
+ s.rubyforge_project = 'asakusarb'
13
+ s.executables = []
14
+ s.name = GEM_NAME
15
+ s.version = GEM_VERSION
16
+ s.platform = Gem::Platform::RUBY
17
+ s.has_rdoc = true
18
+ s.extra_rdoc_files = ["README", "MIT-LICENSE"]
19
+ s.summary = SUMMARY
20
+ s.description = s.summary
21
+ s.author = AUTHOR
22
+ s.email = EMAIL
23
+ s.homepage = HOMEPAGE
24
+ s.require_path = 'lib'
25
+ s.add_dependency('optionize', '>= 0.1.0')
26
+ s.files = %w(MIT-LICENSE README Rakefile) + Dir.glob("{lib,spec,core_ext}/**/*")
52
27
  end
53
28
 
54
29
  Rake::GemPackageTask.new(spec) do |pkg|
@@ -72,3 +47,6 @@ task :gemspec do
72
47
  end
73
48
  end
74
49
 
50
+ require 'spec/rake/spectask'
51
+ desc 'Default: run spec examples'
52
+ task :default => 'spec'
@@ -1,11 +1,17 @@
1
- unless Class.new.respond_to?(:write_inheritable_attribute)
2
- require File.dirname(__FILE__) + "/../core_ext/duplicable" unless Object.new.respond_to?(:duplicable?)
3
- require File.dirname(__FILE__) + "/../core_ext/class/inheritable_attributes"
4
- end
5
-
6
1
  unless Module.new.respond_to?(:delegate)
7
2
  require File.dirname(__FILE__) + "/../core_ext/module/delegation"
8
3
  end
9
4
 
10
- require File.dirname(__FILE__) + '/../core_ext/class/dsl_accessor'
5
+ require File.dirname(__FILE__) + '/dsl_accessor/accessor'
6
+ require File.dirname(__FILE__) + '/dsl_accessor/stores'
7
+
8
+ class Module
9
+ include DslAccessor
10
+ include DslAccessor::Stores::Basic
11
+ end
12
+
13
+ class Class
14
+ include DslAccessor
15
+ include DslAccessor::Stores::Inherit
16
+ end
11
17
 
@@ -0,0 +1,93 @@
1
+ require 'optionize'
2
+
3
+ module DslAccessor
4
+ def dsl_accessor_reader(key, *args)
5
+ key = key.to_s
6
+ if args.empty?
7
+ # getter method
8
+ if !dsl_accessor_key?(key)
9
+ default = dsl_accessor_get("#{key}_default")
10
+ value = default ? default.call : nil
11
+ dsl_accessor_writer(key, value)
12
+ end
13
+ dsl_accessor_get(key)
14
+ else
15
+ # setter method
16
+ dsl_accessor_writer(key, *args)
17
+ end
18
+ end
19
+
20
+ def dsl_accessor_writer(key, *args)
21
+ case args.size
22
+ when 1
23
+ writer = dsl_accessor_get("#{key}_writer")
24
+ value = writer ? writer.call(*args) : args.first
25
+ dsl_accessor_set("#{key}", value)
26
+ else
27
+ raise ArgumentError, "'#{key}=' expected one argument, but got #{args.size} args"
28
+ end
29
+ end
30
+
31
+ def dsl_accessor(*args, &block)
32
+ opts = Optionize.new(args, :name, :default)
33
+ name = opts.name
34
+
35
+ if !name and !block
36
+ raise "dsl_accessor expects at least one arg"
37
+ end
38
+
39
+ writer =
40
+ case opts.writer
41
+ when NilClass then Proc.new{|value| value}
42
+ when Symbol then Proc.new{|value| __send__(opts.writer, value)}
43
+ when Proc then opts.writer
44
+ else raise TypeError, "DSL Error: writer should be a symbol or proc. but got `#{opts.writer.class}'"
45
+ end
46
+ dsl_accessor_set("#{name}_writer", writer)
47
+
48
+ default =
49
+ case opts.default
50
+ when NilClass then nil
51
+ when [] then Proc.new{[]}
52
+ when {} then Proc.new{{}}
53
+ when Symbol then Proc.new{__send__(opts.default)}
54
+ when Proc then opts.default
55
+ else Proc.new{opts.default}
56
+ end
57
+ dsl_accessor_set("#{name}_default", default)
58
+
59
+ meta_class = (class << self; self; end)
60
+
61
+ if opts.instance and !is_a?(Class)
62
+ raise ArgumentError, ":instance option is implemented in only Class"
63
+ end
64
+
65
+ case opts.instance
66
+ when nil
67
+ # nop
68
+ when true
69
+ delegate name, :to=>"self.class"
70
+ when Symbol
71
+ module_eval(<<-EOS, "(__DSL_ACCESSOR__)", 1)
72
+ def #{ name }
73
+ @#{opts.instance} or
74
+ raise TypeError, "DSL Error: missing @#{opts.instance} for %s##{name}" % self.class.name
75
+ @#{opts.instance}.respond_to?(:[]) or
76
+ raise TypeError, "DSL Error: expected @#{opts.instance}[] is implemented (%s##{name})" % self.class.name
77
+ @#{opts.instance}[:#{ name }] || self.class.#{ name }
78
+ end
79
+ EOS
80
+ else
81
+ raise TypeError, "DSL Error: :instance should be true or Symbol, but got `%s' class" % opts.instance.class
82
+ end
83
+
84
+ instance_eval <<-EOS
85
+ def #{name}(*args)
86
+ dsl_accessor_reader("#{name}", *args)
87
+ end
88
+ def #{name}=(*args)
89
+ dsl_accessor_writer("#{name}", *args)
90
+ end
91
+ EOS
92
+ end
93
+ end
@@ -0,0 +1,60 @@
1
+ module DslAccessor
2
+ module Stores
3
+ module Basic
4
+ # testing
5
+ def dsl_accessor_attributes
6
+ @dsl_accessor_attributes ||= {}
7
+ end
8
+
9
+ def dsl_accessor_key?(key)
10
+ dsl_accessor_attributes.has_key?(key)
11
+ end
12
+
13
+ def dsl_accessor_get(key)
14
+ dsl_accessor_attributes[key]
15
+ end
16
+
17
+ def dsl_accessor_set(key, val)
18
+ dsl_accessor_attributes[key] = val
19
+ end
20
+ end
21
+
22
+ module Inherit
23
+ # testing
24
+ def dsl_accessor_attributes
25
+ @dsl_accessor_attributes ||= {}
26
+ end
27
+
28
+ def dsl_accessor_key?(key)
29
+ dsl_accessor_attributes.has_key?(key)
30
+ end
31
+
32
+ def dsl_accessor_get(key)
33
+ if dsl_accessor_key?(key)
34
+ dsl_accessor_attributes[key]
35
+ else
36
+ superclass ? superclass.dsl_accessor_get(key) : nil
37
+ end
38
+ end
39
+
40
+ def dsl_accessor_set(key, val)
41
+ dsl_accessor_attributes[key] = val
42
+ end
43
+ end
44
+
45
+ module InheritableAttributes
46
+ # testing
47
+ def dsl_accessor_key?(key)
48
+ inheritable_attributes.has_key?(key)
49
+ end
50
+
51
+ def dsl_accessor_get(key)
52
+ read_inheritable_attribute(key)
53
+ end
54
+
55
+ def dsl_accessor_set(key, val)
56
+ write_inheritable_attribute(key, val)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,58 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+
3
+ describe DslAccessor do
4
+ it "class should provide 'dsl_accessor'" do
5
+ Class.new.should respond_to(:dsl_accessor)
6
+ end
7
+ end
8
+
9
+
10
+ describe "dsl_accessor(:foo)" do
11
+ before do
12
+ @klass = new_class { dsl_accessor :foo }
13
+ end
14
+
15
+ it "should provide 'foo' method" do
16
+ @klass.should respond_to(:foo)
17
+ end
18
+
19
+ it "should accept nil for default value" do
20
+ @klass.foo.should == nil
21
+ end
22
+
23
+ it "should provide 'foo=' method" do
24
+ @klass.should respond_to(:foo=)
25
+ end
26
+
27
+ it "#foo= should raise ArgumentError" do
28
+ lambda { @klass.send(:foo=) }.should raise_error(ArgumentError)
29
+ end
30
+
31
+ it "#foo=(1) should not raise ArgumentError" do
32
+ lambda { @klass.foo = 1 }.should_not raise_error(ArgumentError)
33
+ end
34
+
35
+ it "#foo=(1) should set :foo to 1" do
36
+ @klass.foo = 1
37
+ @klass.foo.should == 1
38
+ end
39
+
40
+ it "#foo=(1, 2) should raise ArgumentError" do
41
+ lambda { @klass.send(:foo=,1,2) }.should raise_error(ArgumentError)
42
+ end
43
+ end
44
+
45
+
46
+ describe "dsl_accessor(:foo, 1)" do
47
+ before do
48
+ @klass = new_class { dsl_accessor :foo, 1 }
49
+ end
50
+
51
+ it "should provide 'foo' method" do
52
+ @klass.should respond_to(:foo)
53
+ end
54
+
55
+ it "should accept 1 for default value" do
56
+ @klass.foo.should == 1
57
+ end
58
+ end
@@ -0,0 +1,39 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+
3
+ describe DslAccessor do
4
+ it "should duplicate blank array automatically" do
5
+ k1 = Class.new
6
+
7
+ array = []
8
+ k1.dsl_accessor :foo, array
9
+
10
+ k1.foo.should == array
11
+ k1.foo.should_not equal(array)
12
+ end
13
+
14
+ it "should duplicate blank hash automatically" do
15
+ k1 = Class.new
16
+
17
+ hash = {}
18
+ k1.dsl_accessor :foo, :default=>hash
19
+
20
+ k1.foo.should == hash
21
+ k1.foo.should_not equal(hash)
22
+ end
23
+
24
+ it "should call the method when symbol given" do
25
+ k1 = Class.new
26
+ def k1.construct
27
+ 1
28
+ end
29
+ k1.dsl_accessor :foo, :default=>:construct
30
+
31
+ k1.foo.should == 1
32
+ end
33
+
34
+ it "should call it when proc given" do
35
+ k1 = Class.new
36
+ k1.dsl_accessor :foo, :default=>proc{1}
37
+ k1.foo.should == 1
38
+ end
39
+ end
@@ -1,21 +1,48 @@
1
1
  require File.join( File.dirname(__FILE__), "spec_helper" )
2
2
 
3
3
  describe DslAccessor do
4
- module Exts
5
- class All
6
- end
4
+ # | foo | bar | baz | qux | quux |
5
+ # Bottom | * | * | o | o | |
6
+ # Middle | | o | | + | o |
7
+ # Top | + | | + | o | o |
8
+ #
9
+ # *) dsl_accessor :foo
10
+ # o) dsl_accessor :foo, 'val'
11
+ # +) foo 'val'
7
12
 
8
- class Base < All
9
- end
13
+ class Bottom
14
+ dsl_accessor :foo
15
+ dsl_accessor :bar
16
+ dsl_accessor :baz, 'baz1'
17
+ dsl_accessor :qux, 'qux1'
10
18
  end
11
19
 
12
- module Exts
13
- class All
14
- dsl_accessor :ext, "*"
15
- end
20
+ class Middle < Bottom
21
+ dsl_accessor :bar, 'bar2'
22
+ qux 'qux2'
23
+ dsl_accessor :quux, 'quux2'
24
+ end
25
+
26
+ class Top < Middle
27
+ foo 'foo3'
28
+ baz 'baz3'
29
+ dsl_accessor :qux , 'qux3'
30
+ dsl_accessor :quux, 'quux3'
31
+ end
32
+
33
+ it "should define accessor methods" do
34
+ Bottom.foo.should == nil
35
+ Bottom.bar.should == nil
36
+ Bottom.baz.should == 'baz1'
37
+ Bottom.qux.should == 'qux1'
38
+ lambda { Bottom.quux }.should raise_error(NameError)
16
39
  end
17
40
 
18
41
  it "should inherit value" do
19
- Exts::Base.ext.should == "*"
42
+ Middle.foo.should == nil
43
+ Middle.bar.should == 'bar2'
44
+ Middle.baz.should == 'baz1'
45
+ Middle.qux.should == 'qux2'
46
+ Middle.quux.should == 'quux2'
20
47
  end
21
48
  end
@@ -0,0 +1,51 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+
3
+ describe "dsl_accessor(:foo, :instance=>true)" do
4
+ before do
5
+ klass = Class.new
6
+ klass.dsl_accessor :foo, :instance=>true
7
+ @klass = klass
8
+ end
9
+
10
+ it "should provide instance method 'foo'" do
11
+ @klass.new.should respond_to(:foo)
12
+ end
13
+
14
+ it "should delegate instance method to class method about reader" do
15
+ @klass.foo 1
16
+ @klass.new.foo.should == 1
17
+ end
18
+ end
19
+
20
+ describe "dsl_accessor(:foo, :instance=>:opts)" do
21
+ before do
22
+ klass = Class.new
23
+ klass.dsl_accessor :foo, :instance=>:opts
24
+ @klass = klass
25
+ @obj = @klass.new
26
+ end
27
+
28
+ it "should raise error when @opts is not set" do
29
+ lambda {
30
+ @obj.foo
31
+ }.should raise_error(/missing @opts/)
32
+ end
33
+
34
+ it "should raise error when @opts is present but not responds to []" do
35
+ @obj.instance_eval "@opts = true"
36
+ lambda {
37
+ @obj.foo
38
+ }.should raise_error(/expected @opts\[\]/)
39
+ end
40
+
41
+ it "should read value from @opts first" do
42
+ @obj.instance_eval "@opts = {:foo=>2}"
43
+ @obj.foo.should == 2
44
+ end
45
+
46
+ it "should read value from class when @opts value is blank" do
47
+ @klass.foo 1
48
+ @obj.instance_eval "@opts = {}"
49
+ @obj.foo.should == 1
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+
3
+ describe Module do
4
+ it "should provide 'dsl_accessor'" do
5
+ Module.new.should respond_to(:dsl_accessor)
6
+ end
7
+
8
+ describe "#dsl_accessor(:foo, 1)" do
9
+ subject {
10
+ mod = Module.new
11
+ mod.dsl_accessor :foo, 1
12
+ mod
13
+ }
14
+ # default value
15
+ its(:foo) { should == 1}
16
+
17
+ it "foo(2) should update value to 2" do
18
+ subject.foo 2
19
+ subject.foo.should == 2
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,11 @@
1
1
  require "rubygems"
2
2
  require "spec"
3
3
 
4
- require File.dirname(__FILE__) + "/../init"
4
+ require File.dirname(__FILE__) + "/../lib/dsl_accessor"
5
5
 
6
+ ######################################################################
7
+ ### Helper methods
8
+
9
+ def new_class(&block)
10
+ Class.new(&block)
11
+ end
@@ -0,0 +1,35 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper" )
2
+
3
+ describe DslAccessor do
4
+ it "should call writer" do
5
+ klass = new_class
6
+
7
+ klass.dsl_accessor :key, "bar", :writer=>proc{|value| "[#{value}]"}
8
+ klass.key.should == "[bar]"
9
+
10
+ klass.key 'foo'
11
+ klass.key.should == "[foo]"
12
+ end
13
+
14
+ it "should call writer even if no default values given" do
15
+ klass = new_class
16
+
17
+ klass.dsl_accessor :key, :writer=>proc{|value| "[#{value}]"}
18
+ klass.key.should == "[]"
19
+
20
+ klass.key 'foo'
21
+ klass.key.should == "[foo]"
22
+ end
23
+
24
+ it "should call the method when symbol given" do
25
+ klass = new_class
26
+
27
+ klass.dsl_accessor :key, :default=>"foo", :writer=>:labelize
28
+ def klass.labelize(val)
29
+ "[#{val}]"
30
+ end
31
+
32
+ klass.key.should == "[foo]"
33
+ end
34
+
35
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dsl_accessor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - maiha
@@ -9,10 +14,23 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-10-19 00:00:00 +09:00
17
+ date: 2010-03-23 00:00:00 +09:00
13
18
  default_executable:
14
- dependencies: []
15
-
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: optionize
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ - 1
30
+ - 0
31
+ version: 0.1.0
32
+ type: :runtime
33
+ version_requirements: *id001
16
34
  description: This plugin gives hybrid accessor class methods to classes by DSL like definition
17
35
  email: maiha@wota.jp
18
36
  executables: []
@@ -21,26 +39,22 @@ extensions: []
21
39
 
22
40
  extra_rdoc_files:
23
41
  - README
24
- - LICENSE
42
+ - MIT-LICENSE
25
43
  files:
26
- - LICENSE
44
+ - MIT-LICENSE
27
45
  - README
28
46
  - Rakefile
29
- - core_ext/duplicable.rb
30
- - core_ext/module/delegation.rb
31
- - core_ext/class/dsl_accessor.rb
32
- - core_ext/class/inheritable_attributes.rb
47
+ - lib/dsl_accessor/stores.rb
48
+ - lib/dsl_accessor/accessor.rb
33
49
  - lib/dsl_accessor.rb
50
+ - spec/accessor_spec.rb
51
+ - spec/writer_spec.rb
34
52
  - spec/inherit_spec.rb
35
- - spec/auto_declared_spec.rb
53
+ - spec/module_spec.rb
54
+ - spec/instance_spec.rb
55
+ - spec/default_spec.rb
36
56
  - spec/spec_helper.rb
37
- - tasks/dsl_accessor_tasks.rake
38
- - test/instance_test.rb
39
- - test/default_test.rb
40
- - test/writer_test.rb
41
- - test/test_helper.rb
42
- - test/dsl_accessor_test.rb
43
- - test/instance_options_test.rb
57
+ - core_ext/module/delegation.rb
44
58
  has_rdoc: true
45
59
  homepage: http://github.com/maiha/dsl_accessor
46
60
  licenses: []
@@ -54,18 +68,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
54
68
  requirements:
55
69
  - - ">="
56
70
  - !ruby/object:Gem::Version
71
+ segments:
72
+ - 0
57
73
  version: "0"
58
- version:
59
74
  required_rubygems_version: !ruby/object:Gem::Requirement
60
75
  requirements:
61
76
  - - ">="
62
77
  - !ruby/object:Gem::Version
78
+ segments:
79
+ - 0
63
80
  version: "0"
64
- version:
65
81
  requirements: []
66
82
 
67
- rubyforge_project:
68
- rubygems_version: 1.3.5
83
+ rubyforge_project: asakusarb
84
+ rubygems_version: 1.3.6
69
85
  signing_key:
70
86
  specification_version: 3
71
87
  summary: This plugin gives hybrid accessor class methods to classes by DSL like definition
@@ -1,93 +0,0 @@
1
- module DslAccessor
2
- def dsl_accessor(*args)
3
- options = args.last.is_a?(Hash) ? args.pop : {}
4
-
5
- # mark auto_declared
6
- name = args.shift or
7
- return @dsl_accessor_auto_declared = true
8
-
9
- options[:default] = args.shift unless args.empty?
10
-
11
- case options[:instance]
12
- when nil
13
- # nop
14
- when :options
15
- module_eval(<<-EOS, "(__DSL_ACCESSOR__)", 1)
16
- def #{ name }
17
- unless @options
18
- raise TypeError, "DSL Error: missing @options for %s##{name}" % self.class.name
19
- end
20
- @options[:#{ name }] || self.class.#{ name }
21
- end
22
- EOS
23
- when true
24
- delegate name, :to=>"self.class"
25
- else
26
- raise TypeError, "DSL Error: :instance should be true or :instance, but got `%s' class" % options[:instance].class
27
- end
28
-
29
- raise TypeError, "DSL Error: options should be a hash. but got `#{options.class}'" unless options.is_a?(Hash)
30
- writer = options[:writer] || options[:setter]
31
- writer =
32
- case writer
33
- when NilClass then Proc.new{|value| value}
34
- when Symbol then Proc.new{|value| __send__(writer, value)}
35
- when Proc then writer
36
- else raise TypeError, "DSL Error: writer should be a symbol or proc. but got `#{options[:writer].class}'"
37
- end
38
- write_inheritable_attribute(:"#{name}_writer", writer)
39
-
40
- default =
41
- case options[:default]
42
- when NilClass then nil
43
- when [] then Proc.new{[]}
44
- when {} then Proc.new{{}}
45
- when Symbol then Proc.new{__send__(options[:default])}
46
- when Proc then options[:default]
47
- else Proc.new{options[:default]}
48
- end
49
- write_inheritable_attribute(:"#{name}_default", default)
50
-
51
- (class << self; self end).class_eval do
52
- define_method("#{name}=") do |value|
53
- writer = read_inheritable_attribute(:"#{name}_writer")
54
- value = writer.call(value) if writer
55
- write_inheritable_attribute(:"#{name}", value)
56
- end
57
-
58
- define_method(name) do |*values|
59
- if values.empty?
60
- # getter method
61
- key = :"#{name}"
62
- if !inheritable_attributes.has_key?(key)
63
- default = read_inheritable_attribute(:"#{name}_default")
64
- value = default ? default.call(self) : nil
65
- __send__("#{name}=", value)
66
- end
67
- read_inheritable_attribute(key)
68
- else
69
- # setter method
70
- __send__("#{name}=", *values)
71
- end
72
- end
73
- end
74
- end
75
-
76
- private
77
- def dsl_accessor_auto_declared?
78
- !!@dsl_accessor_auto_declared
79
- end
80
-
81
- def method_missing(*args, &block)
82
- if dsl_accessor_auto_declared? and args.size == 1 and block
83
- define_method(*args, &block)
84
- else
85
- super
86
- end
87
- end
88
-
89
- end
90
-
91
- class Class
92
- include DslAccessor
93
- end
@@ -1,140 +0,0 @@
1
- # Retain for backward compatibility. Methods are now included in Class.
2
- module ClassInheritableAttributes # :nodoc:
3
- end
4
-
5
- # Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
6
- # their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
7
- # to, for example, an array without those additions being shared with either their parent, siblings, or
8
- # children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
9
- class Class # :nodoc:
10
- def class_inheritable_reader(*syms)
11
- syms.each do |sym|
12
- next if sym.is_a?(Hash)
13
- class_eval <<-EOS
14
- def self.#{sym}
15
- read_inheritable_attribute(:#{sym})
16
- end
17
-
18
- def #{sym}
19
- self.class.#{sym}
20
- end
21
- EOS
22
- end
23
- end
24
-
25
- def class_inheritable_writer(*syms)
26
- options = syms.last.is_a?(::Hash) ? syms.pop : {}
27
- syms.each do |sym|
28
- class_eval <<-EOS
29
- def self.#{sym}=(obj)
30
- write_inheritable_attribute(:#{sym}, obj)
31
- end
32
-
33
- #{"
34
- def #{sym}=(obj)
35
- self.class.#{sym} = obj
36
- end
37
- " unless options[:instance_writer] == false }
38
- EOS
39
- end
40
- end
41
-
42
- def class_inheritable_array_writer(*syms)
43
- options = syms.last.is_a?(::Hash) ? syms.pop : {}
44
- syms.each do |sym|
45
- class_eval <<-EOS
46
- def self.#{sym}=(obj)
47
- write_inheritable_array(:#{sym}, obj)
48
- end
49
-
50
- #{"
51
- def #{sym}=(obj)
52
- self.class.#{sym} = obj
53
- end
54
- " unless options[:instance_writer] == false }
55
- EOS
56
- end
57
- end
58
-
59
- def class_inheritable_hash_writer(*syms)
60
- options = syms.last.is_a?(::Hash) ? syms.pop : {}
61
- syms.each do |sym|
62
- class_eval <<-EOS
63
- def self.#{sym}=(obj)
64
- write_inheritable_hash(:#{sym}, obj)
65
- end
66
-
67
- #{"
68
- def #{sym}=(obj)
69
- self.class.#{sym} = obj
70
- end
71
- " unless options[:instance_writer] == false }
72
- EOS
73
- end
74
- end
75
-
76
- def class_inheritable_accessor(*syms)
77
- class_inheritable_reader(*syms)
78
- class_inheritable_writer(*syms)
79
- end
80
-
81
- def class_inheritable_array(*syms)
82
- class_inheritable_reader(*syms)
83
- class_inheritable_array_writer(*syms)
84
- end
85
-
86
- def class_inheritable_hash(*syms)
87
- class_inheritable_reader(*syms)
88
- class_inheritable_hash_writer(*syms)
89
- end
90
-
91
- def inheritable_attributes
92
- @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
93
- end
94
-
95
- def write_inheritable_attribute(key, value)
96
- if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
97
- @inheritable_attributes = {}
98
- end
99
- inheritable_attributes[key] = value
100
- end
101
-
102
- def write_inheritable_array(key, elements)
103
- write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
104
- write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
105
- end
106
-
107
- def write_inheritable_hash(key, hash)
108
- write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
109
- write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
110
- end
111
-
112
- def read_inheritable_attribute(key)
113
- inheritable_attributes[key]
114
- end
115
-
116
- def reset_inheritable_attributes
117
- @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
118
- end
119
-
120
- private
121
- # Prevent this constant from being created multiple times
122
- EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
123
-
124
- def inherited_with_inheritable_attributes(child)
125
- inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
126
-
127
- if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
128
- new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
129
- else
130
- new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
131
- memo.update(key => value.duplicable? ? value.dup : value)
132
- end
133
- end
134
-
135
- child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
136
- end
137
-
138
- alias inherited_without_inheritable_attributes inherited
139
- alias inherited inherited_with_inheritable_attributes
140
- end
@@ -1,43 +0,0 @@
1
- class Object
2
- # Can you safely .dup this object?
3
- # False for nil, false, true, symbols, and numbers; true otherwise.
4
- def duplicable?
5
- true
6
- end
7
- end
8
-
9
- class NilClass #:nodoc:
10
- def duplicable?
11
- false
12
- end
13
- end
14
-
15
- class FalseClass #:nodoc:
16
- def duplicable?
17
- false
18
- end
19
- end
20
-
21
- class TrueClass #:nodoc:
22
- def duplicable?
23
- false
24
- end
25
- end
26
-
27
- class Symbol #:nodoc:
28
- def duplicable?
29
- false
30
- end
31
- end
32
-
33
- class Numeric #:nodoc:
34
- def duplicable?
35
- false
36
- end
37
- end
38
-
39
- class Class #:nodoc:
40
- def duplicable?
41
- false
42
- end
43
- end
@@ -1,106 +0,0 @@
1
- require File.join( File.dirname(__FILE__), "spec_helper" )
2
-
3
- describe DslAccessor do
4
- before(:each) do
5
- Object.send(:remove_const, :Foo) if Object.const_defined?(:Foo)
6
- class Foo
7
- end
8
- end
9
-
10
- def foo_should_not_be_defined
11
- Foo .should_not respond_to(:foo)
12
- Foo.new.should_not respond_to(:foo)
13
- end
14
-
15
- it "should provide .dsl_accessor_auto_declared as private method" do
16
- Class.private_methods.should include("dsl_accessor_auto_declared?")
17
- end
18
-
19
- it "should provide .dsl_accessor" do
20
- Class.should respond_to(:dsl_accessor)
21
- end
22
-
23
- describe " should raise NoMethodError when we call a method " do
24
- it "without arugments" do
25
- foo_should_not_be_defined
26
- lambda { Foo.foo }.should raise_error(NoMethodError)
27
- foo_should_not_be_defined
28
- end
29
- it "with arguments" do
30
- foo_should_not_be_defined
31
- lambda { Foo.foo(1) }.should raise_error(NoMethodError)
32
- lambda { Foo.foo(1, 2) }.should raise_error(NoMethodError)
33
- foo_should_not_be_defined
34
- end
35
- it "with block" do
36
- foo_should_not_be_defined
37
- lambda { Foo.foo{} }.should raise_error(NoMethodError)
38
- foo_should_not_be_defined
39
- end
40
- it "with arguments and block" do
41
- foo_should_not_be_defined
42
- lambda { Foo.foo(1){} }.should raise_error(NoMethodError)
43
- foo_should_not_be_defined
44
- end
45
- end
46
-
47
- describe ".dsl_accessor without arguments" do
48
- it "should be accepted" do
49
- lambda {
50
- Foo.dsl_accessor
51
- }.should_not raise_error
52
- end
53
-
54
- it "should mark auto_declared" do
55
- Foo.send(:dsl_accessor_auto_declared?).should be_false
56
- Foo.dsl_accessor
57
- Foo.send(:dsl_accessor_auto_declared?).should be_true
58
- end
59
- end
60
-
61
- describe "auto_declared" do
62
- before(:each) do
63
- class Foo
64
- dsl_accessor
65
- end
66
- end
67
-
68
- it "should raise NoMethodError if unknown method with args is called" do
69
- lambda {
70
- Foo.foo(1)
71
- }.should raise_error(NoMethodError)
72
- end
73
-
74
- it "should raise NoMethodError when unknown method is called with args and block" do
75
- lambda {
76
- Foo.foo(1){}
77
- }.should raise_error(NoMethodError)
78
- end
79
-
80
- describe " when unknown method is called with a block" do
81
- it "should trap NoMethodError" do
82
- lambda {
83
- Foo.foo{}
84
- }.should_not raise_error(NoMethodError)
85
- end
86
-
87
- it "should define its instance method automatically" do
88
- foo_should_not_be_defined
89
- Foo.foo{1}
90
- Foo.new.should respond_to(:foo)
91
- Foo.new.foo.should == 1
92
- end
93
- end
94
-
95
- it "should affect nothing to subclasses" do
96
- class Bar < Foo
97
- end
98
-
99
- lambda { Bar.bar }.should raise_error(NoMethodError)
100
- lambda { Bar.bar(1) }.should raise_error(NoMethodError)
101
- lambda { Bar.bar(1, 2) }.should raise_error(NoMethodError)
102
- lambda { Bar.bar{} }.should raise_error(NoMethodError)
103
- lambda { Bar.bar(1){} }.should raise_error(NoMethodError)
104
- end
105
- end
106
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :dsl_accessor do
3
- # # Task goes here
4
- # end
@@ -1,64 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
-
4
- class DslDefaultAccessorTest < Test::Unit::TestCase
5
-
6
- class CoolActiveRecord
7
- dsl_accessor :primary_key, :default=>"id"
8
- dsl_accessor :table_name, :default=>proc{|klass| klass.name.split(/::/).last.downcase+"s"}
9
- end
10
-
11
- class Item < CoolActiveRecord
12
- end
13
-
14
- class User < CoolActiveRecord
15
- end
16
-
17
- class Folder
18
- dsl_accessor :array_folder, :default=>[]
19
- dsl_accessor :hash_folder, :default=>{}
20
- end
21
-
22
- class SubFolder < Folder
23
- end
24
-
25
- def test_default_accessor_with_string
26
- assert_equal "id", Item.primary_key
27
- assert_equal "id", User.primary_key
28
- end
29
-
30
- def test_default_accessor_with_proc
31
- assert_equal "items", Item.table_name
32
- assert_equal "users", User.table_name
33
- end
34
-
35
- def test_default_accessor_should_duplicate_empty_array_or_hash
36
- Folder.array_folder << 1
37
- Folder.hash_folder[:name] = "maiha"
38
-
39
- assert_equal([1], Folder.array_folder)
40
- assert_equal({:name=>"maiha"}, Folder.hash_folder)
41
-
42
- assert_equal([], SubFolder.array_folder)
43
- assert_equal({}, SubFolder.hash_folder)
44
- end
45
- end
46
-
47
-
48
- class DslOverwritenDefaultAccessorTest < Test::Unit::TestCase
49
- class CoolActiveRecord
50
- dsl_accessor :primary_key, :default=>"id"
51
- dsl_accessor :table_name, :default=>proc{|klass| klass.name+"s"}
52
- end
53
-
54
- class Item < CoolActiveRecord
55
- primary_key :item_id
56
- table_name :item_table
57
- end
58
-
59
- def test_overwrite_default_accessor
60
- assert_equal :item_id, Item.primary_key
61
- assert_equal :item_table, Item.table_name
62
- end
63
- end
64
-
@@ -1,47 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
-
4
- class DslAccessorTest < Test::Unit::TestCase
5
- class CoolActiveRecord
6
- dsl_accessor :primary_key
7
- dsl_accessor :table_name
8
- end
9
-
10
- class Item < CoolActiveRecord
11
- end
12
-
13
- class LegacyItem < CoolActiveRecord
14
- primary_key :itcd
15
- table_name :item
16
- end
17
-
18
- class OtherClass
19
- end
20
-
21
- def test_dsl_accessor_doesnt_affect_other_classes
22
- assert !OtherClass.respond_to?(:primary_key)
23
- end
24
-
25
- def test_accessor_without_initialization
26
- assert_equal nil, Item.primary_key
27
- assert_equal nil, Item.table_name
28
-
29
- Item.primary_key :itcd
30
- Item.table_name :item
31
-
32
- assert_equal :itcd, Item.primary_key
33
- assert_equal :item, Item.table_name
34
- end
35
-
36
- def test_accessor_with_initialization
37
- assert_equal :itcd, LegacyItem.primary_key
38
- assert_equal :item, LegacyItem.table_name
39
-
40
- LegacyItem.primary_key :item_id
41
- LegacyItem.table_name :item_table
42
-
43
- assert_equal :item_id, LegacyItem.primary_key
44
- assert_equal :item_table, LegacyItem.table_name
45
- end
46
- end
47
-
@@ -1,38 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
- class DefineInstanceMethodWithOptionsTest < Test::Unit::TestCase
4
- class Window
5
- dsl_accessor :width, :default=>640, :instance=>:options
6
- end
7
-
8
- class OptionedWindow
9
- dsl_accessor :width, :default=>640, :instance=>:options
10
- def initialize(options = {})
11
- @options = options
12
- end
13
- end
14
-
15
- def test_class_method
16
- assert_equal Window.width, 640
17
- assert_equal OptionedWindow.width, 640
18
- end
19
-
20
- def test_instance_method
21
- assert_raises(TypeError) { Window.new.width }
22
- assert_equal OptionedWindow.new.width, 640
23
- end
24
-
25
- def test_use_options_variable_rather_than_default_value
26
- window = OptionedWindow.new( :width => 320 )
27
- assert_equal window.width, 320
28
- end
29
-
30
- def test_instance_options_value_doesnt_affect_to_class_method
31
- window = OptionedWindow.new( :width => 320 )
32
- assert_equal OptionedWindow.width, 640
33
- end
34
-
35
- end
36
-
37
-
38
-
@@ -1,43 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
- class DefineInstanceMethodTest < Test::Unit::TestCase
4
- class Item
5
- dsl_accessor :primary_key, "code", :instance=>true
6
- end
7
-
8
- class OtherClass
9
- end
10
-
11
- def test_dsl_accessor_doesnt_affect_other_classes
12
- assert !OtherClass.respond_to?(:primary_key)
13
- end
14
-
15
- def test_dsl_accessor_doesnt_affect_other_instances
16
- assert !OtherClass.new.respond_to?(:primary_key)
17
- end
18
-
19
- def test_class_method
20
- assert Item.respond_to?(:primary_key)
21
- assert_nothing_raised do
22
- Item.primary_key
23
- end
24
- end
25
-
26
- def test_class_method_value
27
- assert_equal "code", Item.primary_key
28
- end
29
-
30
- def test_instance_method
31
- assert Item.new.respond_to?(:primary_key)
32
- assert_nothing_raised do
33
- Item.new.primary_key
34
- end
35
- end
36
-
37
- def test_instance_method_value
38
- assert_equal "code", Item.new.primary_key
39
- end
40
- end
41
-
42
-
43
-
@@ -1,5 +0,0 @@
1
- require 'test/unit'
2
-
3
- def __DIR__; File.dirname(__FILE__); end
4
- require File.dirname(__FILE__) + '/../init'
5
-
@@ -1,21 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
-
3
-
4
- class DslWriterAccessorTest < Test::Unit::TestCase
5
- class Item
6
- dsl_accessor :primary_key, :writer=>proc{|value| value.to_s}
7
- end
8
-
9
- def test_string_writer
10
- assert_equal "", Item.primary_key
11
-
12
- Item.primary_key :id
13
- assert_equal "id", Item.primary_key
14
-
15
- Item.primary_key "id"
16
- assert_equal "id", Item.primary_key
17
- end
18
- end
19
-
20
-
21
-