rulebook 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,23 +1,33 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rulebook (0.4.3)
5
- meta_tools (= 0.2.3)
4
+ rulebook (0.5.0)
5
+ meta_tools (~> 0.2.3)
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- meta_tools (0.2.3)
10
+ diff-lcs (1.1.3)
11
+ meta_tools (0.2.5)
12
+ mocha (0.9.12)
11
13
  rake (0.9.2)
12
- riot (0.12.4)
13
- rr
14
- rr (1.0.2)
14
+ rspec (2.6.0)
15
+ rspec-core (~> 2.6.0)
16
+ rspec-expectations (~> 2.6.0)
17
+ rspec-mocks (~> 2.6.0)
18
+ rspec-core (2.6.4)
19
+ rspec-expectations (2.6.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.6.0)
22
+ shoulda (2.11.3)
15
23
 
16
24
  PLATFORMS
17
25
  ruby
18
26
  x86-mingw32
19
27
 
20
28
  DEPENDENCIES
21
- rake (= 0.9.2)
22
- riot (= 0.12.4)
29
+ mocha (~> 0.9.12)
30
+ rake (~> 0.9.2)
31
+ rspec (~> 2.6.0)
23
32
  rulebook!
33
+ shoulda (~> 2.11.3)
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009,2010,2011 Ryan Lewis
1
+ Copyright (c) 2009-2011 Ryan Lewis
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
@@ -10,11 +10,6 @@ rescue Bundler::BundlerError => e
10
10
  end
11
11
  require 'rake'
12
12
 
13
- require 'rake/testtask'
14
-
15
- Rake::TestTask.new(:test) do |t|
16
- t.libs.concat ['lib', 'test']
17
- t.pattern = 'test/**/test_*.rb'
18
- t.verbose = false
19
- end
20
- task :default => :test
13
+ require 'rspec/core/rake_task'
14
+ RSpec::Core::RakeTask.new(:spec)
15
+ task :default => :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.3
1
+ 0.5.0
@@ -1,54 +1,56 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
- require 'rulebook'
3
-
4
- class User
5
- follows_the_rules!
6
-
7
- attr :title
8
-
9
- def initialize(title=:user)
10
- @title = title
11
- end
12
-
13
- rulebook.add /^is_(admin|user)$/ do |title|
14
- @title = title.to_sym
15
- self
16
- end
17
-
18
- rulebook.add /^is_(admin|user)\?$/ do |title|
19
- @title == title.to_sym
20
- end
21
-
22
- class << self
23
- follows_the_rules!
24
- rulebook.add /^new_(admin|user)$/ do |title|
25
- instance = new
26
- instance.instance_eval { @title = title.to_sym }
27
- instance
28
- end
29
- end
30
- end
31
-
32
- u = User.new
33
-
34
- p u.is_user? # => true
35
- p u.is_admin? # => false
36
-
37
- u.is_admin
38
-
39
- p u.is_user? # => false
40
- p u.is_admin? # => true
41
-
42
- u = User.new_admin
43
- p u.is_admin? # => true
44
-
45
-
46
- # DEV: TODO CLASS RULES O_O
47
- Integer.follows_the_rules!
48
- Integer.rulebook.add /to_base_(\d+)/ do |base|
49
- p base
50
- p "OMG"
51
- to_s(base)
52
- end
53
-
54
- p 10.to_base_16
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
+ require 'rulebook'
3
+
4
+ class User
5
+ follows_the_rules!
6
+
7
+ attr :title
8
+
9
+ def initialize(title=:user)
10
+ @title = title
11
+ end
12
+
13
+ rulebook.add /^is_(admin|user)$/ do |title|
14
+ @title = title.to_sym
15
+ self
16
+ end
17
+
18
+ rulebook.add /^is_(admin|user)\?$/ do |title|
19
+ @title == title.to_sym
20
+ end
21
+
22
+ class << self
23
+ follows_the_rules!
24
+
25
+ rulebook.add /^new_(admin|user)$/ do |title|
26
+ instance = new
27
+ instance.instance_eval { @title = title.to_sym }
28
+ instance
29
+ end
30
+ end
31
+ end
32
+
33
+ u = User.new
34
+
35
+ p u.is_user? # => true
36
+ p u.is_admin? # => false
37
+
38
+ u.is_admin
39
+
40
+ p u.is_user? # => false
41
+ p u.is_admin? # => true
42
+
43
+ u = User.new_admin
44
+ p u
45
+ p u.is_admin? # => true
46
+
47
+
48
+ # DEV: TODO CLASS RULES O_O
49
+ Integer.follows_the_rules!
50
+ Integer.rulebook.add /to_base_(\d+)/ do |base|
51
+ p base
52
+ p "OMG"
53
+ to_s(base)
54
+ end
55
+
56
+ p 10.to_base_16
@@ -0,0 +1,82 @@
1
+ class Module
2
+ # This declares that the current class has a rulebook
3
+ # with rules that it wants it's instances to follow.
4
+ #
5
+ # I picked this name because the probability of someone needing the method
6
+ # 'follows_the_rules!' (with a bang) is slim... hopefully.
7
+ def follows_the_rules!
8
+ extend(MetaTools)
9
+ include(MetaTools)
10
+
11
+ meta_def(:def_class_rule) do |what_to_capture, &class_block|
12
+
13
+ class_eval { @rulebook ||= Rulebook.new }.add(what_to_capture, &class_block)
14
+
15
+ # unless respond_to?(:method_missing)
16
+ meta_def(:method_missing) do |meth, *args, &block|
17
+
18
+ matching_rules = @rulebook[meth]
19
+
20
+ unless matching_rules.empty?
21
+ rule = matching_rules.first
22
+ rule_block = rule.block
23
+ rule_captures = rule[meth].captures || []
24
+ #rule_arity = rule_block.arity == -1 ? 0 : rule_block.arity
25
+ # The above removes the possibility of optional arguments
26
+
27
+ # Define the method
28
+ unless meta_class.respond_to?(meth)
29
+ meta_def(meth) do |*rule_args|
30
+ rule_args = (rule_captures + rule_args)#.take(rule_arity)
31
+ instance_exec(*rule_args, &rule_block)
32
+ end
33
+ end
34
+
35
+ send(meth, *args, &block)
36
+ else
37
+ super(meth, *args, &block)
38
+ end # matching_rules.empty?
39
+
40
+ end # meta_def(:method_missing)
41
+
42
+ # end # respond_to?(:method_missing)
43
+
44
+ end # def_class_rule
45
+
46
+ meta_def(:def_rule) do |what_to_capture, &class_block|
47
+
48
+ (@rulebook ||= Rulebook.new).add(what_to_capture, &class_block)
49
+
50
+ # unless respond_to?(:method_missing)
51
+ define_method(:method_missing) do |meth, *args, &block|
52
+ matching_rules = self.class.instance_variable_get(:@rulebook)[meth]
53
+
54
+ unless matching_rules.empty?
55
+ rule = matching_rules.first
56
+ rule_block = rule.block
57
+ rule_captures = rule[meth].captures || []
58
+ # rule_arity = rule_block.arity == -1 ? 0 : rule_block.arity
59
+ # The above removes the possibility of optional arguments
60
+
61
+ # Define the method
62
+ unless meta_class.respond_to?(meth)
63
+ meta_def(meth) do |*rule_args|
64
+ rule_args = (rule_captures + rule_args)#.take(rule_arity)
65
+ instance_exec(*rule_args, &rule_block)
66
+ end
67
+ end
68
+
69
+ send(meth, *args, &block)
70
+ else
71
+ super(meth, *args, &block)
72
+ end # matching_rules.empty?
73
+
74
+ end # meta_def(:method_missing)
75
+
76
+ # end # respond_to?(:method_missing)
77
+
78
+ end # def_rule
79
+
80
+ end # follows_the_rules!
81
+
82
+ end # Module
@@ -1,19 +1,46 @@
1
- $LOAD_PATH.unshift(File.dirname(__FILE__))
2
-
3
- class Rulebook
4
- VERSION = "0.4.3"
5
- end
6
-
7
- require 'rulebook/rule'
1
+ __DIR__ = File.dirname(__FILE__)
2
+ $:.unshift(__DIR__) unless $:.include?(__DIR__)
8
3
 
9
4
  class Rulebook
5
+ VERSION = "0.5.0"
6
+
7
+ class Rule
8
+ attr :block
9
+
10
+ def initialize(regexp, &block)
11
+ # TODO: Match more than Regexp. Strings and Symbols pls.
12
+ raise(TypeError, 'regexp must be of type Regexp') unless regexp.is_a?(Regexp)
13
+ raise(ArgumentError, 'a block is needed') unless block_given?
14
+ @regexp, @block = regexp, block
15
+ end
16
+
17
+ def [](query)
18
+ query.to_s.downcase.match(@regexp)
19
+ end
20
+ alias_method :match, :[]
21
+
22
+ def matches?(query)
23
+ !self[query].nil?
24
+ end
25
+ end
26
+
10
27
  attr_accessor :rules
11
- def initialize; @rules = []; end
12
- def add(what_to_capture, &block); @rules << Rule.new(what_to_capture, &block); end
13
- def [](query); @rules.find_all { |rule| rule.matches_against?(query) }; end
28
+
29
+ def initialize
30
+ @rules = []
31
+ end
32
+
33
+ def add(regexp, &block)
34
+ @rules << Rule.new(regexp, &block)
35
+ end
36
+ # alias_method :<<. :add
37
+
38
+ def [](query)
39
+ @rules.find_all { |rule| rule.matches?(query) }
40
+ end
14
41
  alias_method :rules_that_match_against, :[]
42
+ alias_method :match, :[]
15
43
  end
16
44
 
17
- require 'rulebook/class_methods'
18
- require 'rulebook/instance_methods'
19
- require 'rulebook/core_ext/module'
45
+ require 'meta_tools'
46
+ require 'core_ext'
@@ -1,52 +1,54 @@
1
- Gem::Specification.new do |s|
2
- s.author = "Ryan Scott Lewis"
3
- s.email = "c00lryguy@gmail.com"
4
- s.homepage = "http://github.com/c00lryguy/rulebook"
5
-
6
- s.description = "Allows you to define a set of 'rules' or dynamic methods to apply to a class."
7
- s.summary = "Define methods with regex for dynamic methods."
8
-
9
- s.require_paths = ["lib"]
10
-
11
- s.name = File.basename(__FILE__, ".gemspec")
12
- s.version = File.read("VERSION")
13
- # VERSIONING
14
- # Some people like to use a YAML file to display the version, some like CSV,
15
- # others might just add a constant set to a version string, some (Rack) might
16
- # even have an array splitting the version into parts.
17
- # Just edit the above line appropriately.
18
- # An easy thing to do is set a constant within your app to a version string
19
- # and use it in here
20
-
21
- # Add directories you *might* use in ALL projects.
22
- s.files = [File.basename(__FILE__)] + Dir['lib/**/*'] + Dir['bin/**/*'] + Dir['test/**/*'] + Dir['examples/**/*']
23
-
24
- # Add files you *might* use in ALL projects!
25
- %W{Gemfile.lock README.* README Rakefile VERSION LICENSE}.each do |file|
26
- s.files.unshift(file) if File.exists?(file)
27
- end
28
-
29
- # Add files you *might* use in ALL projects!
30
- %W{README.* README VERSION LICENSE LICENSE.*}.each do |file|
31
- (s.extra_rdoc_files ||= []).unshift(file) if File.exists?(file)
32
- end
33
-
34
- # s.executables = ["bin/myapp.rb"]
35
-
36
- # If you only specify one application file in executables, that file becomes
37
- # the default executable. Therefore, you only need to specify this value if you
38
- # have more than one application file.
39
- if s.executables.length > 1
40
- if exe = s.executables.find { |e| e.include?(File.basename(__FILE__, ".gemspec")) }
41
- s.default_executable = exe
42
- else
43
- raise(Exception, "Couldn't automatically figure out the default_executable")
44
- end
45
- end
46
-
47
- s.test_files = Dir['test/**/*'] + Dir['examples/**/*']
48
-
49
- s.add_dependency("meta_tools", "0.2.3")
50
- s.add_development_dependency("rake", "0.9.2")
51
- s.add_development_dependency("riot", "0.12.4")
1
+ Gem::Specification.new do |s|
2
+ s.author = "Ryan Scott Lewis"
3
+ s.email = "c00lryguy@gmail.com"
4
+ s.homepage = "http://github.com/c00lryguy/rulebook"
5
+
6
+ s.description = "Allows you to define a set of 'rules' or dynamic methods to apply to a class."
7
+ s.summary = "Define methods with regex for dynamic methods."
8
+
9
+ s.require_paths = ["lib"]
10
+
11
+ s.name = File.basename(__FILE__, ".gemspec")
12
+ s.version = File.read("VERSION")
13
+ # VERSIONING
14
+ # Some people like to use a YAML file to display the version, some like CSV,
15
+ # others might just add a constant set to a version string, some (Rack) might
16
+ # even have an array splitting the version into parts.
17
+ # Just edit the above line appropriately.
18
+ # An easy thing to do is set a constant within your app to a version string
19
+ # and use it in here
20
+
21
+ # Add directories you *might* use in ALL projects.
22
+ s.files = [File.basename(__FILE__)] + Dir['lib/**/*'] + Dir['bin/**/*'] + Dir['test/**/*'] + Dir['examples/**/*'] + Dir['spec/**/*']
23
+
24
+ # Add files you *might* use in ALL projects!
25
+ %W{Gemfile.lock README.* README Rakefile VERSION LICENSE}.each do |file|
26
+ s.files.unshift(file) if File.exists?(file)
27
+ end
28
+
29
+ # Add files you *might* use in ALL projects!
30
+ %W{README.* README VERSION LICENSE LICENSE.*}.each do |file|
31
+ (s.extra_rdoc_files ||= []).unshift(file) if File.exists?(file)
32
+ end
33
+
34
+ # s.executables = ["bin/myapp.rb"]
35
+
36
+ # If you only specify one application file in executables, that file becomes
37
+ # the default executable. Therefore, you only need to specify this value if you
38
+ # have more than one application file.
39
+ if s.executables.length > 1
40
+ if exe = s.executables.find { |e| e.include?(File.basename(__FILE__, ".gemspec")) }
41
+ s.default_executable = exe
42
+ else
43
+ raise(Exception, "Couldn't automatically figure out the default_executable")
44
+ end
45
+ end
46
+
47
+ s.test_files = Dir['test/**/*'] + Dir['examples/**/*'] + Dir['spec/**/*']
48
+
49
+ s.add_dependency("meta_tools", "~> 0.2.3")
50
+ s.add_development_dependency("rake", "~> 0.9.2")
51
+ s.add_development_dependency("rspec", "~> 2.6.0")
52
+ s.add_development_dependency("shoulda", "~> 2.11.3")
53
+ s.add_development_dependency("mocha", "~> 0.9.12")
52
54
  end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module SomeService
4
+ follows_the_rules!
5
+
6
+ def_class_rule(/^say_([a-z_]+)$/) do |message|
7
+ message.gsub(/_/, ' ')
8
+ end
9
+ end
10
+
11
+ describe SomeService do
12
+ describe "When a method matches the rule's regexp" do
13
+ it "should respond correctly" do
14
+ SomeService.say_hello_world.should == "hello world"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rulebook::Rule do
4
+ let(:rule) { Rule.new(/^foobar$/){ "Foobar!" } }
5
+ end
6
+
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rulebook do
4
+ let(:rulebook) { Rulebook.new }
5
+ let(:regexp) { /^foobar$/ }
6
+
7
+ describe "#initialize" do
8
+ it "should have the #rules method available" do
9
+ rulebook.should be_instance_of(Rulebook)
10
+ rulebook.should respond_to(:rules)
11
+ rulebook.rules.should == Array.new
12
+ end
13
+ end
14
+
15
+ describe "#add and #<<" do
16
+ it "should add a rule correctly" do
17
+ block = proc { puts "Foobar" }
18
+
19
+ Rulebook::Rule.expects(:initialize).with(regexp, block)
20
+
21
+ rulebook.rules.length.should == 0
22
+ rulebook.add(regexp, &block)
23
+ rulebook.rules.length.should == 1
24
+ end
25
+ end
26
+
27
+ describe "#[], #match, and #rules_that_match_against" do
28
+ it "should return an Array of rules that match the given query" do
29
+ query = "foobar"
30
+
31
+ rulebook.add(regexp) { "Foobar" }
32
+
33
+ rulebook[query].should == [rulebook.rules.first]
34
+ rulebook.match(query).should == [rulebook.rules.first]
35
+ rulebook.rules_that_match_against(query).should == [rulebook.rules.first]
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'mocha'
4
+ require 'rulebook'
5
+
6
+ # Require all files within /support
7
+ Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
@@ -0,0 +1,18 @@
1
+ class User
2
+ follows_the_rules!
3
+
4
+ attr :role
5
+
6
+ def initialize
7
+ @role = :user
8
+ end
9
+
10
+ def_class_rule(/new_(admin|moderator|user)/) do |role|
11
+ new.instance_eval { @role = role.to_sym; self }
12
+ end
13
+
14
+ def_rule(/is_(admin|moderator|user)\?/) do |role|
15
+ @role == role.to_sym
16
+ end
17
+
18
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe User do
4
+ describe ".new" do
5
+ it "returns a new User with the role of :user" do
6
+ User.new.instance_variable_get(:@role).should == :user
7
+ end
8
+ end
9
+ describe ".new_user" do
10
+ it "returns a new User with the role of :user" do
11
+ User.new_user.instance_variable_get(:@role).should == :user
12
+ end
13
+ end
14
+ describe ".new_moderator" do
15
+ it "returns a new User with the role of :moderator" do
16
+ User.new_moderator.instance_variable_get(:@role).should == :moderator
17
+ end
18
+ end
19
+ describe ".new_admin" do
20
+ it "returns a new User with the role of :admin" do
21
+ User.new_admin.instance_variable_get(:@role).should == :admin
22
+ end
23
+ end
24
+ describe "#is_user?" do
25
+ describe "when the user's role is :user" do
26
+ it "should return true" do
27
+ User.new.is_user?.should == true
28
+ end
29
+ end
30
+ describe "when the user's role is not :user" do
31
+ it "should return false" do
32
+ User.new_moderator.is_user?.should == false
33
+ User.new_admin.is_user?.should == false
34
+ end
35
+ end
36
+ end
37
+ describe "#is_moderator?" do
38
+ describe "when the user's role is :moderator" do
39
+ it "should return true" do
40
+ User.new_moderator.is_moderator?.should == true
41
+ end
42
+ end
43
+ describe "when the user's role is not :moderator" do
44
+ it "should return false" do
45
+ User.new.is_moderator?.should == false
46
+ User.new_user.is_moderator?.should == false
47
+ User.new_admin.is_moderator?.should == false
48
+ end
49
+ end
50
+ end
51
+ describe "#is_admin?" do
52
+ describe "when the user's role is :admin" do
53
+ it "should return true" do
54
+ User.new_admin.is_admin?.should == true
55
+ end
56
+ end
57
+ describe "when the user's role is not :admin" do
58
+ it "should return false" do
59
+ User.new.is_admin?.should == false
60
+ User.new_user.is_admin?.should == false
61
+ User.new_moderator.is_admin?.should == false
62
+ end
63
+ end
64
+ end
65
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rulebook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,42 +9,63 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-26 00:00:00.000000000 -04:00
13
- default_executable:
12
+ date: 2011-09-05 00:00:00.000000000Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: meta_tools
17
- requirement: &2165090800 !ruby/object:Gem::Requirement
16
+ requirement: &70328089193000 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
- - - =
19
+ - - ~>
21
20
  - !ruby/object:Gem::Version
22
21
  version: 0.2.3
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *2165090800
24
+ version_requirements: *70328089193000
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: rake
28
- requirement: &2165010640 !ruby/object:Gem::Requirement
27
+ requirement: &70328089192520 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
- - - =
30
+ - - ~>
32
31
  - !ruby/object:Gem::Version
33
32
  version: 0.9.2
34
33
  type: :development
35
34
  prerelease: false
36
- version_requirements: *2165010640
35
+ version_requirements: *70328089192520
37
36
  - !ruby/object:Gem::Dependency
38
- name: riot
39
- requirement: &2165010020 !ruby/object:Gem::Requirement
37
+ name: rspec
38
+ requirement: &70328089192060 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
- - - =
41
+ - - ~>
43
42
  - !ruby/object:Gem::Version
44
- version: 0.12.4
43
+ version: 2.6.0
45
44
  type: :development
46
45
  prerelease: false
47
- version_requirements: *2165010020
46
+ version_requirements: *70328089192060
47
+ - !ruby/object:Gem::Dependency
48
+ name: shoulda
49
+ requirement: &70328089191600 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.11.3
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70328089191600
58
+ - !ruby/object:Gem::Dependency
59
+ name: mocha
60
+ requirement: &70328089191140 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.9.12
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70328089191140
48
69
  description: Allows you to define a set of 'rules' or dynamic methods to apply to
49
70
  a class.
50
71
  email: c00lryguy@gmail.com
@@ -59,16 +80,15 @@ files:
59
80
  - Rakefile
60
81
  - Gemfile.lock
61
82
  - rulebook.gemspec
62
- - lib/rulebook/class_methods.rb
63
- - lib/rulebook/core_ext/module.rb
64
- - lib/rulebook/instance_methods.rb
65
- - lib/rulebook/rule.rb
83
+ - lib/core_ext.rb
66
84
  - lib/rulebook.rb
67
- - test/helper.rb
68
- - test/test_chevy.rb
69
- - test/test_rule.rb
70
85
  - examples/simple.rb
71
- has_rdoc: true
86
+ - spec/module_class_methods_spec.rb
87
+ - spec/rule_spec.rb
88
+ - spec/rulebook_spec.rb
89
+ - spec/spec_helper.rb
90
+ - spec/support/user.rb
91
+ - spec/user_spec.rb
72
92
  homepage: http://github.com/c00lryguy/rulebook
73
93
  licenses: []
74
94
  post_install_message:
@@ -89,12 +109,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
109
  version: '0'
90
110
  requirements: []
91
111
  rubyforge_project:
92
- rubygems_version: 1.6.2
112
+ rubygems_version: 1.8.6
93
113
  signing_key:
94
114
  specification_version: 3
95
115
  summary: Define methods with regex for dynamic methods.
96
116
  test_files:
97
- - test/helper.rb
98
- - test/test_chevy.rb
99
- - test/test_rule.rb
100
117
  - examples/simple.rb
118
+ - spec/module_class_methods_spec.rb
119
+ - spec/rule_spec.rb
120
+ - spec/rulebook_spec.rb
121
+ - spec/spec_helper.rb
122
+ - spec/support/user.rb
123
+ - spec/user_spec.rb
@@ -1,6 +0,0 @@
1
- class Rulebook
2
- module ClassMethods
3
- # Finds or creates an instrance of Rulebook
4
- def rulebook; @rulebook ||= Rulebook.new; end
5
- end
6
- end
@@ -1,24 +0,0 @@
1
- require 'meta_tools'
2
-
3
- #++
4
- # Should this be class Object?
5
- # Is there really a difference?
6
- #--
7
- class Module
8
- # This declares that the current class has a rulebook
9
- # with rules that it wants it's instances to follow.
10
- #
11
- # I picked this name because the probability of someone needing the method
12
- # 'follows_the_rules!' (with a bang) is slim... hopefully.
13
- #
14
- # This adds the following method:
15
- # User#rulebook
16
- # Returns the RuleBook instance that contains the defined rules.
17
- def follows_the_rules!
18
- extend(MetaTools)
19
- include(MetaTools)
20
-
21
- extend(Rulebook::ClassMethods)
22
- include(Rulebook::InstanceMethods)
23
- end
24
- end
@@ -1,41 +0,0 @@
1
- class Rulebook
2
- module InstanceMethods
3
- def method_missing(meth, *args, &blk)
4
- # Classes and instances find their rulebook differently.
5
- begin
6
- rulebook = self.class.rulebook
7
- rescue NoMethodError
8
- rulebook = metaclass.rulebook
9
- end
10
-
11
- rules = rulebook.rules_that_match_against(meth)
12
- unless rules.nil?
13
- rules.each do |rule|
14
- # =S Run all matched rules or run first matched rule...?
15
- # rule = rules.first
16
-
17
- captures = rule[meth].captures || []
18
- block = rule.block
19
-
20
- # Remove the possibility of optional arguments
21
- arity = block.arity == -1 ? 0 : block.arity
22
-
23
- # Define the method
24
- meta_def(meth) do |*args|
25
- instance_exec(*(captures + args).take(arity), &block)
26
- end
27
-
28
- # klass = self.class
29
- # klass.send(:define_method, meth) do |*args|
30
- # instance_exec(*(captures + args).take(arity), &block)
31
- # end
32
-
33
- # Call the method and return the result
34
- return send(meth, *args, &block)
35
- end
36
- else
37
- super
38
- end
39
- end
40
- end
41
- end
@@ -1,18 +0,0 @@
1
- class Rulebook
2
- # This class creates an instance of a Rule, which holds the
3
- # Regexp to match against and the block to run when matched
4
- class Rule
5
- attr :block
6
-
7
- def initialize(what_to_capture, &block)
8
- # TODO: Match more than Regexp. Strings and Symbols pls.
9
- raise(TypeError, 'what_to_capture must be of type Regexp') unless what_to_capture.is_a?(Regexp)
10
- raise(ArgumentError, 'a block is needed') unless block_given?
11
- @what_to_capture, @block = what_to_capture, block
12
- end
13
-
14
- def [](query); query.to_s.downcase.match(@what_to_capture); end
15
- alias_method :match_against, :[]
16
- def matches_against?(query); !self[query].nil?; end
17
- end
18
- end
@@ -1,7 +0,0 @@
1
- require 'rubygems'
2
-
3
- require 'riot'
4
-
5
- $LOAD_PATH.unshift(File.dirname(__FILE__))
6
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
- require 'rulebook'
@@ -1,56 +0,0 @@
1
- require 'helper'
2
-
3
- class Engine
4
- follows_the_rules!
5
-
6
- attr_accessor :state
7
-
8
- def initialize
9
- @state = :off
10
- end
11
-
12
- rulebook.add(/is_(off|idle|broken)/) do |state|
13
- @state = state.to_sym
14
- self
15
- end
16
-
17
- rulebook.add(/is_(off|idle|broken)\?/) do |state|
18
- @state == state.to_sym
19
- end
20
- end
21
-
22
- context "A Chevy engine" do
23
- setup { Engine.new }
24
-
25
- context "that is off" do
26
- asserts_topic.assigns(:state, :off)
27
- asserts(:state).equals(:off)
28
- end
29
-
30
- context "that is idle" do
31
- setup { topic.is_idle }
32
- asserts_topic.assigns(:state, :idle)
33
- asserts(:state).equals(:idle)
34
- end
35
-
36
- context "that is broken as usual" do
37
- setup { topic.is_broken }
38
- asserts_topic.assigns(:state, :broken)
39
- end
40
-
41
- context "checked with custom rule" do
42
- context "that is off" do
43
- asserts(:is_off?)
44
- end
45
-
46
- context "that is idle" do
47
- setup { topic.is_idle }
48
- asserts(:is_idle?)
49
- end
50
-
51
- context "that is broken as usual" do
52
- setup { topic.is_broken }
53
- asserts(:is_broken?)
54
- end
55
- end
56
- end
@@ -1,10 +0,0 @@
1
- require 'helper'
2
-
3
- context "A rule all on it's lonesome" do
4
- setup do
5
- Rulebook::Rule.new(/is_lonely/) { "='(" }
6
- end
7
- asserts("that this rule truly is alone") { topic.matches_against?(:is_lonely) }
8
- denies("an awkward method") { topic.matches_against?(:is_surrounded_by_other_rule_friends) }
9
- asserts("this works with Strings") { topic.matches_against?("is_lonely") }
10
- end