Commit 34b873d

mo khan <mo@mokhan.ca>
2013-12-27 17:32:08
add block specification.
1 parent a3e6760
lib/nasty/block_specification.rb
@@ -0,0 +1,35 @@
+module Nasty
+  module Specification
+    def or(other_predicate = nil, &block)
+      matcher = create_predicate(other_predicate, &block)
+      create_predicate { |item| self.matches?(item) || matcher.matches?(item) }
+    end
+
+    def and(other_predicate = nil, &block)
+      matcher = create_predicate(other_predicate, &block)
+      create_predicate { |item| self.matches?(item) && matcher.matches?(item) }
+    end
+
+    def not
+      create_predicate { |item| !self.matches?(item) }
+    end
+
+    private
+
+    def create_predicate(predicate = nil, &block)
+      block_given? ? Nasty::BlockSpecification.new(&block) : predicate
+    end
+  end
+
+  class BlockSpecification
+    include Nasty::Specification
+
+    def initialize(&block)
+      @block = block
+    end
+
+    def matches?(item)
+      @block.call(item)
+    end
+  end
+end
lib/nasty.rb
@@ -1,11 +1,12 @@
 require "nasty/background_job"
+require "nasty/block_specification"
 require "nasty/command"
 require "nasty/composite_command"
 require "nasty/expose_binding"
 require "nasty/kernel"
+require "nasty/lambda_behaviours"
 require "nasty/log"
 require "nasty/object"
-require "nasty/lambda_behaviours"
 require "nasty/version"
 
 module Nasty
spec/unit/block_specification_spec.rb
@@ -0,0 +1,100 @@
+require 'spec_helper'
+
+module Nasty
+  describe BlockSpecification do
+    let(:sut) { BlockSpecification.new { |item| item == true } }
+
+    context "when an item matches" do
+      it "should return true" do
+        sut.matches?(true).should be_true
+      end
+    end
+
+    context "when an item does not match" do
+      it "should return true" do
+        sut.matches?(false).should be_false
+      end
+    end
+
+    describe "or" do
+      context "when one item matches" do
+        it "should return true" do
+          sut.or(BlockSpecification.new {|x| x == false} ).matches?(false).should be_true
+        end
+        it "should return true" do
+          sut.or {|x| x == false} .matches?(false).should be_true
+        end
+      end
+
+      context "when the other item matches" do
+        it "should return true" do
+          sut.or(BlockSpecification.new {|x| x == false} ).matches?(true).should be_true
+        end
+        it "should return true" do
+          sut.or {|x| x == false} .matches?(true).should be_true
+        end
+      end
+
+      context "when neither item matches" do
+        it "should return false" do
+          sut.or(BlockSpecification.new {|x| x == true}).matches?(false).should be_false
+        end
+        it "should return false" do
+          sut.or {|x| x == true}.matches?(false).should be_false
+        end
+      end
+    end
+
+    describe "and" do
+      context "when one item matches" do
+        it "should return false" do
+          sut.and(BlockSpecification.new {|x| x == false} ).matches?(false).should be_false
+        end
+        it "should return false" do
+          sut.and {|x| x == false} .matches?(false).should be_false
+        end
+      end
+
+      context "when the other item matches" do
+        it "should return false" do
+          sut.and(BlockSpecification.new {|x| x == false} ).matches?(true).should be_false
+        end
+        it "should return false" do
+          sut.and {|x| x == false} .matches?(true).should be_false
+        end
+      end
+
+      context "when neither item matches" do
+        it "should return false" do
+          sut.and(BlockSpecification.new {|x| x == true}).matches?(false).should be_false
+        end
+        it "should return false" do
+          sut.and {|x| x == true}.matches?(false).should be_false
+        end
+      end
+
+      context "when both items match" do
+        it "should return true" do
+          sut.and(BlockSpecification.new {|x| x == true}).matches?(true).should be_true
+        end
+        it "should return true" do
+          sut.and {|x| x == true}.matches?(true).should be_true
+        end
+      end
+    end
+
+    describe "not" do
+      context "when an item matches" do
+        it "should return false" do
+          sut.not.matches?(true).should be_false
+        end
+      end
+
+      context "when an item does not match" do
+        it "should return true" do
+          sut.not.matches?(false).should be_true
+        end
+      end
+    end
+  end
+end