dsl_accessor 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-