hanswurst 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ gem 'couch_potato'
9
+ group :development do
10
+ gem "yard", "~> 0.6.0"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "jeweler", "~> 1.5.2"
13
+ gem "rcov", ">= 0"
14
+ gem 'mocha'
15
+ gem "shoulda", ">= 0"
16
+
17
+ gem 'linecache19'
18
+ gem 'ruby-debug19'
19
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Marc Rene Arns
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ hanswurst: Be a couch potato and play different roles
2
+ =====================
3
+
4
+ Hanswurst is a library that uses couch potato to create arbitrary
5
+ objects that may have different roles. The roles determine the
6
+ properties and they can be mixed and matched at will.
7
+
8
+ Hanswurst is only tested with ruby 1.9.2 and above.
9
+
10
+ Example:
11
+ --------
12
+
13
+ first you have to build your roles as normal couch potato classes
14
+
15
+ class Person
16
+ include CouchPotato::Persistence
17
+
18
+ property :last_name
19
+ property :first_name
20
+
21
+ validates_presence_of :last_name
22
+ end
23
+
24
+ class Product
25
+ include CouchPotato::Persistence
26
+
27
+ property :price
28
+ property :in_stock
29
+ end
30
+
31
+ then you may use them as you like
32
+
33
+ hw = Hanswurst.new
34
+ hw.add_role Person
35
+ hw.add_role Product
36
+
37
+ hw.person___first_name = 'Diederich'
38
+ hw.person___last_name = 'Hessling' # an RoleNotValid error is raised if person___last_name is missing
39
+
40
+ # this is also possible
41
+ hw.product = Product.new :price => 20, :in_stock => 1
42
+
43
+ id = CouchPotato.database.save_document hanswurst
44
+
45
+ later...
46
+
47
+ hw = CouchPotato.database.load_document id
48
+
49
+ hw.person___first_name # => 'Diederich'
50
+ hw.product___price # => 20
51
+
52
+
53
+ All views are attached to the hanswurst design document
54
+ You may create general views:
55
+
56
+ Hanswurst.view :all, :key => :created_at
57
+
58
+ or views specific for a role
59
+
60
+ Hanswurst.view_for :person, :all, :key => :created_at
61
+
62
+ # execute them this way
63
+ CouchPotato.database.view Hanswurst.person_all
64
+
65
+ the same works with lists.
66
+
67
+ You may subclass Hanswurst to do further separation and mix the
68
+ native properties of Hanswursts / its subclasses with the roles properties.
69
+
70
+
71
+ Contributing to hanswurst
72
+ -------------------------
73
+
74
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
75
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
76
+ * Fork the project
77
+ * Start a feature/bugfix branch
78
+ * Commit and push until you are happy with your contribution
79
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
80
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
81
+
82
+ Copyright
83
+ ---------
84
+
85
+ Copyright (c) 2012 Marc Rene Arns. See LICENSE.txt for
86
+ further details.
87
+
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "hanswurst"
16
+ gem.homepage = "http://github.com/metakeule/hanswurst"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{Be a couch potato and play different roles}
19
+ gem.description = %Q{flexible enhancement of couch potato}
20
+ gem.email = "Base64.decode64('bGludXhAbWFyY3JlbmVhcm5zLmRl\n')"
21
+ gem.authors = ["Marc Rene Arns"]
22
+ gem.add_runtime_dependency 'couch_potato'
23
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
24
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
25
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
26
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
27
+ end
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ require 'rcov/rcovtask'
38
+ Rcov::RcovTask.new do |test|
39
+ test.libs << 'test'
40
+ test.pattern = 'test/**/test_*.rb'
41
+ test.verbose = true
42
+ end
43
+
44
+ task :default => :test
45
+
46
+ require 'yard'
47
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/hanswurst.rb ADDED
@@ -0,0 +1,176 @@
1
+ require 'couch_potato'
2
+
3
+ # Each Hanswurst may have a different combination of roles. It's a very flexible way to be a couch potato.
4
+ class Hanswurst
5
+
6
+ # error raised when a role is not valid
7
+ class RoleNotValid < Exception
8
+ def initialize(role, value)
9
+ @role = role
10
+ @value = value
11
+ end
12
+
13
+ def message()
14
+ errors = @value.errors.messages.collect do |field, err|
15
+ "#{field} #{err.join('/')}"
16
+ end.join(" # ")
17
+ "role not valid #{@role}: #{errors}"
18
+ end
19
+ end
20
+
21
+ # class methods for Hanswurst
22
+ module ClassMethods
23
+
24
+ # get class obj from a classname
25
+ def getClass(classname)
26
+ classname.split('::').inject Kernel do |c,name| c = c.const_get name; end
27
+ end
28
+
29
+ # creates a view to show only documents of the role +role_alias+
30
+ def role_view(role_alias, viewname, options)
31
+ # I keep this commented out to inform the reader that we don't want this in order to easily reuse general lists
32
+ #options[:list] &&= :"#{role_alias}_#{options[:list]}"
33
+ options[:conditions] &&= " && ( #{options[:conditions]} )"
34
+ options[:conditions] = "(doc.roles.#{role_alias} !== undefined)#{options[:conditions]}"
35
+ self.view :"#{role_alias}_#{viewname}", options
36
+ end
37
+
38
+ alias :view_for :role_view
39
+
40
+ # creates a list for documents of the role +role_alias+
41
+ def role_list(role_alias, listname, val)
42
+ self.list :"#{role_alias}_#{listname}", val.to_s
43
+ end
44
+
45
+ alias :list_for :role_list
46
+
47
+ # shortcuts view_for_[role], list_for_[role]
48
+ def method_missing(meth, *args, &code)
49
+ case meth
50
+ when /^view_for_(.+)$/
51
+ send(:view_for, $1, *args)
52
+ when /^list_for_(.+)$/
53
+ send(:list_for, $1, *args)
54
+ else
55
+ super
56
+ end
57
+ end
58
+ end
59
+
60
+ extend ClassMethods
61
+
62
+ include CouchPotato::Persistence
63
+
64
+ module MethodMissing
65
+ # dispatches self.role___prop calls and self.role= setters
66
+ def method_missing(meth, *args, &code)
67
+ value = args.first
68
+ case meth
69
+ when /^([^=]+)___([^=]+)(\=)?$/ # obj.role__prop # => we get / set a property
70
+ role, property, setter = $1, $2, $3
71
+ return setter ? set_property(role, property, value) : read(role, property)
72
+ when /^([^=]+)\=$/ # obj.role = ... # => we set a role
73
+ return set_role(role, value) if role_exists?(role=$1)
74
+ end
75
+ super
76
+ end
77
+ end
78
+
79
+ property :roles
80
+ property :data
81
+
82
+ # check if every role is valid before saving
83
+ before_save do
84
+ self.data.each do |role,val|
85
+ unless val.valid?
86
+ raise RoleNotValid.new(role, val)
87
+ end
88
+ end
89
+ end
90
+
91
+ include MethodMissing
92
+
93
+ # add a role
94
+ def add_role(role, klass)
95
+ add_roles(role => klass)
96
+ end
97
+
98
+ # add more roles at once
99
+ def add_roles(hsh)
100
+ self.data ||= {}
101
+ r = self.roles || {}
102
+ hsh.each do |role,klass|
103
+ raise "class expected: #{klass.inspect}" unless klass.is_a? Class
104
+ r.update(role.to_s => klass.name)
105
+ end
106
+ self.roles = r
107
+ end
108
+
109
+ # does he have a role
110
+ def role_exists?(role)
111
+ self.roles and self.roles[role.to_s]
112
+ end
113
+
114
+ # does he have data for the role
115
+ def data_exists?(role)
116
+ self.data and self.data[role.to_s]
117
+ end
118
+
119
+ # set a property of a role
120
+ def set_property(role, property, value)
121
+ return unless role_exists? role
122
+ create(role) unless data_exists? role
123
+ update role, property, value
124
+ end
125
+
126
+ # set a role
127
+ def set_role(role, value)
128
+ value ? set(role, value) : delete_role(role)
129
+ end
130
+
131
+ # delete a role
132
+ def delete_role(role)
133
+ delete role # delete the data
134
+ self.roles.delete role.to_s # and the role itself
135
+ end
136
+
137
+ # set instance for a role
138
+ def set(role, val)
139
+ self.data ||= {}
140
+ self.data.update role.to_s => val
141
+ end
142
+
143
+ # create a new instance of a role
144
+ def create(role)
145
+ raise "unknown role #{role.inspect}" unless role_exists? role.to_s
146
+ self.data ||= {}
147
+ self.data[role.to_s] = self.class.getClass(self.roles[role.to_s]).new
148
+ end
149
+
150
+ # delete a role
151
+ def delete(role)
152
+ self.data ||= {}
153
+ hsh = self.data
154
+ hsh.delete(role.to_s)
155
+ self.data = {} # we have to do this, otherwise it won't save?!
156
+ self.data = hsh
157
+ end
158
+
159
+ # read a property of a role
160
+ def read(role, property)
161
+ return self.data[role.to_s].send(property.to_sym) if data_exists?(role.to_s)
162
+ nil
163
+ end
164
+
165
+ # update a property of a role
166
+ # we have to use this method in order to make sure that everything is saved
167
+ def update(role, property, value)
168
+ if data_exists? role
169
+ self.data[role.to_s].send(:"#{property}=", value)
170
+ hsh = self.data.merge(role.to_s => self.data[role.to_s])
171
+ self.data = {} # we have to do this, otherwise it won't save?!
172
+ self.data = hsh
173
+ end
174
+ end
175
+ end
176
+
data/test/helper.rb ADDED
@@ -0,0 +1,19 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+ require 'mocha'
13
+
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ require 'hanswurst'
17
+
18
+
19
+
@@ -0,0 +1,165 @@
1
+ require 'helper'
2
+ require 'hanswurst'
3
+
4
+ CouchPotato::Config.database_name = ENV['COUCH_POTATO_TEST_DB']
5
+
6
+
7
+ class Pers
8
+ include CouchPotato::Persistence
9
+ property :firstname
10
+ property :lastname
11
+ end
12
+
13
+ class Prod
14
+ include CouchPotato::Persistence
15
+
16
+ property :article_number
17
+ property :name
18
+
19
+ validates_presence_of :name
20
+ end
21
+
22
+ module Thing
23
+ class A
24
+ include CouchPotato::Persistence
25
+ property :a
26
+ end
27
+ end
28
+
29
+ Hanswurst.list_for :pers, :complete_name, %q|
30
+ function(head, req) {
31
+ var row;
32
+ var rows = [];
33
+ send('{"rows": ');
34
+ while(row = getRow()) {
35
+ row.doc.data.q = req.query;
36
+ if(req.query["startkey_docid"] && row.doc.data.pers.firstname == req.query["startkey_docid"]){
37
+ row.doc.data.pers.complete_name = row.doc.data.pers.firstname + ' ' + row.doc.data.pers.lastname;
38
+ rows[rows.length] = row;
39
+ }
40
+ };
41
+ send(JSON.stringify(rows));
42
+ send('}');
43
+ }
44
+ |
45
+
46
+ Hanswurst.view_for :pers, :all_names, :list => :pers_complete_name #, :raw => true
47
+
48
+
49
+
50
+ class TestCouch < Test::Unit::TestCase
51
+
52
+ def recreate_db
53
+ CouchPotato.couchrest_database.recreate!
54
+ end
55
+
56
+ def save(doc)
57
+ CouchPotato.database.save_document doc
58
+ end
59
+
60
+ def save!(doc)
61
+ CouchPotato.database.save_document! doc
62
+ end
63
+
64
+ def load(id)
65
+ CouchPotato.database.load_document id
66
+ end
67
+
68
+ def view(v)
69
+ CouchPotato.database.view v
70
+ end
71
+
72
+ def update(id)
73
+ doc = load id
74
+ yield doc
75
+ save doc
76
+ end
77
+
78
+ context "in a real couch" do
79
+ setup do
80
+ recreate_db()
81
+ end
82
+
83
+ should "save stuff" do
84
+ o = Hanswurst.new
85
+ o.add_role 'person', Pers
86
+ o.add_role 'product', Prod
87
+ o.product = Prod.new( :article_number => 'xyz', :name => 'prod1' )
88
+ o.person = Pers.new( :firstname => 'Donald', :lastname => 'Duck' )
89
+ save o
90
+ o = load(o._id)
91
+ roles = {'person' => 'Pers', 'product' => 'Prod'}
92
+ assert_equal roles, o.roles
93
+ assert_equal 'prod1', o.data["product"].name
94
+ assert_equal 'Donald', o.data["person"].firstname
95
+ assert_equal 'Donald', o.person___firstname
96
+ end
97
+
98
+ should "save roles" do
99
+ o = Hanswurst.new
100
+ o.add_role 'person', Pers
101
+ o.add_role 'product', Prod
102
+ o.product___article_number = "abc"
103
+ o.product___name = "prod1"
104
+ o.person___firstname = "Bugs"
105
+ o.person___lastname = "Bunny"
106
+ save o
107
+ o = load(o._id)
108
+ roles = {'person' => 'Pers', 'product' => 'Prod'}
109
+ assert_equal roles, o.roles
110
+ assert_equal 'Bugs', o.person___firstname
111
+ assert_equal 'Bunny', o.person___lastname
112
+ assert_equal 'abc', o.product___article_number
113
+
114
+ o.product___article_number = "cde"
115
+ save o
116
+ o = load(o._id)
117
+ assert_equal 'prod1', o.product___name
118
+ assert_equal 'Bugs', o.person___firstname
119
+ assert_equal 'cde', o.product___article_number
120
+
121
+ o.product = nil
122
+ save o
123
+ o = load(o._id)
124
+ assert_equal nil, o.product___name
125
+ assert !o.roles.has_key?("product")
126
+ assert_equal 'Bugs', o.person___firstname
127
+ assert_equal nil, o.product___article_number
128
+ end
129
+
130
+ should "save for moduled classed" do
131
+ o = Hanswurst.new
132
+ o.add_role 'thing', Thing::A
133
+ o.thing___a = "hiho"
134
+ save o
135
+ o = load(o._id)
136
+ roles = {'thing' => 'Thing::A'}
137
+ assert_equal roles, o.roles
138
+ assert_equal 'hiho', o.thing___a
139
+ end
140
+
141
+
142
+ should "not save when validation fails" do
143
+ o = Hanswurst.new
144
+ o.add_role 'product', Prod
145
+ o.product = Prod.new( :article_number => 'xyz')
146
+ assert_raises Hanswurst::RoleNotValid do
147
+ save o
148
+ end
149
+ end
150
+
151
+ should "make a view with list" do
152
+ o = Hanswurst.new
153
+ o.add_role 'pers', Pers
154
+ o.pers = Pers.new :firstname => "Donald", :lastname => "Duck"
155
+ save o
156
+ a = Hanswurst.new
157
+ a.add_role 'pers', Pers
158
+ a.pers = Pers.new :firstname => "Mickey", :lastname => "Mouse"
159
+ save a
160
+ assert_equal "Donald Duck", view(Hanswurst.pers_all_names(:startkey_docid => "Donald")).first.data["pers"].complete_name
161
+ assert_equal "Donald", view(Hanswurst.pers_all_names(:startkey_docid => "Donald")).first.data["pers"].firstname
162
+ end
163
+ end
164
+
165
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hanswurst
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Marc Rene Arns
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-05 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: couch_potato
16
+ requirement: &27122780 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *27122780
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ requirement: &27122300 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.6.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *27122300
36
+ - !ruby/object:Gem::Dependency
37
+ name: bundler
38
+ requirement: &27097640 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.0.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *27097640
47
+ - !ruby/object:Gem::Dependency
48
+ name: jeweler
49
+ requirement: &27097060 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.5.2
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *27097060
58
+ - !ruby/object:Gem::Dependency
59
+ name: rcov
60
+ requirement: &27096480 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *27096480
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: &27095960 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *27095960
80
+ - !ruby/object:Gem::Dependency
81
+ name: shoulda
82
+ requirement: &27095360 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *27095360
91
+ - !ruby/object:Gem::Dependency
92
+ name: linecache19
93
+ requirement: &27094800 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *27094800
102
+ - !ruby/object:Gem::Dependency
103
+ name: ruby-debug19
104
+ requirement: &27094320 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *27094320
113
+ - !ruby/object:Gem::Dependency
114
+ name: couch_potato
115
+ requirement: &27093760 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :runtime
122
+ prerelease: false
123
+ version_requirements: *27093760
124
+ description: flexible enhancement of couch potato
125
+ email: ! 'Base64.decode64(''bGludXhAbWFyY3JlbmVhcm5zLmRl
126
+
127
+ '')'
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files:
131
+ - LICENSE.txt
132
+ - README.md
133
+ files:
134
+ - .document
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - VERSION
140
+ - lib/hanswurst.rb
141
+ - test/helper.rb
142
+ - test/test_hanswurst.rb
143
+ homepage: http://github.com/metakeule/hanswurst
144
+ licenses:
145
+ - MIT
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ segments:
157
+ - 0
158
+ hash: -565794256545933132
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ requirements: []
166
+ rubyforge_project:
167
+ rubygems_version: 1.8.6
168
+ signing_key:
169
+ specification_version: 3
170
+ summary: Be a couch potato and play different roles
171
+ test_files:
172
+ - test/helper.rb
173
+ - test/test_hanswurst.rb