categories 1.0.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.
@@ -0,0 +1,3 @@
1
+ === 1.0.0 / 2008-02-09
2
+
3
+ * Initial Release
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Simon Menke
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 NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ History.txt
2
+ LICENSE.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/categories.rb
7
+ spec/categories_class_spec.rb
8
+ spec/categories_class_with_module_spec.rb
9
+ spec/categories_instance_spec.rb
10
+ spec/categories_instance_with_module_spec.rb
11
+ spec/spec.opts
@@ -0,0 +1,65 @@
1
+ = categories
2
+
3
+ * http://5xm.org (home)
4
+
5
+ == DESCRIPTION:
6
+
7
+ Easily create class and module extentions.
8
+
9
+ == SYNOPSIS:
10
+
11
+ category :Hello do
12
+ before_include do
13
+ # this gets executed before the include
14
+ ...
15
+ end
16
+ after_include do
17
+ # this gets executed after the include
18
+ ...
19
+ end
20
+ for_class do
21
+ # class methods go here
22
+ ...
23
+ end
24
+ for_instance do
25
+ # instance methods go here
26
+ ...
27
+ end
28
+ end
29
+
30
+ class Person
31
+ include Hello
32
+ end
33
+
34
+ == REQUIREMENTS:
35
+
36
+ * activesupport (OPTIONAL)
37
+
38
+ == INSTALL:
39
+
40
+ * sudo gem install categories
41
+
42
+ == LICENSE:
43
+
44
+ (The MIT License)
45
+
46
+ Copyright (c) 2008 Simon Menke
47
+
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of this software and associated documentation files (the
50
+ 'Software'), to deal in the Software without restriction, including
51
+ without limitation the rights to use, copy, modify, merge, publish,
52
+ distribute, sublicense, and/or sell copies of the Software, and to
53
+ permit persons to whom the Software is furnished to do so, subject to
54
+ the following conditions:
55
+
56
+ The above copyright notice and this permission notice shall be
57
+ included in all copies or substantial portions of the Software.
58
+
59
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
60
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
62
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
63
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
64
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
65
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,97 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require 'spec'
6
+ require 'spec/rake/spectask'
7
+ require 'spec/rake/verify_rcov'
8
+ require './lib/categories.rb'
9
+
10
+ module Spec
11
+ class << self; def run; false; end; end
12
+ end
13
+
14
+ Spec::Rake::SpecTask.new :spec do |t|
15
+ t.spec_files = FileList['spec/*_spec.rb']
16
+ t.spec_opts << "-O spec/spec.opts"
17
+ end
18
+
19
+ task :default => :spec
20
+
21
+ Hoe.new('categories', Class::Category::VERSION) do |p|
22
+ p.rubyforge_name = 'categories'
23
+ p.author = 'Simon Menke'
24
+ p.email = 'simon@5xm.org'
25
+ p.summary = 'Easily create class and module extentions.'
26
+ # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
27
+ p.url = "http://5xm.org"
28
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
29
+ end
30
+
31
+ desc "Run all specs with rcov and store coverage report in doc/output/coverage"
32
+ Spec::Rake::SpecTask.new(:spec_rcov) do |t|
33
+ t.spec_files = FileList['spec/*.rb']
34
+ t.spec_opts << "-O spec/spec.opts"
35
+ t.rcov = true
36
+ t.rcov_dir = 'coverage'
37
+ t.rcov_opts = ['--exclude', 'pkg,spec,\.autotest,\/Library']
38
+ end
39
+
40
+ desc "Verify that coverage is 100%"
41
+ RCov::VerifyTask.new(:verify_rcov => :spec_rcov) do |t|
42
+ t.index_html = "coverage/index.html"
43
+ t.threshold = 100
44
+ end
45
+
46
+ desc "Heckle each module and class in turn"
47
+ task :heckle => :verify_rcov do
48
+ root_module = "Class::Category"
49
+ spec_files = FileList['spec/*_spec.rb']
50
+
51
+ current_module, current_method = nil, nil
52
+ heckle_caught_modules = Hash.new { |hash, key| hash[key] = [] }
53
+ unhandled_mutations = 0
54
+
55
+ IO.popen("spec -O spec/spec.opts --heckle #{root_module} #{spec_files}") do |pipe|
56
+ while line = pipe.gets
57
+ line = line.chomp
58
+
59
+ if line =~ /^\*\*\* ((?:\w+(?:::)?)+)#(\w+)/
60
+ current_module, current_method = $1, $2
61
+ elsif line == "The following mutations didn't cause test failures:"
62
+ heckle_caught_modules[current_module] << current_method
63
+ elsif line == "+++ mutation"
64
+ unhandled_mutations += 1
65
+ end
66
+
67
+ puts line
68
+ end
69
+ end
70
+
71
+ if unhandled_mutations > 0
72
+ error_message_lines = ["*************\n"]
73
+
74
+ error_message_lines <<
75
+ "Heckle found #{unhandled_mutations} " +
76
+ "mutation#{"s" unless unhandled_mutations == 1} " +
77
+ "that didn't cause spec violations\n"
78
+
79
+ heckle_caught_modules.each do |mod, methods|
80
+ error_message_lines <<
81
+ "#{mod} contains the following poorly-specified methods:"
82
+ methods.each do |m|
83
+ error_message_lines << " - #{m}"
84
+ end
85
+ error_message_lines << ""
86
+ end
87
+
88
+ error_message_lines <<
89
+ "Get your act together and come back " +
90
+ "when your specs are doing their job!"
91
+
92
+ puts "*************"
93
+ raise error_message_lines.join("\n")
94
+ else
95
+ puts "Well done! Your code withstood a heckling."
96
+ end
97
+ end
@@ -0,0 +1,84 @@
1
+
2
+ class Class # :nodoc:
3
+ class Category
4
+ VERSION = '1.0.0'
5
+
6
+ def initialize(mod, &block) # :nodoc:
7
+ category_model = mod if mod.is_a? Module
8
+ category_model.const_set("CATEGORY",self)
9
+ category_model.instance_eval do
10
+ def self.included(klass) # :nodoc:
11
+ category = const_get("CATEGORY")
12
+ klass.instance_eval(&category.send(:before_include_proc))
13
+ klass.instance_eval do
14
+ extend category.send(:for_class_module)
15
+ include category.send(:for_instance_module)
16
+ end
17
+ klass.instance_eval(&category.send(:after_include_proc))
18
+ end
19
+ end
20
+ self.instance_eval(&block)
21
+ end
22
+
23
+ # This block is executed before the category is included in the host class or module.
24
+ def before_include(&block)
25
+ self.before_include_proc = block
26
+ end
27
+
28
+ # This block is executed after the category is included in the host class or module.
29
+ def after_include(&block)
30
+ self.after_include_proc = block
31
+ end
32
+
33
+ # This block defines all the class/module methods of the category.
34
+ def for_class(&block)
35
+ self.for_class_module = Module.new(&block)
36
+ end
37
+
38
+ # This block defines all the instance methods of the category.
39
+ def for_instance(&block)
40
+ self.for_instance_module = Module.new(&block)
41
+ end
42
+
43
+ private
44
+
45
+ attr_accessor :before_include_proc, :after_include_proc, :for_instance_module, :for_class_module, :category_model # :nodoc:
46
+
47
+ def before_include_proc # :nodoc:
48
+ @before_include_proc ||= Proc.new { || nil }
49
+ end
50
+
51
+ def after_include_proc # :nodoc:
52
+ @after_include_proc ||= Proc.new { || nil }
53
+ end
54
+
55
+ def for_class_module # :nodoc:
56
+ @for_class_module ||= Module.new
57
+ end
58
+
59
+ def for_instance_module # :nodoc:
60
+ @for_instance_module ||= Module.new
61
+ end
62
+ end
63
+ end
64
+
65
+ module Kernel
66
+ # defines a category.
67
+ # If module_or_name is a String or a Symbol then a new Module will be created in the current scope with this name.
68
+ # If a Module is passed then this Module will be used as the category Module.
69
+ #
70
+ # If String responds to camelcase it will be camelcased for you.
71
+ def category(module_or_name, &block)
72
+ mod = nil
73
+ if module_or_name.is_a? ::Module
74
+ mod = module_or_name
75
+ else
76
+ module_or_name = module_or_name.to_s.camelcase if module_or_name.to_s.respond_to? :camelcase
77
+ mod = ""
78
+ mod = "::#{self}" if (self.is_a? ::Module or self.is_a? ::Class) and self.to_s != "main"
79
+ mod = Object.module_eval("module #{mod}::#{module_or_name} ; end ; #{mod}::#{module_or_name}", __FILE__, __LINE__)
80
+ end
81
+ Class::Category.new(mod,&block)
82
+ end
83
+ end
84
+
@@ -0,0 +1,48 @@
1
+
2
+ class BaseA ; end
3
+
4
+ describe BaseA do
5
+
6
+ before :all do
7
+ category :BaseAClassExtention do
8
+ before_include do
9
+ class << self
10
+ attr_accessor :name
11
+ end
12
+ end
13
+ after_include do
14
+ class << self
15
+ alias_method :hello_alias, :hello
16
+ end
17
+ end
18
+ for_class do
19
+ def hello
20
+ "Hello #{name}"
21
+ end
22
+ end
23
+ end
24
+ BaseA.send :include, BaseAClassExtention
25
+ end
26
+
27
+ it "should respond to name" do
28
+ BaseA.should respond_to(:name)
29
+ end
30
+
31
+ it "should respond to name=" do
32
+ BaseA.should respond_to("name=")
33
+ end
34
+
35
+ it "should respond to hello" do
36
+ BaseA.should respond_to(:hello)
37
+ end
38
+
39
+ it "should respond to hello_alias" do
40
+ BaseA.should respond_to(:hello_alias)
41
+ end
42
+
43
+ it "should execute properly" do
44
+ BaseA.name = "World"
45
+ BaseA.hello.should be_eql("Hello World")
46
+ end
47
+
48
+ end
@@ -0,0 +1,49 @@
1
+
2
+ class BaseD ; end
3
+ module BaseDClassExtention ; end
4
+
5
+ describe BaseD do
6
+
7
+ before :all do
8
+ category :BaseDClassExtention do
9
+ before_include do
10
+ class << self
11
+ attr_accessor :name
12
+ end
13
+ end
14
+ after_include do
15
+ class << self
16
+ alias_method :hello_alias, :hello
17
+ end
18
+ end
19
+ for_class do
20
+ def hello
21
+ "Hello #{name}"
22
+ end
23
+ end
24
+ end
25
+ BaseD.send :include, BaseDClassExtention
26
+ end
27
+
28
+ it "should respond to name" do
29
+ BaseD.should respond_to(:name)
30
+ end
31
+
32
+ it "should respond to name=" do
33
+ BaseD.should respond_to("name=")
34
+ end
35
+
36
+ it "should respond to hello" do
37
+ BaseD.should respond_to(:hello)
38
+ end
39
+
40
+ it "should respond to hello_alias" do
41
+ BaseD.should respond_to(:hello_alias)
42
+ end
43
+
44
+ it "should execute properly" do
45
+ BaseD.name = "World"
46
+ BaseD.hello.should be_eql("Hello World")
47
+ end
48
+
49
+ end
@@ -0,0 +1,44 @@
1
+ class BaseB ; end
2
+
3
+ describe BaseB, "instance" do
4
+
5
+ before :all do
6
+ category :BaseBInstanceExtention do
7
+ before_include do
8
+ attr_accessor :name
9
+ end
10
+ after_include do
11
+ alias_method :hello_alias, :hello
12
+ end
13
+ for_instance do
14
+ def hello
15
+ "Hello #{name}"
16
+ end
17
+ end
18
+ end
19
+ BaseB.send :include, BaseBInstanceExtention
20
+ @base = BaseB.new
21
+ end
22
+
23
+ it "should respond to name" do
24
+ @base.should respond_to(:name)
25
+ end
26
+
27
+ it "should respond to name=" do
28
+ @base.should respond_to("name=")
29
+ end
30
+
31
+ it "should respond to hello" do
32
+ @base.should respond_to(:hello)
33
+ end
34
+
35
+ it "should respond to hello_alias" do
36
+ @base.should respond_to(:hello_alias)
37
+ end
38
+
39
+ it "should execute properly" do
40
+ @base.name = "World"
41
+ @base.hello.should be_eql("Hello World")
42
+ end
43
+
44
+ end
@@ -0,0 +1,45 @@
1
+ class BaseC ; end
2
+ module BaseCInstanceExtention ; end
3
+
4
+ describe BaseB, "instance" do
5
+
6
+ before :all do
7
+ category BaseCInstanceExtention do
8
+ before_include do
9
+ attr_accessor :name
10
+ end
11
+ after_include do
12
+ alias_method :hello_alias, :hello
13
+ end
14
+ for_instance do
15
+ def hello
16
+ "Hello #{name}"
17
+ end
18
+ end
19
+ end
20
+ BaseC.send :include, BaseCInstanceExtention
21
+ @base = BaseC.new
22
+ end
23
+
24
+ it "should respond to name" do
25
+ @base.should respond_to(:name)
26
+ end
27
+
28
+ it "should respond to name=" do
29
+ @base.should respond_to("name=")
30
+ end
31
+
32
+ it "should respond to hello" do
33
+ @base.should respond_to(:hello)
34
+ end
35
+
36
+ it "should respond to hello_alias" do
37
+ @base.should respond_to(:hello_alias)
38
+ end
39
+
40
+ it "should execute properly" do
41
+ @base.name = "World"
42
+ @base.hello.should be_eql("Hello World")
43
+ end
44
+
45
+ end
@@ -0,0 +1,3 @@
1
+ --color
2
+ -r lib/categories.rb
3
+ -f specdoc
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: categories
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Simon Menke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-02-11 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.5.0
23
+ version:
24
+ description: Easily create class and module extentions.
25
+ email: simon@5xm.org
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - History.txt
32
+ - LICENSE.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ files:
36
+ - History.txt
37
+ - LICENSE.txt
38
+ - Manifest.txt
39
+ - README.txt
40
+ - Rakefile
41
+ - lib/categories.rb
42
+ - spec/categories_class_spec.rb
43
+ - spec/categories_class_with_module_spec.rb
44
+ - spec/categories_instance_spec.rb
45
+ - spec/categories_instance_with_module_spec.rb
46
+ - spec/spec.opts
47
+ has_rdoc: true
48
+ homepage: http://5xm.org
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --main
52
+ - README.txt
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project: categories
70
+ rubygems_version: 1.0.1
71
+ signing_key:
72
+ specification_version: 2
73
+ summary: Easily create class and module extentions.
74
+ test_files: []
75
+