fact_checker 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ coverage
6
+ .DS_Store
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.2@fact_checker 2>/dev/null
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fact_checker.gemspec
4
+ gemspec
data/README ADDED
@@ -0,0 +1,23 @@
1
+ 1. What is FactChecker
2
+
3
+ Simple ruby gem to check hierarchically dependent "facts" about objects.
4
+
5
+ 2. Getting started
6
+
7
+ 2.1 Installation
8
+
9
+ gem install fact_checker
10
+
11
+ 2.2 Usage
12
+
13
+ https://github.com/alexis/fact_checker/tree/master/examples
14
+
15
+ 3. Development / Contributing
16
+
17
+ 3.1 Testing code with rspec
18
+
19
+ rake spec
20
+
21
+ 3.2 Testing code coverage with rcov for ruby 1.8
22
+
23
+ rcov -Ilib:spec --exclude gem spec/fact_checker_spec.rb
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rake'
4
+ require 'bundler'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ Dir['lib/tasks/**/*.rake'].
9
+ concat(Dir['tasks/**/*.rake']).
10
+ concat(Dir['{test,spec}/*.rake']).each { |rake| load(rake) }
11
+
12
+ task :default => :spec
13
+ task :test => :spec # for http://test.rubygems.org/
@@ -0,0 +1,72 @@
1
+ # FactChecker / Examples
2
+
3
+ ## How to run
4
+
5
+ ``` ruby
6
+ bundle exec ruby -rubygems examples/basic.rb
7
+ ```
8
+
9
+ ## BasicExample
10
+
11
+ ``` ruby
12
+ # encoding: utf-8
13
+
14
+ require 'fact_checker'
15
+
16
+ class BasicExample
17
+ include FactChecker
18
+
19
+ def_fact :be
20
+ def_fact :be_or => :be
21
+ def_fact :be_or_not => :be, :if => :my_requirement?
22
+ def_fact :be_or_not_to => [:be, :be_or_not], :if => :my_requirement?
23
+ def_fact :be_or_not_to_be => :be, :if => lambda { |context| !context.my_requirement? }
24
+ end
25
+
26
+ target = BasicExample.new
27
+
28
+ def target.my_requirement?; false end
29
+
30
+ p target.fact_possible? :be
31
+ # => true
32
+ p target.fact_accomplished? :be
33
+ # => true
34
+ p target.be?
35
+ # => true
36
+
37
+ puts
38
+
39
+ p target.fact_possible? :be_or
40
+ # => true
41
+ p target.fact_accomplished? :be_or
42
+ # => true
43
+ p target.be_or?
44
+ # => true
45
+
46
+ puts
47
+
48
+ p target.fact_possible? :be_or_not
49
+ # => true
50
+ p target.fact_accomplished? :be_or_not
51
+ # => false
52
+ p target.be_or_not?
53
+ # => false
54
+
55
+ puts
56
+
57
+ p target.fact_possible? :be_or_not_to
58
+ # => false
59
+ p target.fact_accomplished? :be_or_not_to
60
+ # => false
61
+ p target.be_or_not_to?
62
+ # => false
63
+
64
+ puts
65
+
66
+ p target.fact_possible? :be_or_not_to_be
67
+ # => true
68
+ p target.fact_accomplished? :be_or_not_to_be
69
+ # => true
70
+ p target.be_or_not_to_be?
71
+ # => true
72
+ ```
data/examples/basic.rb ADDED
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fact_checker'
4
+
5
+ class BasicExample
6
+ include FactChecker
7
+
8
+ def_fact :be
9
+ def_fact :be_or => :be
10
+ def_fact :be_or_not => :be, :if => :my_requirement?
11
+ def_fact :be_or_not_to => [:be, :be_or_not], :if => :my_requirement?
12
+ def_fact :be_or_not_to_be => :be, :if => lambda { |context| !context.my_requirement? }
13
+ end
14
+
15
+ target = BasicExample.new
16
+
17
+ def target.my_requirement?; false end
18
+
19
+ p target.fact_possible? :be
20
+ # => true
21
+ p target.fact_accomplished? :be
22
+ # => true
23
+ p target.be?
24
+ # => true
25
+
26
+ puts
27
+
28
+ p target.fact_possible? :be_or
29
+ # => true
30
+ p target.fact_accomplished? :be_or
31
+ # => true
32
+ p target.be_or?
33
+ # => true
34
+
35
+ puts
36
+
37
+ p target.fact_possible? :be_or_not
38
+ # => true
39
+ p target.fact_accomplished? :be_or_not
40
+ # => false
41
+ p target.be_or_not?
42
+ # => false
43
+
44
+ puts
45
+
46
+ p target.fact_possible? :be_or_not_to
47
+ # => false
48
+ p target.fact_accomplished? :be_or_not_to
49
+ # => false
50
+ p target.be_or_not_to?
51
+ # => false
52
+
53
+ puts
54
+
55
+ p target.fact_possible? :be_or_not_to_be
56
+ # => true
57
+ p target.fact_accomplished? :be_or_not_to_be
58
+ # => true
59
+ p target.be_or_not_to_be?
60
+ # => true
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "fact_checker/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "fact_checker"
8
+ s.version = FactChecker::VERSION
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Alexey Smolianinov", "Ivan Povalyukhin"]
11
+ s.email = ["alexisowl+fact_checker@gmail.com"]
12
+ s.homepage = "https://github.com/alexis/fact_checker"
13
+ s.summary = %q{Checks facts which may depend on other facts}
14
+ s.description = %q{Simple gem to check hierarchically dependent "facts" about objects}
15
+
16
+ s.rubyforge_project = "fact_checker"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.required_ruby_version = ">= 1.8.7"
24
+ s.required_rubygems_version = ">= 1.3.5"
25
+
26
+ s.add_development_dependency 'rspec', '~> 2.6'
27
+ s.add_development_dependency 'rake'
28
+ s.add_development_dependency 'bundler'
29
+ end
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ module FactChecker
4
+ class Base
5
+ attr_accessor :facts, :dependencies, :requirements
6
+
7
+ def initialize(facts = nil, deps = nil, reqs = nil)
8
+ @facts = facts || []
9
+ @dependencies = deps || {}
10
+ @requirements = reqs || {}
11
+ end
12
+
13
+ def initialize_copy(orig)
14
+ super
15
+ @facts = orig.facts.dup
16
+ @dependencies = orig.dependencies.dup
17
+ @requirements = orig.requirements.dup
18
+ end
19
+
20
+ def accomplished_facts(context)
21
+ facts.select{ |fact| fact_accomplished?(context, fact) }
22
+ end
23
+ def possible_facts(context)
24
+ facts.select{ |fact| fact_possible?(context, fact) }
25
+ end
26
+
27
+ # Checks if requirement and dependency for the fact are satisfied
28
+ def fact_accomplished?(context, fact)
29
+ fact_possible?(context, fact) && requirement_satisfied_for?(context, fact)
30
+ end
31
+
32
+ # Checks if dependency for the fact is satisfied
33
+ def fact_possible?(context, fact)
34
+ [* @dependencies[fact] || []].all?{ |dep| fact_accomplished?(context, dep) }
35
+ end
36
+
37
+ # Checks if requirement for the fact is satisfied (no dependency checks here)
38
+ def requirement_satisfied_for?(context, fact)
39
+ return false unless @facts.include?(fact)
40
+
41
+ case req = @requirements[fact]
42
+ when Symbol then context.send(req)
43
+ when Proc then req.arity < 1 ? req.call : req.call(context)
44
+ when NilClass then true
45
+ else raise RuntimeError, "can't check this fact - wrong requirement"
46
+ end
47
+ end
48
+
49
+ # Syntactic sugar, adds fact with its requirement and dependency. Examples:
50
+ # - def_fact(:fact)
51
+ # - def_fact(:fact, :if => :requirement)
52
+ # - def_fact(:fact => :dependency)
53
+ # - def_fact(:fact => :dependency, :if => :requirement)
54
+ def def_fact(*opt)
55
+ raise ArgumentError, "wrong number of arguments (#{opt.size} for 2)" if opt.size > 2
56
+ raise ArgumentError, "wrong number of arguments (0 for 1)" if opt.size == 0
57
+
58
+ if opt[0].is_a?(Hash)
59
+ raise ArgumentError, "wrong arguments (hash argument can only be the last one)" if opt.size > 1
60
+ hash = opt[0]
61
+ else
62
+ raise ArgumentError, "wrong arguments (second argument must be a hash)" if opt[1] && ! opt[1].is_a?(Hash)
63
+ hash = (opt[1] || {}).merge(opt[0] => nil)
64
+ end
65
+
66
+ req = hash.delete(:if)
67
+ fact = hash.keys.first
68
+ dep = hash.delete(fact)
69
+
70
+ raise ArgumentError, "wrong arguments: #{hash.keys.join(', ')}" if hash.size > 0
71
+
72
+ @requirements[fact] = req
73
+ @dependencies[fact] = dep
74
+ @facts |= [fact]
75
+ fact
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module FactChecker
4
+ VERSION = "0.0.1"
5
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require "fact_checker/base"
4
+ require "fact_checker/version"
5
+
6
+ module FactChecker
7
+ def self.included(klass)
8
+ klass.extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ def inherited(child)
13
+ child.instance_variable_set('@fact_checker', fact_checker.dup)
14
+ end
15
+
16
+ def def_fact(*opts)
17
+ fact_name = fact_checker.def_fact(*opts)
18
+ define_method(fact_name.to_s << '?') { fact_accomplished?(fact_name) }
19
+ end
20
+
21
+ def fact_checker
22
+ @fact_checker ||= FactChecker::Base.new
23
+ end
24
+ end
25
+
26
+ # Delegate methods to self.class.fact_checker
27
+ [:fact_accomplished?, :fact_possible?, :accomplished_facts, :possible_facts].each do |name|
28
+ define_method(name) { |*opts| self.class.fact_checker.send(name, self, *opts) }
29
+ end
30
+ def facts; self.class.fact_checker.facts; end
31
+ end
@@ -0,0 +1,180 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe FactChecker::Base do
6
+ describe "constructor" do
7
+ it "should accept facts, dependencies and requirements as arguments" do
8
+ fc = FactChecker::Base.new([:a, :b], {:a => :b}, {:b => :nil?})
9
+ fc.facts.should == [:a, :b]
10
+ fc.dependencies.should == {:a => :b}
11
+ fc.requirements.should == {:b => :nil?}
12
+ end
13
+ it "should use empty hash as a default for requirements" do
14
+ fc = FactChecker::Base.new([:a, :b], {:a => :b})
15
+ fc.requirements.should == {}
16
+ end
17
+ it "should use empty hash as a default for dependencies" do
18
+ fc = FactChecker::Base.new([:a, :b])
19
+ fc.dependencies.should == {}
20
+ end
21
+ it "should use empty array as a default for facts" do
22
+ fc = FactChecker::Base.new()
23
+ fc.facts.should == []
24
+ end
25
+ end
26
+
27
+ describe "#facts" do
28
+ it "should return all facts" do
29
+ fc = FactChecker::Base.new([:f1, :f2])
30
+ fc.facts.should == [:f1, :f2]
31
+ end
32
+ end
33
+
34
+ describe "#accomplished_facts" do
35
+ it "should return accomplished facts" do
36
+ fc = FactChecker::Base.new([:f1, :f2], nil, {:f2 => lambda{ false }})
37
+ fc.accomplished_facts("context").should == [:f1]
38
+ end
39
+ end
40
+
41
+ describe "#possible_facts" do
42
+ it "should return possible facts" do
43
+ fc = FactChecker::Base.new([:f1, :f2], {:f1 => :f2}, {:f2 => lambda{ false }})
44
+ fc.possible_facts("context").should == [:f2]
45
+ end
46
+ end
47
+
48
+ describe "#requirement_satisfied_for?" do
49
+ it "should return true if no requerment defined for the step" do
50
+ fc = FactChecker::Base.new([:f1])
51
+ fc.requirement_satisfied_for?(1, :f1).should be_true
52
+ end
53
+ it "should return false if fact is unknown" do
54
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => :nil?})
55
+ fc.requirement_satisfied_for?(1, :f2).should be_false
56
+ end
57
+ it "should return false if requirement is :symbol and context.symbol() == false" do
58
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => :nil?})
59
+ fc.requirement_satisfied_for?(1, :f1).should be_false
60
+ end
61
+ it "should return true if requirement is :symbol and context.symbol() == true" do
62
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => :nil?})
63
+ fc.requirement_satisfied_for?(nil, :f1).should be_true
64
+ end
65
+ it "should return false if requirement is Proc and proc(context) == false" do
66
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => lambda{|t| t.nil?}})
67
+ fc.requirement_satisfied_for?(1, :f1).should be_false
68
+ end
69
+ it "should return true if requirement is Proc and proc(context) == true" do
70
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => lambda{|t| t.nil?}})
71
+ fc.requirement_satisfied_for?(nil, :f1).should be_true
72
+ end
73
+ it "should return false if requirement is Proc with arity < 1 and proc() == false" do
74
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => lambda{false}})
75
+ fc.requirement_satisfied_for?(nil, :f1).should be_false
76
+ end
77
+ it "should return true if requirement is Proc with arity < 1 and proc() == true" do
78
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => lambda{true}})
79
+ fc.requirement_satisfied_for?(nil, :f1).should be_true
80
+ end
81
+ it "should raise RuntimeError if requirement has wrong type" do
82
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => "wrong"})
83
+ lambda{fc.requirement_satisfied_for?(nil, :f1)}.should raise_error(RuntimeError)
84
+ end
85
+ end
86
+
87
+ describe "#fact_accomplished?" do
88
+ it "should return false if fact is unknown" do
89
+ fc = FactChecker::Base.new([:f2], nil, {:f1 => :nil?})
90
+ fc.fact_accomplished?(nil, :f1).should be_false
91
+ end
92
+ it "should return true if requirement satisfied and fact has no dependencies" do
93
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => lambda{|o| o.size > 2}})
94
+ fc.fact_accomplished?("name", :f1).should be_true
95
+ end
96
+ it "should return false if requirement not satisfied (fact has no dependencies)" do
97
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => :nil?})
98
+ fc.fact_accomplished?("something", :f1).should be_false
99
+ end
100
+ it "should return false if fact has unsatisfied dependencies" do
101
+ fc = FactChecker::Base.new([:f1, :f2], {:f1 => :f2}, {:f2 => :nil?})
102
+ fc.fact_accomplished?("something", :f1).should be_false
103
+ end
104
+ it "should return false if fact has both satisfied and unsatisfied dependencies" do
105
+ fc = FactChecker::Base.new([:f1, :f2, :f3, :f4], {:f1 => [:f2, :f3], :f3 => :f4}, {:f2 => :size, :f3 => :size, :f4 => :nil?})
106
+ fc.fact_accomplished?("something", :f1).should be_false
107
+ end
108
+ it "should return true if all dependencies are satisfied and fact has no requirements" do
109
+ fc = FactChecker::Base.new([:f1, :f2, :f3, :f4], {:f1 => [:f2, :f3], :f3 => :f4}, {:f2 => :size, :f3 => :size, :f4 => :size})
110
+ fc.fact_accomplished?("something", :f1).should be_true
111
+ end
112
+ it "should return false if requirements not satisfied (all dependencies are satisfied)" do
113
+ fc = FactChecker::Base.new([:f1, :f2, :f3, :f4], {:f1 => [:f2, :f3], :f3 => :f4}, {:f1 => :nil?, :f2 => :size, :f3 => :size, :f4 => :size})
114
+ fc.fact_accomplished?("something", :f1).should be_false
115
+ end
116
+ end
117
+
118
+ describe "#fact_possible?" do
119
+ it "should return true if fact is unknown" do
120
+ fc = FactChecker::Base.new([:f2], nil, {:f1 => :nil?})
121
+ fc.fact_possible?(nil, :f1).should be_true
122
+ end
123
+ it "should return true if dependencies satisfied (even if requirement is not satisfied)" do
124
+ fc = FactChecker::Base.new([:f1], nil, {:f1 => :nil?})
125
+ fc.fact_possible?(1, :f1).should be_true
126
+ end
127
+ it "should return false if dependencies unsatisfied (even if requirement is satisfied)" do
128
+ fc = FactChecker::Base.new([:f1], {:f1 => :f2}, {:f2 => :nil?})
129
+ fc.fact_possible?(1, :f1).should be_false
130
+ end
131
+ end
132
+
133
+ describe "#def_fact" do
134
+ let(:fc) { FactChecker::Base.new }
135
+
136
+ it "should add argument to facts when called with (:fact) and return (:fact)" do
137
+ fc.def_fact(:f1).should be :f1
138
+ fc.def_fact(:f2).should be :f2
139
+ fc.facts.should == [:f1, :f2]
140
+ end
141
+
142
+ it "should define fact correctly when called with (:fact, :if => :requirement)" do
143
+ fc.def_fact(:f1)
144
+ fc.def_fact(:f2, :if => :nil?)
145
+ fc.facts.should == [:f1, :f2]
146
+ fc.requirements[:f2].should == :nil?
147
+ end
148
+
149
+ it "should define fact correctly when called with (:fact => :dependency)" do
150
+ fc.def_fact(:f1)
151
+ fc.def_fact(:f2 => :f1)
152
+ fc.facts.should == [:f1, :f2]
153
+ fc.dependencies[:f2].should == :f1
154
+ end
155
+
156
+ it "should define fact correctly when called with (:fact => :dependency, :if => :requirement)" do
157
+ fc.def_fact(:f1)
158
+ fc.def_fact(:f2 => :f1, :if => :nil?)
159
+ fc.facts.should == [:f1, :f2]
160
+ fc.dependencies[:f2].should == :f1
161
+ fc.requirements[:f2].should == :nil?
162
+ end
163
+
164
+ it "should redefine fact if a fact with a given name already exists" do
165
+ fc.def_fact(:f1 => :f2, :if => :nil?)
166
+ fc.def_fact(:f1)
167
+ fc.facts.should == [:f1]
168
+ fc.requirements[:f1].should be_nil
169
+ fc.dependencies[:f1].should be_nil
170
+ end
171
+
172
+ it "should raise ArgumentError exception when called with wrong arguments" do
173
+ expect { fc.def_fact() }.to raise_error ArgumentError
174
+ expect { fc.def_fact(:f1, {:if => :nil?}, true) }.to raise_error ArgumentError
175
+ expect { fc.def_fact(:f1, :f2) }.to raise_error ArgumentError
176
+ expect { fc.def_fact({:if => :nil?}, :f1) }.to raise_error ArgumentError
177
+ expect { fc.def_fact(:f1 => :f2, :if => :nil?, :something_else => true) }.to raise_error ArgumentError
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe FactChecker::VERSION do
6
+ it { should =~ /\A\d+\.\d+\.\d+\z/ }
7
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'FactCheckerInheritance' do
6
+ describe ChildOfClassWithFacts do
7
+ subject { ChildOfClassWithFacts }
8
+
9
+ it { should respond_to :def_fact }
10
+ its(:fact_checker) { should be_kind_of FactChecker::Base }
11
+
12
+ describe 'context for inherited facts' do
13
+ let(:target) { ChildOfClassWithFacts.new }
14
+
15
+ context 'inherited bare fact', :fact => :bare_fact do
16
+ it_behaves_like 'an accomplished fact', true
17
+ it_behaves_like 'a possible fact', true
18
+ end
19
+
20
+ context 'inherited true fact with no dependencies', :fact => :true_fact_with_no_dependencies do
21
+ it_behaves_like 'an accomplished fact', true
22
+ it_behaves_like 'a possible fact', true
23
+ end
24
+
25
+ context 'inherited true fact with true dependencies', :fact => :true_fact_with_true_dependencies do
26
+ it_behaves_like 'an accomplished fact', true
27
+ it_behaves_like 'a possible fact', true
28
+ end
29
+
30
+ context 'inherited true fact with false dependencies', :fact => :true_fact_with_false_dependencies do
31
+ it_behaves_like 'an accomplished fact', false
32
+ it_behaves_like 'a possible fact', false
33
+ end
34
+
35
+ context 'inherited false fact with no dependencies', :fact => :false_fact_with_no_dependencies do
36
+ it_behaves_like 'an accomplished fact', false
37
+ it_behaves_like 'a possible fact', true
38
+ end
39
+
40
+ context 'inherited false fact with true dependencies', :fact => :false_fact_with_true_dependencies do
41
+ it_behaves_like 'an accomplished fact', false
42
+ it_behaves_like 'a possible fact', true
43
+ end
44
+
45
+ context 'inherited false fact with false dependencies', :fact => :false_fact_with_false_dependencies do
46
+ it_behaves_like 'an accomplished fact', false
47
+ it_behaves_like 'a possible fact', false
48
+ end
49
+
50
+ specify '#facts' do
51
+ target.facts.size.should == 7
52
+ end
53
+
54
+ specify '#accomplished_facts' do
55
+ target.accomplished_facts.should == [ :bare_fact, :true_fact_with_no_dependencies, :true_fact_with_true_dependencies ]
56
+ end
57
+
58
+ specify '#possible_facts' do
59
+ target.possible_facts.should == target.facts - [ :true_fact_with_false_dependencies, :false_fact_with_false_dependencies ]
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe 'FactChecker' do
6
+ describe ClassWithNoFacts do
7
+ its(:facts) { should == [] }
8
+ its(:possible_facts) { should == [] }
9
+ its(:accomplished_facts) { should == [] }
10
+
11
+ specify '#fact_possible? and #fact_accomplished?' do
12
+ subject.fact_possible?(:unknown_fact).should be_true
13
+ subject.fact_accomplished?(:unknown_fact).should be_false
14
+ end
15
+ end
16
+
17
+ describe ClassWithFacts do
18
+ subject { ClassWithFacts }
19
+
20
+ it { should respond_to :def_fact }
21
+ its(:fact_checker) { should be_kind_of FactChecker::Base }
22
+
23
+ describe 'context for facts' do
24
+ let(:target) { ClassWithFacts.new }
25
+
26
+ context 'given bare fact', :fact => :bare_fact do
27
+ it_behaves_like 'an accomplished fact', true
28
+ it_behaves_like 'a possible fact', true
29
+ end
30
+
31
+ context 'given true fact with no dependencies', :fact => :true_fact_with_no_dependencies do
32
+ it_behaves_like 'an accomplished fact', true
33
+ it_behaves_like 'a possible fact', true
34
+ end
35
+
36
+ context 'given true fact with true dependencies', :fact => :true_fact_with_true_dependencies do
37
+ it_behaves_like 'an accomplished fact', true
38
+ it_behaves_like 'a possible fact', true
39
+ end
40
+
41
+ context 'given true fact with false dependencies', :fact => :true_fact_with_false_dependencies do
42
+ it_behaves_like 'an accomplished fact', false
43
+ it_behaves_like 'a possible fact', false
44
+ end
45
+
46
+ context 'given false fact with no dependencies', :fact => :false_fact_with_no_dependencies do
47
+ it_behaves_like 'an accomplished fact', false
48
+ it_behaves_like 'a possible fact', true
49
+ end
50
+
51
+ context 'given false fact with true dependencies', :fact => :false_fact_with_true_dependencies do
52
+ it_behaves_like 'an accomplished fact', false
53
+ it_behaves_like 'a possible fact', true
54
+ end
55
+
56
+ context 'given false fact with false dependencies', :fact => :false_fact_with_false_dependencies do
57
+ it_behaves_like 'an accomplished fact', false
58
+ it_behaves_like 'a possible fact', false
59
+ end
60
+
61
+ specify '#facts' do
62
+ target.facts.size.should == 7
63
+ end
64
+
65
+ specify '#accomplished_facts' do
66
+ target.accomplished_facts.should == [ :bare_fact, :true_fact_with_no_dependencies, :true_fact_with_true_dependencies ]
67
+ end
68
+
69
+ specify '#possible_facts' do
70
+ target.possible_facts.should == target.facts - [ :true_fact_with_false_dependencies, :false_fact_with_false_dependencies ]
71
+ end
72
+ end
73
+ end
74
+ end
data/spec/spec.rake ADDED
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ desc 'Run complete application spec suite'
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ spec_tasks = Dir['spec/*/'].map { |d| File.basename(d) }
9
+
10
+ spec_tasks.each do |folder|
11
+ RSpec::Core::RakeTask.new("spec:#{folder}") do |t|
12
+ t.pattern = "./spec/#{folder}/**/*_spec.rb"
13
+ t.rspec_opts = %w(--color)
14
+ end
15
+ end
16
+
17
+ # task 'spec' => spec_tasks.map { |f| "spec:#{f}" }
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift File.expand_path('../lib', __FILE__)
4
+ require 'fact_checker'
5
+ Dir['./spec/support/**/*.rb'].each { |f| require f }
6
+
7
+ RSpec.configure do |conf|
8
+ conf.color_enabled = true
9
+ conf.treat_symbols_as_metadata_keys_with_true_values = true
10
+
11
+ conf.expect_with :rspec, :stdlib
12
+ conf.mock_with :rspec
13
+
14
+ conf.fail_fast = true
15
+ conf.filter_run :focus => true
16
+ conf.filter_run_excluding :broken => true
17
+ conf.run_all_when_everything_filtered = true
18
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ class ClassWithNoFacts
6
+ include FactChecker
7
+ end
8
+
9
+ class ClassWithFacts
10
+ include FactChecker
11
+
12
+ def_fact :bare_fact
13
+ def_fact :true_fact_with_no_dependencies, :if => lambda { true }
14
+ def_fact :true_fact_with_true_dependencies => :bare_fact, :if => lambda { true }
15
+ def_fact :true_fact_with_false_dependencies => :false_fact_with_no_dependencies, :if => lambda { true }
16
+ def_fact :false_fact_with_no_dependencies, :if => lambda { false }
17
+ def_fact :false_fact_with_true_dependencies => :bare_fact , :if => lambda { false }
18
+ def_fact :false_fact_with_false_dependencies => :false_fact_with_no_dependencies , :if => lambda { false }
19
+ end
20
+
21
+ class ChildOfClassWithFacts < ClassWithFacts
22
+ end
23
+
24
+ # :another_fact should not creep back to parent classes
25
+ class GrandChildOfClassWithFacts < ChildOfClassWithFacts
26
+ def_fact :another_fact
27
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ shared_examples 'an accomplished fact' do |true_or_false|
4
+ specify '#fact_accomplished?' do
5
+ target.fact_accomplished?(example.metadata[:fact]).should be true_or_false
6
+ end
7
+
8
+ specify '#(:fact)? predicate' do
9
+ target.send("#{example.metadata[:fact]}?").should be true_or_false
10
+ end
11
+ end
12
+
13
+ shared_examples 'a possible fact' do |true_or_false|
14
+ specify '#fact_possible?' do
15
+ target.fact_possible?(example.metadata[:fact]).should be true_or_false
16
+ end
17
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fact_checker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alexey Smolianinov
9
+ - Ivan Povalyukhin
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2011-10-31 00:00:00.000000000 +04:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ requirement: &84896850 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: '2.6'
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: *84896850
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: &84896660 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *84896660
38
+ - !ruby/object:Gem::Dependency
39
+ name: bundler
40
+ requirement: &84896430 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *84896430
49
+ description: Simple gem to check hierarchically dependent "facts" about objects
50
+ email:
51
+ - alexisowl+fact_checker@gmail.com
52
+ executables: []
53
+ extensions: []
54
+ extra_rdoc_files: []
55
+ files:
56
+ - .gitignore
57
+ - .rvmrc
58
+ - Gemfile
59
+ - README
60
+ - Rakefile
61
+ - examples/README.md
62
+ - examples/basic.rb
63
+ - fact_checker.gemspec
64
+ - lib/fact_checker.rb
65
+ - lib/fact_checker/base.rb
66
+ - lib/fact_checker/version.rb
67
+ - spec/fact_checker/base_spec.rb
68
+ - spec/fact_checker/version_spec.rb
69
+ - spec/fact_checker_inheritance_spec.rb
70
+ - spec/fact_checker_spec.rb
71
+ - spec/spec.rake
72
+ - spec/spec_helper.rb
73
+ - spec/support/classes_with_facts.rb
74
+ - spec/support/shared_facts_behaviour.rb
75
+ has_rdoc: true
76
+ homepage: https://github.com/alexis/fact_checker
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: 1.8.7
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.5
94
+ requirements: []
95
+ rubyforge_project: fact_checker
96
+ rubygems_version: 1.6.2
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Checks facts which may depend on other facts
100
+ test_files: []