Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 2 commits
  • 23 files changed
  • 0 commit comments
  • 1 contributor
View
3 .gitignore
@@ -0,0 +1,3 @@
+coverage
+rdoc
+pkg
View
22 LICENSE
@@ -0,0 +1,22 @@
+The MIT License
+
+Copyright (c) 2011 Annkissam
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
33 README.rdoc
@@ -0,0 +1,33 @@
+= acts_as_span
+
+ActiveRecord model w/ a start_date and an end_date
+
+== Getting Started
+
+In your Gemfile:
+
+ gem "appraisal"
+
+In your model:
+
+ class SpanRecord < ActiveRecord::Base
+ acts_as_span
+ end
+
+In your migrations:
+
+ class AddSpanToSpanRecord < ActiveRecord::Migration
+ def self.up
+ add_column :span_records, :start_date, :date
+ add_column :span_records, :end_date, :date
+ end
+
+ def self.down
+ remove_column :span_records, :start_date
+ remove_column :span_records, :end_date
+ end
+ end
+
+== Copyright
+
+Copyright (c) 2011 Annkissam. See LICENSE for details.
View
56 lib/acts_as_span.rb
@@ -5,7 +5,8 @@
ACTS_AS_SPAN_PATH = File.dirname(__FILE__) + "/acts_as_span/"
require ACTS_AS_SPAN_PATH + 'version'
-require ACTS_AS_SPAN_PATH + 'span'
+require ACTS_AS_SPAN_PATH + 'span_klass'
+require ACTS_AS_SPAN_PATH + 'span_instance'
module ActsAsSpan
extend ActiveSupport::Concern
@@ -42,7 +43,7 @@ def acts_as_span(*args)
self.send(:extend, Forwardable)
- self.send(:extend, ActsAsSpan::Scopes)
+ self.send(:extend, ActsAsSpan::ExtendedClassMethods)
self.send(:include, ActsAsSpan::IncludedInstanceMethods)
options = OpenStruct.new(args.last.is_a?(Hash) ? ActsAsSpan.options.merge(args.pop) : ActsAsSpan.options)
@@ -57,8 +58,27 @@ def acts_as_span(*args)
:span_status,
:span_status_on,
:span_status_to_s,
- :span_status_to_s_on
+ :span_status_to_s_on,
+ :current?,
+ :current_on?,
+ :future?,
+ :future_on?,
+ :expired?,
+ :expired_on?
+ def_delegators 'self.class', :acts_as_span_definitions
+
+ class << self
+ self.send(:extend, Forwardable)
+
+ def_delegators :span, :current,
+ :current_on,
+ :future,
+ :future_on,
+ :expired,
+ :expired_on
+ end
+
validate :validate_spans
end
@@ -67,33 +87,49 @@ def acts_as_span_definitions
end
end
- module Scopes
+ module ExtendedClassMethods
def overlap(test_record)
overlap_for(test_record, :default, :default)
end
def overlap_for(test_record, test_record_span_name = :default, this_span_name = :default)
- test_record.span_for(test_record_span_name).overlap(self, this_span_name)
+ span_for(this_span_name).overlap(test_record.span_for(test_record_span_name))
+ end
+
+ def spans
+ acts_as_span_definitions.keys.map { |acts_as_span_definition_name| span_for(acts_as_span_definition_name) }
+ end
+
+ def span
+ span_for(:default)
+ end
+
+ def span_for(name = :default)
+ acts_as_span_klasses[name] ||= SpanKlass.new(name, self, acts_as_span_definitions[name])
+ end
+
+ def acts_as_span_klasses
+ @_acts_as_span_klasses ||= {}
end
end
module IncludedInstanceMethods
+ def spans
+ acts_as_span_definitions.keys.map { |acts_as_span_definition_name| span_for(acts_as_span_definition_name) }
+ end
+
def span
span_for(:default)
end
def span_for(name = :default)
- acts_as_span_instances[name] ||= Span.new(name, self, self.class.acts_as_span_definitions[name])
+ acts_as_span_instances[name] ||= SpanInstance.new(name, self, acts_as_span_definitions[name])
end
def acts_as_span_instances
@_acts_as_span_instances ||= {}
end
- def spans
- self.class.acts_as_span_definitions.keys.map { |acts_as_span_definition| span_for(acts_as_span_definition) }
- end
-
def validate_spans
spans.each(&:validate)
end
View
94 lib/acts_as_span/span.rb
@@ -1,94 +0,0 @@
-require 'forwardable'
-
-require ACTS_AS_SPAN_PATH + 'span/validations'
-
-module ActsAsSpan
- class Span
- extend Forwardable
-
- include ActsAsSpan::Span::Validations
-
- def_delegators :@acts_as_span_definition, :start_date_field,
- :end_date_field,
- :start_date_field_required,
- :end_date_field_required,
- :exclude_end,
- :span_overlap_scope,
- :span_overlap_count
-
- attr_reader :name, :span_model, :acts_as_span_definition
-
- def initialize(name, span_model, acts_as_span_definition)
- @name = name
- @span_model = span_model
- @acts_as_span_definition = acts_as_span_definition
- end
-
- def span_klass
- @span_klass ||= span_model.class
- end
-
- def start_date
- span_model[start_date_field]
- end
-
- def end_date
- span_model[end_date_field]
- end
-
- def close!(close_date = Date.today)
- if end_date.blank?
- span_model.update_attributes!(end_date_field => close_date)
- end
- end
-
- alias_method :close_on!, :close!
-
- def span_status(query_date = Date.today)
- if future?(query_date)
- :future
- elsif expired?(query_date)
- :expired
- elsif current?(query_date)
- :current
- else
- :unknown
- end
- end
-
- alias_method :span_status_on, :span_status
-
- def span_status_to_s(query_date = Date.today)
- case span_status(query_date)
- when :future
- "Future"
- when :expired
- "Expired"
- when :current
- "Current"
- when :unknown
- "Unknown"
- end
- end
-
- alias_method :span_status_to_s_on, :span_status_to_s
-
- #http://stackoverflow.com/questions/699448/ruby-how-do-you-check-whether-a-range-contains-a-subset-of-another-range
- #start_date <= record_end_date && record_start_date <= end_date
- def overlap?(other_span)
- (start_date.nil? || other_span.end_date.nil? || start_date <= other_span.end_date) && (end_date.nil? || other_span.start_date.nil? || other_span.start_date <= end_date)
- end
-
- def overlap(span_class = span_klass, span_class_span_name = :default)
- span_class_span_definition = span_class.acts_as_span_definitions[span_class_span_name]
-
- span_class_overlap_scope = span_class.where( ["(#{span_class.table_name}.#{span_class_span_definition.start_date_field} IS NULL OR :end_date IS NULL OR #{span_class.table_name}.#{span_class_span_definition.start_date_field} <= :end_date) AND (#{span_class.table_name}.#{span_class_span_definition.end_date_field} IS NULL OR :start_date IS NULL OR :start_date <= #{span_class.table_name}.#{span_class_span_definition.end_date_field})", { :start_date => start_date, :end_date => end_date } ] )
-
- if !span_model.new_record? && span_klass == span_class
- span_class_overlap_scope.where( ["#{span_class.table_name}.id != :id", { :id => span_model.id } ] )
- end
-
- span_class_overlap_scope
- end
- end
-end
View
53 lib/acts_as_span/span_instance.rb
@@ -0,0 +1,53 @@
+require 'forwardable'
+
+require ACTS_AS_SPAN_PATH + 'span_instance/validations'
+require ACTS_AS_SPAN_PATH + 'span_instance/status'
+require ACTS_AS_SPAN_PATH + 'span_instance/overlap'
+
+module ActsAsSpan
+ class SpanInstance
+ extend Forwardable
+
+ include ActsAsSpan::SpanInstance::Validations
+ include ActsAsSpan::SpanInstance::Status
+ include ActsAsSpan::SpanInstance::Overlap
+
+ def_delegators :@acts_as_span_definition, :start_date_field,
+ :end_date_field,
+ :start_date_field_required,
+ :end_date_field_required,
+ :exclude_end,
+ :span_overlap_scope,
+ :span_overlap_count
+
+ def_delegators :span_model, :new_record?
+
+ attr_reader :name, :span_model, :acts_as_span_definition
+
+ def initialize(name, span_model, acts_as_span_definition)
+ @name = name
+ @span_model = span_model
+ @acts_as_span_definition = acts_as_span_definition
+ end
+
+ def span_klass
+ @span_klass ||= span_model.class
+ end
+
+ def start_date
+ span_model[start_date_field]
+ end
+
+ def end_date
+ span_model[end_date_field]
+ end
+
+ def close!(close_date = Date.today)
+ if end_date.blank?
+ span_model.update_attributes!(end_date_field => close_date)
+ end
+ end
+
+ alias_method :close_on!, :close!
+ end
+end
View
17 lib/acts_as_span/span_instance/overlap.rb
@@ -0,0 +1,17 @@
+require 'active_support'
+
+module ActsAsSpan
+ class SpanInstance
+ module Overlap
+ extend ActiveSupport::Concern
+
+ module InstanceMethods
+ #http://stackoverflow.com/questions/699448/ruby-how-do-you-check-whether-a-range-contains-a-subset-of-another-range
+ #start_date <= record_end_date && record_start_date <= end_date
+ def overlap?(other_span)
+ (start_date.nil? || other_span.end_date.nil? || start_date <= other_span.end_date) && (end_date.nil? || other_span.start_date.nil? || other_span.start_date <= end_date)
+ end
+ end
+ end
+ end
+end
View
58 lib/acts_as_span/span_instance/status.rb
@@ -0,0 +1,58 @@
+require 'active_support'
+
+module ActsAsSpan
+ class SpanInstance
+ module Status
+ extend ActiveSupport::Concern
+
+ module InstanceMethods
+ def span_status(query_date = Date.today)
+ if future?(query_date)
+ :future
+ elsif expired?(query_date)
+ :expired
+ elsif current?(query_date)
+ :current
+ else
+ :unknown
+ end
+ end
+
+ alias_method :span_status_on, :span_status
+
+ def span_status_to_s(query_date = Date.today)
+ case span_status(query_date)
+ when :future
+ "Future"
+ when :expired
+ "Expired"
+ when :current
+ "Current"
+ when :unknown
+ "Unknown"
+ end
+ end
+
+ alias_method :span_status_to_s_on, :span_status_to_s
+
+ def current?(query_date = Date.today)
+ !future?(query_date) && !expired?(query_date)
+ end
+
+ alias_method :current_on?, :current?
+
+ def future?(query_date = Date.today)
+ start_date && start_date > query_date
+ end
+
+ alias_method :future_on?, :future?
+
+ def expired?(query_date = Date.today)
+ end_date && end_date < query_date
+ end
+
+ alias_method :expired_on?, :expired?
+ end
+ end
+ end
+end
View
6 lib/acts_as_span/span/validations.rb → ...acts_as_span/span_instance/validations.rb
@@ -1,7 +1,7 @@
require 'active_support'
module ActsAsSpan
- class Span
+ class SpanInstance
module Validations
extend ActiveSupport::Concern
@@ -43,7 +43,7 @@ def validate_overlap
conditions[span_overlap_scope] = span_model.send(span_overlap_scope)
end
- records = overlap(span_klass, name).where(conditions)
+ records = span_klass.span_for(name).overlap(self).where(conditions)
if span_klass.respond_to?('not_archived')
records.not_archived
@@ -57,7 +57,7 @@ def validate_overlap
#end
if records.count > span_overlap_count
- span_model.errors.add(:base, "date range overlaps with #{records.count} other record(s)\n#{overlap.to_sql}")
+ span_model.errors.add(:base, "date range overlaps with #{records.count} other record(s)")
end
end
end
View
31 lib/acts_as_span/span_klass.rb
@@ -0,0 +1,31 @@
+require 'forwardable'
+
+require ACTS_AS_SPAN_PATH + 'span_klass/status'
+require ACTS_AS_SPAN_PATH + 'span_klass/overlap'
+
+module ActsAsSpan
+ class SpanKlass
+ extend Forwardable
+
+ include ActsAsSpan::SpanKlass::Status
+ include ActsAsSpan::SpanKlass::Overlap
+
+ def_delegators :@acts_as_span_definition, :start_date_field,
+ :end_date_field,
+ :start_date_field_required,
+ :end_date_field_required,
+ :exclude_end,
+ :span_overlap_scope,
+ :span_overlap_count
+
+ def_delegators :klass, :table_name
+
+ attr_reader :name, :klass, :acts_as_span_definition
+
+ def initialize(name, klass, acts_as_span_definition)
+ @name = name
+ @klass = klass
+ @acts_as_span_definition = acts_as_span_definition
+ end
+ end
+end
View
21 lib/acts_as_span/span_klass/overlap.rb
@@ -0,0 +1,21 @@
+require 'active_support'
+
+module ActsAsSpan
+ class SpanKlass
+ module Overlap
+ extend ActiveSupport::Concern
+
+ module InstanceMethods
+ def overlap(test_span)
+ overlap_scope = klass.where( ["(#{table_name}.#{start_date_field} IS NULL OR :end_date IS NULL OR #{table_name}.#{start_date_field} <= :end_date) AND (#{table_name}.#{end_date_field} IS NULL OR :start_date IS NULL OR :start_date <= #{table_name}.#{end_date_field})", { :start_date => test_span.start_date, :end_date => test_span.end_date } ] )
+
+ if !test_span.new_record? && test_span.span_klass == klass
+ overlap_scope.where( ["#{table_name}.id != :id", { :id => test_span.id } ] )
+ end
+
+ overlap_scope
+ end
+ end
+ end
+ end
+end
View
29 lib/acts_as_span/span_klass/status.rb
@@ -0,0 +1,29 @@
+require 'active_support'
+
+module ActsAsSpan
+ class SpanKlass
+ module Status
+ extend ActiveSupport::Concern
+
+ module InstanceMethods
+ def current(query_date = Date.today)
+ klass.where(["(#{table_name}.#{start_date_field} <= :query_date OR #{table_name}.#{start_date_field} IS NULL) AND (#{table_name}.#{end_date_field} >= :query_date OR #{table_name}.#{end_date_field} IS NULL)", { :query_date => query_date } ] )
+ end
+
+ alias_method :current_on, :current
+
+ def future(query_date = Date.today)
+ klass.where(["#{table_name}.#{start_date_field} > :query_date", { :query_date => query_date } ] )
+ end
+
+ alias_method :future_on, :future
+
+ def expired(query_date = Date.today)
+ klass.where(["#{table_name}.#{end_date_field} < :query_date", { :query_date => query_date } ] )
+ end
+
+ alias_method :expired_on, :expired
+ end
+ end
+ end
+end
View
32 spec/lib/span_model/acts_as_span_spec.rb → spec/lib/acts_as_span_spec.rb
@@ -7,7 +7,7 @@
end
end
- context "SpanModel (Class)" do
+ context "ClassMethods" do
it "should return true for acts_as_span?" do
SpanModel.acts_as_span?.should be_true
end
@@ -28,33 +28,37 @@
span_definition.span_overlap_count.should be_nil
span_definition.name.should == :default
end
+
+ it "should return a SpanKlass w/ span" do
+ SpanModel.span.should be_instance_of(ActsAsSpan::SpanKlass)
+ end
+
+ it "should return a SpanKlass w/ span_for(:default)" do
+ SpanModel.span_for(:default).should be_instance_of(ActsAsSpan::SpanKlass)
+ end
+
+ it "should have (1) spans" do
+ SpanModel.spans.should have(1).span
+ end
end
- context "SpanModel (Instance)" do
+ context "InstanceMethods" do
let(:span_model) { SpanModel.new }
it "should return true for acts_as_span?" do
span_model.acts_as_span?.should be_true
end
-
- #it "should have 1 acts_as_span_instance" do
- # span_model.should have(1).acts_as_span_instances
- #end
- it "should return a Span w/ span" do
- span_model.span.should be_instance_of(ActsAsSpan::Span)
+ it "should return a SpanInstance w/ span" do
+ span_model.span.should be_instance_of(ActsAsSpan::SpanInstance)
end
- it "should return a Span w/ span_for(:default)" do
- span_model.span_for(:default).should be_instance_of(ActsAsSpan::Span)
+ it "should return a SpanInstance w/ span_for(:default)" do
+ span_model.span_for(:default).should be_instance_of(ActsAsSpan::SpanInstance)
end
it "should have (1) spans" do
span_model.spans.should have(1).span
end
-
- #NOTE: This is (indirectly) tested in span/validate_span
- #it "should validate_spans" do
- #end
end
end
View
128 spec/lib/delegation_spec.rb
@@ -0,0 +1,128 @@
+require 'spec_helper'
+
+describe "Span" do
+ before(:each) do
+ build_model :span_model do
+ date :start_date
+ date :end_date
+
+ acts_as_span
+ end
+ end
+
+ let(:span_model) { SpanModel.new(:start_date => Date.today, :end_date => nil) }
+ let(:span_klass) { SpanModel.span }
+ let(:span_instance) { span_model.span }
+
+ context "ClassMethods" do
+ it "should delegate current" do
+ span_klass.should_receive(:current).and_return(true)
+
+ SpanModel.current
+ end
+
+ it "should delegate current_on" do
+ span_klass.should_receive(:current_on).and_return(true)
+
+ SpanModel.current_on
+ end
+
+ it "should delegate future" do
+ span_klass.should_receive(:future).and_return(true)
+
+ SpanModel.future
+ end
+
+ it "should delegate future_on" do
+ span_klass.should_receive(:future_on).and_return(true)
+
+ SpanModel.future_on
+ end
+
+ it "should delegate expired" do
+ span_klass.should_receive(:expired).and_return(true)
+
+ SpanModel.expired
+ end
+
+ it "should delegate expired_on" do
+ span_klass.should_receive(:expired_on).and_return(true)
+
+ SpanModel.expired_on
+ end
+ end
+
+ context "InstanceMethods" do
+ it "should delegate close!" do
+ span_instance.should_receive(:close!).and_return(true)
+
+ span_model.close!
+ end
+
+ it "should delegate close_on!" do
+ span_instance.should_receive(:close_on!).and_return(true)
+
+ span_model.close_on!
+ end
+
+ it "should delegate span_status" do
+ span_instance.should_receive(:span_status).and_return(true)
+
+ span_model.span_status
+ end
+
+ it "should delegate span_status_on" do
+ span_instance.should_receive(:span_status_on).and_return(true)
+
+ span_model.span_status_on
+ end
+
+ it "should delegate span_status_to_s" do
+ span_instance.should_receive(:span_status_to_s).and_return(true)
+
+ span_model.span_status_to_s
+ end
+
+ it "should delegate span_status_to_s_on" do
+ span_instance.should_receive(:span_status_to_s_on).and_return(true)
+
+ span_model.span_status_to_s_on
+ end
+
+ it "should delegate current?" do
+ span_instance.should_receive(:current?).and_return(true)
+
+ span_model.current?
+ end
+
+ it "should delegate current_on?" do
+ span_instance.should_receive(:current_on?).and_return(true)
+
+ span_model.current_on?
+ end
+
+ it "should delegate future?" do
+ span_instance.should_receive(:future?).and_return(true)
+
+ span_model.future?
+ end
+
+ it "should delegate future_on?" do
+ span_instance.should_receive(:future_on?).and_return(true)
+
+ span_model.future_on?
+ end
+
+ it "should delegate expired?" do
+ span_instance.should_receive(:expired?).and_return(true)
+
+ span_model.expired?
+ end
+
+ it "should delegate expired_on?" do
+ span_instance.should_receive(:expired_on?).and_return(true)
+
+ span_model.expired_on?
+ end
+ end
+end
View
0 spec/lib/span_model/negative_spec.rb → spec/lib/negative_spec.rb
File renamed without changes.
View
26 spec/lib/span/span_spec.rb
@@ -1,26 +0,0 @@
-require 'spec_helper'
-
-#NOTE: we're also testing :start_date_field & :end_date_field options work
-
-describe "Span" do
- before(:each) do
- build_model :span_model do
- date :start_date_x
- date :end_date_x
-
- acts_as_span :start_date_field => :start_date_x,
- :end_date_field => :end_date_x
- end
- end
-
- let(:span_model) { SpanModel.new(:start_date_x => Date.today, :end_date_x => Date.today + 1) }
- let(:span) { span_model.span }
-
- it "should return the start_date" do
- span.start_date.should == span_model.start_date_x
- end
-
- it "should return the end_date" do
- span.end_date.should == span_model.end_date_x
- end
-end
View
304 spec/lib/span_instance/named_scopes_on_spec.rb
@@ -0,0 +1,304 @@
+require 'spec_helper'
+
+describe "a basic model using acts_as_span" do
+ before(:all) do
+ build_model :span_model do
+ string :description
+ date :start_date
+ date :end_date
+
+ acts_as_span
+ end
+
+ @query_date = Date.today + 1.month
+ end
+
+ context "named_scopes and current_on?, expired_on?, and future_on?" do
+ # -2 -1 Q +1 +2 C F E
+ # A |---| E
+ # B |-------| C
+ # C |--------------| C
+ # D | C
+ # E |------| C
+ # F |--| F
+ # G |-> C
+ # H |-> C
+ # I |-> F
+ # J <-| E
+ # K <-| C
+ # L <-| C
+ # M <-> C
+ context "A) start_date < query_date & end_date < query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date - 2.days, :end_date => @query_date - 1.day)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current_on(@query_date).should_not include(@span_model)
+ @span_model.current_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should be included in #expired" do
+ SpanModel.expired_on(@query_date).should include(@span_model)
+ @span_model.expired_on?(@query_date).should be_true
+ end
+ end
+
+ context "B) start_date < query_date & end_date == query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date - 2.day, :end_date => @query_date)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "C) start_date < query_date & end_date > query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date - 2.day, :end_date => @query_date + 2.day)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "D) start_date == query_date & end_date == query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date, :end_date => @query_date)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "E) start_date == query_date & end_date > query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date, :end_date => @query_date + 2.day)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "F) start_date > query_date & end_date > query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date + 1.day, :end_date => @query_date + 2.days)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current_on(@query_date).should_not include(@span_model)
+ @span_model.current_on?(@query_date).should be_false
+ end
+
+ it "should be included in #future" do
+ SpanModel.future_on(@query_date).should include(@span_model)
+ @span_model.future_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "G) start_date < query_date & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date - 2.day, :end_date => nil)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "H) start_date == query_date & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date, :end_date => nil)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "I) start_date > query_date & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => @query_date + 1.day, :end_date => nil)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current_on(@query_date).should_not include(@span_model)
+ @span_model.current_on?(@query_date).should be_false
+ end
+
+ it "should be included in #future" do
+ SpanModel.future_on(@query_date).should include(@span_model)
+ @span_model.future_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "J) start_date == nil & end_date < query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => @query_date - 1.day)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current_on(@query_date).should_not include(@span_model)
+ @span_model.current_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should be included in #expired" do
+ SpanModel.expired_on(@query_date).should include(@span_model)
+ @span_model.expired_on?(@query_date).should be_true
+ end
+ end
+
+ context "K) start_date == nil & end_date == query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => @query_date)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "L) start_date == nil & end_date > query_date" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => @query_date + 2.day)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+
+ context "M) start_date == nil & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => nil)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current_on(@query_date).should include(@span_model)
+ @span_model.current_on?(@query_date).should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future_on(@query_date).should_not include(@span_model)
+ @span_model.future_on?(@query_date).should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired_on(@query_date).should_not include(@span_model)
+ @span_model.expired_on?(@query_date).should be_false
+ end
+ end
+ end
+end
View
302 spec/lib/span_instance/named_scopes_spec.rb
@@ -0,0 +1,302 @@
+require 'spec_helper'
+
+describe "a basic model using acts_as_span" do
+ before(:all) do
+ build_model :span_model do
+ string :description
+ date :start_date
+ date :end_date
+
+ acts_as_span
+ end
+ end
+
+ context "named_scopes and current?, expired?, and future?" do
+ # -2 -1 T +1 +2 C F E
+ # A |---| E
+ # B |-------| C
+ # C |--------------| C
+ # D | C
+ # E |------| C
+ # F |--| F
+ # G |-> C
+ # H |-> C
+ # I |-> F
+ # J <-| E
+ # K <-| C
+ # L <-| C
+ # M <-> C
+ context "A) start_date < today & end_date < today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today - 2.days, :end_date => Date.today - 1.day)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current.should_not include(@span_model)
+ @span_model.current?.should be_false
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should be included in #expired" do
+ SpanModel.expired.should include(@span_model)
+ @span_model.expired?.should be_true
+ end
+ end
+
+ context "B) start_date < today & end_date == today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today - 2.day, :end_date => Date.today)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "C) start_date < today & end_date > today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today - 2.day, :end_date => Date.today + 2.day)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "D) start_date == today & end_date == today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today, :end_date => Date.today)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "E) start_date == today & end_date > today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today, :end_date => Date.today + 2.day)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "F) start_date > today & end_date > today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today + 1.day, :end_date => Date.today + 2.days)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current.should_not include(@span_model)
+ @span_model.current?.should be_false
+ end
+
+ it "should be included in #future" do
+ SpanModel.future.should include(@span_model)
+ @span_model.future?.should be_true
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "G) start_date < today & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today - 2.day, :end_date => nil)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "H) start_date == today & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today, :end_date => nil)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "I) start_date > today & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => Date.today + 1.day, :end_date => nil)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current.should_not include(@span_model)
+ @span_model.current?.should be_false
+ end
+
+ it "should be included in #future" do
+ SpanModel.future.should include(@span_model)
+ @span_model.future?.should be_true
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "J) start_date == nil & end_date < today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => Date.today - 1.day)
+ end
+
+ it "should NOT be included in #current" do
+ SpanModel.current.should_not include(@span_model)
+ @span_model.current?.should be_false
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should be included in #expired" do
+ SpanModel.expired.should include(@span_model)
+ @span_model.expired?.should be_true
+ end
+ end
+
+ context "K) start_date == nil & end_date == today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => Date.today)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "L) start_date == nil & end_date > today" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => Date.today + 2.day)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+
+ context "M) start_date == nil & end_date == nil" do
+ before(:all) do
+ @span_model = SpanModel.create!(:start_date => nil, :end_date => nil)
+ end
+
+ it "should be included in #current" do
+ SpanModel.current.should include(@span_model)
+ @span_model.current?.should be_true
+ end
+
+ it "should NOT be included in #future" do
+ SpanModel.future.should_not include(@span_model)
+ @span_model.future?.should be_false
+ end
+
+ it "should NOT be included in #expired" do
+ SpanModel.expired.should_not include(@span_model)
+ @span_model.expired?.should be_false
+ end
+ end
+ end
+end
View
0 spec/lib/span/overlap_spec.rb → spec/lib/span_instance/overlap_spec.rb
File renamed without changes.
View
10 spec/lib/span/span_status_spec.rb → spec/lib/span_instance/status_spec.rb
@@ -46,14 +46,4 @@
span.span_status_to_s.should == 'Expired'
end
end
-
- context "#close!" do
- it "should set end_date? to today" do
- lambda { span.close! }.should change(span_model, :end_date).from(nil).to(Date.today)
- end
-
- it "should set end_date? to the parameter" do
- lambda { span.close_on!(Date.today + 1.day) }.should change(span_model, :end_date).from(nil).to(Date.today + 1.day)
- end
- end
end
View
2 spec/lib/span/validations_spec.rb → spec/lib/span_instance/validations_spec.rb
@@ -37,7 +37,7 @@
end
it "should require an end_date" do
- span_model = SpanModel.new(:start_date => Date.today, :end_date => nil)
+ span_model = SpanModel.new(:start_date => Date.today, :end_date => nil)
span_model.should_not be_valid
span_model.errors[:end_date].should have(1).error
View
41 spec/lib/span_instance_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+#NOTE: we're also testing :start_date_field & :end_date_field options work
+
+describe "Span" do
+ before(:each) do
+ build_model :span_model do
+ date :start_date_x
+ date :end_date_x
+
+ acts_as_span :start_date_field => :start_date_x,
+ :end_date_field => :end_date_x
+ end
+ end
+
+ context "#close!" do
+ let(:span_model) { SpanModel.new(:start_date_x => Date.today, :end_date_x => nil) }
+ let(:span) { span_model.span }
+
+ it "should set end_date? to today" do
+ lambda { span.close! }.should change(span_model, :end_date_x).from(nil).to(Date.today)
+ end
+
+ it "should set end_date? to the parameter" do
+ lambda { span.close_on!(Date.today + 1.day) }.should change(span_model, :end_date_x).from(nil).to(Date.today + 1.day)
+ end
+ end
+
+ context "start_date & end_date" do
+ let(:span_model) { SpanModel.new(:start_date_x => Date.today, :end_date_x => Date.today + 1) }
+ let(:span) { span_model.span }
+
+ it "should return the start_date" do
+ span.start_date.should == span_model.start_date_x
+ end
+
+ it "should return the end_date" do
+ span.end_date.should == span_model.end_date_x
+ end
+ end
+end
View
51 spec/lib/span_model/delegation_spec.rb
@@ -1,51 +0,0 @@
-require 'spec_helper'
-
-describe "Span" do
- before(:each) do
- build_model :span_model do
- date :start_date
- date :end_date
-
- acts_as_span
- end
- end
-
- let(:span_model) { SpanModel.new(:start_date => Date.today, :end_date => nil) }
- let(:span) { span_model.span }
-
- it "should delegate close!" do
- span.should_receive(:close!).and_return(true)
-
- span_model.close!
- end
-
- it "should delegate close_on!" do
- span.should_receive(:close_on!).and_return(true)
-
- span_model.close_on!
- end
-
- it "should delegate span_status" do
- span.should_receive(:span_status).and_return(true)
-
- span_model.span_status
- end
-
- it "should delegate span_status_on" do
- span.should_receive(:span_status_on).and_return(true)
-
- span_model.span_status_on
- end
-
- it "should delegate span_status_to_s" do
- span.should_receive(:span_status_to_s).and_return(true)
-
- span_model.span_status_to_s
- end
-
- it "should delegate span_status_to_s_on" do
- span.should_receive(:span_status_to_s_on).and_return(true)
-
- span_model.span_status_to_s_on
- end
-end

No commit comments for this range

Something went wrong with that request. Please try again.