uber 0.0.1 → 0.0.2
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.
- checksums.yaml +7 -0
- data/CHANGES.md +3 -0
- data/Gemfile +2 -0
- data/README.md +61 -13
- data/lib/uber/inheritable_attr.rb +22 -0
- data/lib/uber/options.rb +70 -0
- data/lib/uber/version.rb +1 -1
- data/test/inheritable_attr_test.rb +54 -0
- data/test/inheritance_test.rb +47 -2
- data/test/options_test.rb +72 -0
- data/test/test_helper.rb +0 -3
- data/test/zeugs.rb +54 -0
- data/uber.gemspec +4 -3
- metadata +37 -18
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 58b218477b8c36e49f66c8bd47175bf605613ef1
|
4
|
+
data.tar.gz: bde8206f4395aa6469f9dfe84eb3651449acd0e3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f08f9af53d76f9800741b6eacd147d031a356b40e309172c1323cf5a80b2f1f70271c1f383f7fbcb2681ac72eaf163b64fc364a36888523688cbbb8147185d22
|
7
|
+
data.tar.gz: 8b6a3e28f375e50b829fe60bf5a2a5ab50daafee28cd5e6334d8488e201b85a12ed915ed0e3c1c84938f5006f5ec55a8b1be07141895bdecc8472c24bfa8348e
|
data/CHANGES.md
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Uber
|
2
2
|
|
3
|
-
|
3
|
+
_Gem-authoring tools like class method inheritance in modules, dynamic options and more._
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -8,22 +8,70 @@ Add this line to your application's Gemfile:
|
|
8
8
|
|
9
9
|
gem 'uber'
|
10
10
|
|
11
|
-
|
11
|
+
Ready?
|
12
12
|
|
13
|
-
|
13
|
+
# Inheritable Class Attributes
|
14
14
|
|
15
|
-
|
15
|
+
This is for you if you want class attributes to be inherited, which is a mandatory mechanism for creating DSLs.
|
16
16
|
|
17
|
-
|
17
|
+
```ruby
|
18
|
+
require 'uber/inheritable_attr'
|
18
19
|
|
19
|
-
|
20
|
+
class Song
|
21
|
+
extend Uber::InheritableAttr
|
20
22
|
|
21
|
-
|
23
|
+
inheritable_attr :properties
|
24
|
+
self.properties = [:title, :track] # initialize it before using it.
|
25
|
+
end
|
26
|
+
```
|
22
27
|
|
23
|
-
|
28
|
+
Note that you have to initialize your attribute which whatever you want - usually a hash or an array.
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
You can now use that attribute on the class level.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
Song.properties #=> [:title, :track]
|
34
|
+
```
|
35
|
+
|
36
|
+
Inheriting from `Song` will result in the `properties` object being `clone`d to the sub-class.
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
class Hit < Song
|
40
|
+
end
|
41
|
+
|
42
|
+
Hit.properties #=> [:title, :track]
|
43
|
+
```
|
44
|
+
|
45
|
+
The cool thing about the inheritance is: you can work on the inherited attribute without any restrictions, as it is a _copy_ of the original.
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
Hit.properties << :number
|
49
|
+
|
50
|
+
Hit.properties #=> [:title, :track, :number]
|
51
|
+
Song.properties #=> [:title, :track]
|
52
|
+
```
|
53
|
+
|
54
|
+
It's similar to ActiveSupport's `class_attribute` but with a simpler implementation resulting in a less dangerous potential. Also, there is no restriction about the way you modify the attribute [as found in `class_attribute`](http://apidock.com/rails/v4.0.2/Class/class_attribute).
|
55
|
+
|
56
|
+
This module is very popular amongst numerous gems like Cells, Representable, Roar and Reform.
|
57
|
+
|
58
|
+
|
59
|
+
# Options
|
60
|
+
|
61
|
+
Implements the pattern of defining configuration options and evaluating them at run-time.
|
62
|
+
|
63
|
+
Usually DSL methods accept a number of options that can either be static values, instance method names as symbols, or blocks (lambdas/Procs).
|
64
|
+
|
65
|
+
Uber::Options.new volume: 9, track: lambda { |s| s.track }
|
66
|
+
|
67
|
+
|
68
|
+
Note that `Options` behaves *and performs* like an ordinary hash when all options are static.
|
69
|
+
|
70
|
+
only use for declarative assets, not at runtime (use a hash)
|
71
|
+
|
72
|
+
|
73
|
+
# License
|
74
|
+
|
75
|
+
Copyright (c) 2014 by Nick Sutterer <apotonick@gmail.com>
|
76
|
+
|
77
|
+
Roar is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Uber
|
2
|
+
module InheritableAttr
|
3
|
+
def inheritable_attr(name)
|
4
|
+
instance_eval %Q{
|
5
|
+
def #{name}=(v)
|
6
|
+
@#{name} = v
|
7
|
+
end
|
8
|
+
|
9
|
+
def #{name}
|
10
|
+
@#{name} ||= InheritableAttribute.inherit_for(self, :#{name})
|
11
|
+
end
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.inherit_for(klass, name)
|
16
|
+
return unless klass.superclass.respond_to?(name) and value = klass.superclass.send(name)
|
17
|
+
value.clone # only do this once.
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
InheritableAttribute = InheritableAttr
|
22
|
+
end
|
data/lib/uber/options.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
module Uber
|
2
|
+
class Options < Hash
|
3
|
+
def initialize(options)
|
4
|
+
@static = options
|
5
|
+
|
6
|
+
options.each do |k,v|
|
7
|
+
self[k] = option = Value.new(v)
|
8
|
+
@static = nil if option.dynamic?
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# 1.100000 0.060000 1.160000 ( 1.159762) original
|
13
|
+
# 0.120000 0.010000 0.130000 ( 0.135803) return self
|
14
|
+
# 0.930000 0.060000 0.990000 ( 0.997095) without v.evaluate
|
15
|
+
|
16
|
+
# Evaluates every element and returns a hash. Accepts context and arbitrary arguments.
|
17
|
+
def evaluate(context, *args)
|
18
|
+
return @static unless dynamic?
|
19
|
+
|
20
|
+
evaluate_for(context, *args)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Evaluates a single value.
|
24
|
+
def eval(key, *args)
|
25
|
+
self[key].evaluate(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def evaluate_for(context, *args)
|
30
|
+
{}.tap do |evaluated|
|
31
|
+
each do |k,v|
|
32
|
+
evaluated[k] = v.evaluate(context, *args)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def dynamic?
|
38
|
+
not @static
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
class Value # TODO: rename to Value.
|
43
|
+
def initialize(value, options={})
|
44
|
+
@value = value || true
|
45
|
+
@options = options
|
46
|
+
end
|
47
|
+
|
48
|
+
def evaluate(context, *args)
|
49
|
+
return true if @value.is_a?(TrueClass)
|
50
|
+
|
51
|
+
evaluate_for(context, *args)
|
52
|
+
end
|
53
|
+
|
54
|
+
def dynamic?
|
55
|
+
@options[:instance_method] || @value.kind_of?(Proc)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def evaluate_for(context, *args)
|
60
|
+
return proc!(context, *args) unless @value.kind_of?(Proc)
|
61
|
+
@value.call(context, *args) # TODO: change to context.instance_exec and deprecate first argument.
|
62
|
+
end
|
63
|
+
|
64
|
+
def proc!(context, *args)
|
65
|
+
return context.send(@value, *args) if @options[:instance_method]
|
66
|
+
@value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/uber/version.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require "uber/inheritable_attr"
|
3
|
+
|
4
|
+
class InheritableAttrTest < MiniTest::Spec
|
5
|
+
describe "::inheritable_attr" do
|
6
|
+
subject {
|
7
|
+
Class.new(Object) do
|
8
|
+
extend Uber::InheritableAttribute
|
9
|
+
inheritable_attr :drinks
|
10
|
+
end
|
11
|
+
}
|
12
|
+
|
13
|
+
it "provides a reader with empty inherited attributes, already" do
|
14
|
+
assert_equal nil, subject.drinks
|
15
|
+
end
|
16
|
+
|
17
|
+
it "provides a reader with empty inherited attributes in a derived class" do
|
18
|
+
assert_equal nil, Class.new(subject).drinks
|
19
|
+
#subject.drinks = true
|
20
|
+
#Class.new(subject).drinks # TODO: crashes.
|
21
|
+
end
|
22
|
+
|
23
|
+
it "provides an attribute copy in subclasses" do
|
24
|
+
subject.drinks = []
|
25
|
+
assert subject.drinks.object_id != Class.new(subject).drinks.object_id
|
26
|
+
end
|
27
|
+
|
28
|
+
it "provides a writer" do
|
29
|
+
subject.drinks = [:cabernet]
|
30
|
+
assert_equal [:cabernet], subject.drinks
|
31
|
+
end
|
32
|
+
|
33
|
+
it "inherits attributes" do
|
34
|
+
subject.drinks = [:cabernet]
|
35
|
+
|
36
|
+
subklass_a = Class.new(subject)
|
37
|
+
subklass_a.drinks << :becks
|
38
|
+
|
39
|
+
subklass_b = Class.new(subject)
|
40
|
+
|
41
|
+
assert_equal [:cabernet], subject.drinks
|
42
|
+
assert_equal [:cabernet, :becks], subklass_a.drinks
|
43
|
+
assert_equal [:cabernet], subklass_b.drinks
|
44
|
+
end
|
45
|
+
|
46
|
+
it "does not inherit attributes if we set explicitely" do
|
47
|
+
subject.drinks = [:cabernet]
|
48
|
+
subklass = Class.new(subject)
|
49
|
+
|
50
|
+
subklass.drinks = [:merlot] # we only want merlot explicitely.
|
51
|
+
assert_equal [:merlot], subklass.drinks # no :cabernet, here
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/test/inheritance_test.rb
CHANGED
@@ -1,7 +1,52 @@
|
|
1
1
|
require 'test_helper'
|
2
|
+
require 'uber/inheritable_included'
|
3
|
+
|
4
|
+
module InheritIncludedTo
|
5
|
+
def self.call(includer, proc)
|
6
|
+
proc.call(includer) # das will ich eigentlich machen
|
7
|
+
|
8
|
+
includer.class_eval do
|
9
|
+
@block = proc
|
10
|
+
|
11
|
+
def self.included(base) #
|
12
|
+
InheritIncludedTo.call(base, instance_variable_get(:@block))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
2
17
|
|
3
18
|
class InheritanceTest < MiniTest::Spec
|
4
|
-
|
5
|
-
|
19
|
+
module Feature
|
20
|
+
#extend Uber::InheritedIncluded
|
21
|
+
|
22
|
+
CODE_BLOCK = lambda { |base| base.class_eval { extend ClassMethods } } # i want that to be executed at every include
|
23
|
+
|
24
|
+
|
25
|
+
def self.included(includer) #
|
26
|
+
# CODE_BLOCK.call(base)
|
27
|
+
InheritIncludedTo.call(includer, CODE_BLOCK)
|
28
|
+
end
|
29
|
+
|
30
|
+
module ClassMethods
|
31
|
+
def feature; end
|
32
|
+
end
|
6
33
|
end
|
34
|
+
|
35
|
+
module Extension
|
36
|
+
include Feature
|
37
|
+
|
38
|
+
# TODO: test overriding ::included
|
39
|
+
end
|
40
|
+
|
41
|
+
module Client
|
42
|
+
include Extension
|
43
|
+
end
|
44
|
+
|
45
|
+
module ExtendedClient
|
46
|
+
include Client
|
47
|
+
end
|
48
|
+
|
49
|
+
it { Extension.must_respond_to :feature }
|
50
|
+
it { Client.must_respond_to :feature }
|
51
|
+
it { ExtendedClient.must_respond_to :feature }
|
7
52
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'uber/options'
|
3
|
+
|
4
|
+
class UberOptionTest < MiniTest::Spec
|
5
|
+
Value = Uber::Options::Value
|
6
|
+
|
7
|
+
describe "#dynamic?" do
|
8
|
+
it { Value.new(1).dynamic?.must_equal false }
|
9
|
+
it { Value.new(true).dynamic?.must_equal false }
|
10
|
+
it { Value.new(:loud).dynamic?.must_equal false }
|
11
|
+
|
12
|
+
it { Value.new(lambda {}).dynamic?.must_equal true }
|
13
|
+
it { Value.new(Proc.new{}).dynamic?.must_equal true }
|
14
|
+
it { Value.new(:method, :instance_method => true).dynamic?.must_equal true }
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
# it "speed" do
|
20
|
+
# require "benchmark"
|
21
|
+
|
22
|
+
# options = 1000000.times.collect do
|
23
|
+
# Uber::Options.new(expires: false)
|
24
|
+
# end
|
25
|
+
|
26
|
+
# time = Benchmark.measure do
|
27
|
+
# options.each do |opt|
|
28
|
+
# opt.evaluate(nil)
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
|
32
|
+
# puts "good results"
|
33
|
+
# puts time
|
34
|
+
# end
|
35
|
+
end
|
36
|
+
|
37
|
+
class UberOptionsTest < MiniTest::Spec
|
38
|
+
Options = Uber::Options
|
39
|
+
|
40
|
+
let (:dynamic) { Options.new(:volume =>1, :style => "Punkrock", :track => Proc.new { |i| i.to_s }) }
|
41
|
+
|
42
|
+
describe "#dynamic?" do
|
43
|
+
it { Options.new(:volume =>1, :style => "Punkrock").send(:dynamic?).must_equal false }
|
44
|
+
it { Options.new(:style => Proc.new{}, :volume =>1).send(:dynamic?).must_equal true }
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#evaluate" do
|
48
|
+
|
49
|
+
it { dynamic.evaluate(999).must_equal({:volume =>1, :style => "Punkrock", :track => "999"}) }
|
50
|
+
|
51
|
+
describe "static" do
|
52
|
+
let (:static) { Options.new(:volume =>1, :style => "Punkrock") }
|
53
|
+
|
54
|
+
it { static.evaluate(nil).must_equal({:volume =>1, :style => "Punkrock"}) }
|
55
|
+
|
56
|
+
it "doesn't evaluate internally" do
|
57
|
+
static.instance_eval do
|
58
|
+
def evaluate_for(*)
|
59
|
+
raise "i shouldn't be called!"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
static.evaluate(nil).must_equal({:volume =>1, :style => "Punkrock"})
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#eval" do
|
68
|
+
it { dynamic.eval(:volume, 999).must_equal 1 }
|
69
|
+
it { dynamic.eval(:style, 999).must_equal "Punkrock" }
|
70
|
+
it { dynamic.eval(:track, 999).must_equal "999" }
|
71
|
+
end
|
72
|
+
end
|
data/test/test_helper.rb
CHANGED
data/test/zeugs.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Feature
|
2
|
+
module ClassMethods
|
3
|
+
def feature
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
# in uber, this would look somehow like
|
8
|
+
# module Feature
|
9
|
+
# module ClassMethods ... end
|
10
|
+
|
11
|
+
# extend Uber::InheritableIncluded
|
12
|
+
# inheritable_included do |includer|
|
13
|
+
# includer.extend ClassMethods
|
14
|
+
# end
|
15
|
+
# end
|
16
|
+
|
17
|
+
InheritedIncludedCodeBlock = lambda do |includer|
|
18
|
+
includer.extend ClassMethods
|
19
|
+
end
|
20
|
+
|
21
|
+
module RecursiveIncluded
|
22
|
+
def included(includer)
|
23
|
+
#super # TODO: test me.
|
24
|
+
puts "RecursiveIncluded in #{includer}"
|
25
|
+
|
26
|
+
includer.module_eval do
|
27
|
+
InheritedIncludedCodeBlock.call(includer)
|
28
|
+
extend RecursiveIncluded
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
extend RecursiveIncluded
|
33
|
+
end
|
34
|
+
|
35
|
+
module Client
|
36
|
+
include Feature
|
37
|
+
end
|
38
|
+
|
39
|
+
module Extension
|
40
|
+
include Client
|
41
|
+
end
|
42
|
+
|
43
|
+
module Plugin
|
44
|
+
include Extension
|
45
|
+
end
|
46
|
+
|
47
|
+
module Framework
|
48
|
+
include Plugin
|
49
|
+
end
|
50
|
+
|
51
|
+
Client.feature
|
52
|
+
Extension.feature
|
53
|
+
Plugin.feature
|
54
|
+
Framework.feature
|
data/uber.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |gem|
|
|
5
5
|
gem.authors = ["Nick Sutterer"]
|
6
6
|
gem.email = ["apotonick@gmail.com"]
|
7
7
|
gem.description = %q{A gem-authoring framework.}
|
8
|
-
gem.summary = %q{
|
8
|
+
gem.summary = %q{Gem-authoring tools like class method inheritance in modules, dynamic options and more.}
|
9
9
|
gem.homepage = ""
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
@@ -14,6 +14,7 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.name = "uber"
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Uber::VERSION
|
17
|
-
|
18
|
-
gem.add_development_dependency "
|
17
|
+
|
18
|
+
gem.add_development_dependency "rake", ">= 0.10.1"
|
19
|
+
gem.add_development_dependency "minitest", ">= 5.0.0"
|
19
20
|
end
|
metadata
CHANGED
@@ -1,32 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Nick Sutterer
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-03-06 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.10.1
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.10.1
|
14
27
|
- !ruby/object:Gem::Dependency
|
15
28
|
name: minitest
|
16
29
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
30
|
requirements:
|
19
|
-
- -
|
31
|
+
- - ">="
|
20
32
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
33
|
+
version: 5.0.0
|
22
34
|
type: :development
|
23
35
|
prerelease: false
|
24
36
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
37
|
requirements:
|
27
|
-
- -
|
38
|
+
- - ">="
|
28
39
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
40
|
+
version: 5.0.0
|
30
41
|
description: A gem-authoring framework.
|
31
42
|
email:
|
32
43
|
- apotonick@gmail.com
|
@@ -34,41 +45,49 @@ executables: []
|
|
34
45
|
extensions: []
|
35
46
|
extra_rdoc_files: []
|
36
47
|
files:
|
37
|
-
- .gitignore
|
48
|
+
- ".gitignore"
|
49
|
+
- CHANGES.md
|
38
50
|
- Gemfile
|
39
51
|
- LICENSE
|
40
52
|
- README.md
|
41
53
|
- Rakefile
|
42
54
|
- lib/uber.rb
|
55
|
+
- lib/uber/inheritable_attr.rb
|
56
|
+
- lib/uber/options.rb
|
43
57
|
- lib/uber/version.rb
|
58
|
+
- test/inheritable_attr_test.rb
|
44
59
|
- test/inheritance_test.rb
|
60
|
+
- test/options_test.rb
|
45
61
|
- test/test_helper.rb
|
62
|
+
- test/zeugs.rb
|
46
63
|
- uber.gemspec
|
47
64
|
homepage: ''
|
48
65
|
licenses: []
|
66
|
+
metadata: {}
|
49
67
|
post_install_message:
|
50
68
|
rdoc_options: []
|
51
69
|
require_paths:
|
52
70
|
- lib
|
53
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
-
none: false
|
55
72
|
requirements:
|
56
|
-
- -
|
73
|
+
- - ">="
|
57
74
|
- !ruby/object:Gem::Version
|
58
75
|
version: '0'
|
59
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
-
none: false
|
61
77
|
requirements:
|
62
|
-
- -
|
78
|
+
- - ">="
|
63
79
|
- !ruby/object:Gem::Version
|
64
80
|
version: '0'
|
65
81
|
requirements: []
|
66
82
|
rubyforge_project:
|
67
|
-
rubygems_version:
|
83
|
+
rubygems_version: 2.2.1
|
68
84
|
signing_key:
|
69
|
-
specification_version:
|
70
|
-
summary:
|
71
|
-
more.
|
85
|
+
specification_version: 4
|
86
|
+
summary: Gem-authoring tools like class method inheritance in modules, dynamic options
|
87
|
+
and more.
|
72
88
|
test_files:
|
89
|
+
- test/inheritable_attr_test.rb
|
73
90
|
- test/inheritance_test.rb
|
91
|
+
- test/options_test.rb
|
74
92
|
- test/test_helper.rb
|
93
|
+
- test/zeugs.rb
|