herder 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- herder (0.0.1)
4
+ herder (0.0.4)
5
5
  active_resource_pagination
6
6
  activeresource
7
7
  reactive_resource
8
+ timecop
8
9
  will_paginate
9
10
 
10
11
  GEM
@@ -36,6 +37,7 @@ GEM
36
37
  rspec-expectations (2.11.1)
37
38
  diff-lcs (~> 1.1.3)
38
39
  rspec-mocks (2.11.1)
40
+ timecop (0.3.5)
39
41
  will_paginate (3.0.3)
40
42
 
41
43
  PLATFORMS
data/README.md CHANGED
@@ -22,9 +22,25 @@ password: "password"
22
22
 
23
23
  Or don't add the yml file to fall back on the ENV variables `HERDER_SITE`, `HERDER_USER` and `HERDER_PASSWORD`. This is useful for Heroku.
24
24
 
25
- ## Usage
26
-
27
- For now Herder adds a few built in ActiveResource classes. For full usage details read the [ActiveResource documentation](http://api.rubyonrails.org/classes/ActiveResource/Base.html).
25
+ ## Basic usage
26
+
27
+ For now Herder adds a few built in ActiveResource classes.
28
+
29
+ * `Herder::Attendee`
30
+ * has many `Herder::Emails`
31
+ * has many `Herder::Tickets`
32
+ * `Herder::Email`
33
+ * belongs to `Herder::Attendee`
34
+ * `Herder::Ticket`
35
+ * belongs to `Herder::Attendee`
36
+ * belongs to `Herder::Event`
37
+ * `Herder::Event`
38
+ * has many `Herder::Tickets`
39
+ * belongs to `Herder::Venue`
40
+ * `Herder::Venue`
41
+ * has many `Herder::Events`
42
+
43
+ For full usage details read the [ActiveResource documentation](http://api.rubyonrails.org/classes/ActiveResource/Base.html).
28
44
 
29
45
  ```ruby
30
46
  Herder::Attendee.find(1)
@@ -45,8 +61,49 @@ Attendee.find(1)
45
61
  #=> #<Attendee:0x007f9aabb84550 @attributes={"created_at"=>"2012-07-10T19:26:23Z", "diet"=>nil, "first_name"=>"John", "id"=>1, "kind"=>1, "last_name"=>"Doe", "name"=>"John Doe", "notes"=>nil, "phone_number"=>nil, "public"=>true, "tshirt"=>nil, "twitter"=>nil, "updated_at"=>"2012-07-10T19:26:23Z"}, @prefix_options={}, @persisted=true>
46
62
  ```
47
63
 
64
+ ## Using interactions
65
+
66
+ Interactions are a handy key-value attributes that can be set on other classes (Interactables). This is handy as it means we don't need to add loads of extra booleans to Hamster for every little thing we might need to keep track of.
67
+
68
+ **Note:** Interactions are never deleted, hence you can always get a full log of interactions including date and time of when something changed value.
69
+
70
+ ### Acting on a record
71
+
72
+ ```ruby
73
+ ticket = Ticket.find(1)
74
+ ticket.interactions.checkin = true #changes state
75
+ ticket.interactions.checkin.toggle #changes state to opposite of current state
76
+ ticket.interactions.checkin.undo! #undoes (hard delete) last state
77
+ ticket.interactions.checkin #just returns latest value for the checkin key
78
+ ticket.interactions.checkin? #just checks if value == true
79
+ ticket.interactions.limit(5).checkin #just returns last 5 values for checkin
80
+ ticket.interactions.limit(5).oldest.checkin #just returns first 5 (oldest) values for checkin
81
+ ticket.interactions #full list of interaction objects
82
+ ```
83
+
84
+ ### Acting on a table
85
+
86
+ **Note:** These methods return the objects they are performed on (in this case Ticket).
87
+
88
+ ```ruby
89
+ event = Event.find(1)
90
+ event.tickets.where("interactions.confirmed = true") #confirmed tickets for event #1
91
+ event.tickets.where("interactions.confirmed != true") #unconfirmed tickets for event #1
92
+ event.tickets.where("interactions.cancelled = true") #cancelled tickets for event #1
93
+ event.tickets.where("interactions.checkin ~ true") #attended tickets for event #1
94
+ event.tickets.where("interactions.checkin !~ true") #noshow tickets for event #1
95
+ event.tickets.where("interactions.checkin = true") #onsite tickets for event #1
96
+ event.tickets.where("interactions.checkin != true") #offsite tickets for event #1
97
+ event.tickets.where("interactions.checkin ~ ? AND interactions.created_at < ? AND interactions.created_at > ?", true, Time.now, 3.days.ago) #attended during period
98
+ event.tickets.where("interactions.checkin !~ ? AND interactions.created_at < ? AND interactions.created_at > ?", false, Time.now, 3.days.ago) # did not check out during period
99
+ event.tickets.where("interactions.permanently_left = true") #not-coming-back
100
+ event.tickets.where("interactions.permanently_left != true") #coming-back
101
+ ```
102
+
48
103
  ## Changelog
49
104
 
105
+ * 0.0.4 - Added events and venues
106
+ * 0.0.3 - Added interactions and interactables
50
107
  * 0.0.2 - Added emails, tickets, and association
51
108
  * 0.0.1 - Added basic attendee interface
52
109
 
@@ -24,4 +24,5 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency 'reactive_resource'
25
25
  s.add_dependency 'active_resource_pagination'
26
26
  s.add_dependency 'will_paginate'
27
+ s.add_dependency 'timecop'
27
28
  end
@@ -4,9 +4,6 @@ require "active_resource_pagination"
4
4
 
5
5
  require_relative "herder/config"
6
6
  require_relative "herder/model"
7
- require_relative "herder/attendee"
8
- require_relative "herder/ticket"
9
- require_relative "herder/email"
10
7
 
11
8
  class Herder
12
9
  end
@@ -1,5 +1,7 @@
1
1
  class Herder
2
2
  class Attendee < Herder::Model
3
+ include Herder::Interactable
4
+
3
5
  has_many :emails
4
6
  has_many :tickets
5
7
  end
@@ -0,0 +1,8 @@
1
+ class Herder
2
+ class Event < Herder::Model
3
+ include Herder::Interactable
4
+
5
+ has_many :tickets
6
+ belongs_to :venue
7
+ end
8
+ end
@@ -0,0 +1,15 @@
1
+ class Herder
2
+ module Interactable
3
+ def interactions
4
+ Interactable::Query.new(type: klass, id: id)
5
+ end
6
+
7
+ protected
8
+
9
+ def klass
10
+ @klass ||= self.class.name.split("::").last
11
+ end
12
+ end
13
+ end
14
+
15
+ require_relative "interactable/query"
@@ -0,0 +1,94 @@
1
+ class Herder
2
+ module Interactable
3
+ class Query
4
+ def initialize options
5
+ params[:interactable_id] = options[:id] if options[:id]
6
+ params[:interactable_type] = options[:type] if options[:type]
7
+ newest
8
+ end
9
+
10
+ # this is used for lazy execution of the query
11
+ def each &block
12
+ query.each &block
13
+ end
14
+
15
+ def to_s
16
+ query.to_s
17
+ end
18
+
19
+ def limit count
20
+ params[:limit] = count
21
+ self
22
+ end
23
+
24
+ def oldest
25
+ order "created_at ASC"
26
+ end
27
+
28
+ def newest
29
+ order "created_at DESC"
30
+ end
31
+
32
+ def set key
33
+ params[:key] = key
34
+ self
35
+ end
36
+
37
+ def to value
38
+ params[:value] = value
39
+ create
40
+ end
41
+
42
+ def state? key
43
+ interaction = state(key)
44
+ interaction && interaction.value.to_s == "true"
45
+ end
46
+
47
+ def state key
48
+ limit 1
49
+ newest
50
+ states(key).first
51
+ end
52
+
53
+ def states key
54
+ params[:key] = key
55
+ query
56
+ end
57
+
58
+ protected
59
+
60
+ attr_accessor :params
61
+
62
+ def order by
63
+ params[:order] = by
64
+ self
65
+ end
66
+
67
+ def params
68
+ @params ||= {}
69
+ end
70
+
71
+ def query
72
+ @query ||= Interaction.where(params)
73
+ end
74
+
75
+ def method_missing(key, *args, &block)
76
+ if key.to_s.ends_with? "?"
77
+ key = key.to_s.gsub("?", "")
78
+ state? key
79
+ elsif key.to_s.ends_with? "="
80
+ key = key.to_s.gsub("=", "")
81
+ set(key).to(*args)
82
+ elsif params[:limit] || params[:offset]
83
+ states key
84
+ else
85
+ state(key)
86
+ end
87
+ end
88
+
89
+ def create
90
+ Interaction.create params.except(:limit, :offset, :order)
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,26 @@
1
+ class Herder
2
+ class Interaction < Herder::Model
3
+ def toggle
4
+ val = !["true", true].include?(value)
5
+ query.set(key).to(val)
6
+ end
7
+
8
+ def undo!
9
+ destroy
10
+ end
11
+
12
+ def to_s
13
+ value
14
+ end
15
+
16
+ def ==(other)
17
+ value == other
18
+ end
19
+
20
+ private
21
+
22
+ def query
23
+ @query ||= Interactable::Query.new(type: interactable_type, id: interactable_id)
24
+ end
25
+ end
26
+ end
@@ -4,8 +4,17 @@ class Herder
4
4
  self.user = Herder::Config.get("user")
5
5
  self.password = Herder::Config.get("password")
6
6
 
7
- def self.where options
8
- find(:all, params: options)
7
+ def self.where *params
8
+ Herder::Model::Query.new(self).where(*params)
9
9
  end
10
10
  end
11
- end
11
+ end
12
+
13
+ require_relative "model/query"
14
+ require_relative "interaction"
15
+ require_relative "interactable"
16
+ require_relative "attendee"
17
+ require_relative "venue"
18
+ require_relative "event"
19
+ require_relative "ticket"
20
+ require_relative "email"
@@ -0,0 +1,82 @@
1
+ class Herder
2
+ class Model
3
+ class Query
4
+ attr_accessor :model, :params
5
+
6
+ def initialize model
7
+ self.model = model
8
+ self.params = {}
9
+ end
10
+
11
+ def where *prms
12
+ params.merge!(sanitize prms)
13
+ self
14
+ end
15
+
16
+ def each &block
17
+ query.each &block
18
+ end
19
+
20
+ def to_s
21
+ query.to_s
22
+ end
23
+
24
+ protected
25
+
26
+ COMPARATORS = {
27
+ "=" => "=",
28
+ "!=" => "!=",
29
+ "~" => "~",
30
+ "!~" => "!~",
31
+ "is" => "=",
32
+ "isnt" => "!=",
33
+ "was" => "~",
34
+ "wasnt" => "!~"
35
+ }.freeze
36
+
37
+ def query
38
+ @query ||= model.find(:all, params: params)
39
+ end
40
+
41
+ def sanitize params
42
+ case params.class.name
43
+ when "Hash"
44
+ return params.stringify_keys
45
+ when "String"
46
+ return hashify params
47
+ when "Array"
48
+ if params.first.is_a?(Hash)
49
+ return params.first.stringify_keys
50
+ else
51
+ return hashify(parameterize params)
52
+ end
53
+ end
54
+ end
55
+
56
+ def hashify params
57
+ subqueries = params.split(/and/i)
58
+ return subqueries.inject(Hash.new) do |results, subquery|
59
+ tokens = subquery.strip.split(" ", 3)
60
+ tokens[2].gsub!(/\A"|'/m, "")
61
+ tokens[2].gsub!(/"|'\Z/m, "")
62
+ append_param results, tokens
63
+ results
64
+ end
65
+ end
66
+
67
+ def parameterize params
68
+ return params unless params.is_a?(Array)
69
+ params[0].gsub(/ \?/, " %s") % params[1..-1]
70
+ end
71
+
72
+ def append_param results, tokens
73
+ if tokens[0].starts_with? "interactions."
74
+ comparator = COMPARATORS[tokens[1]] || tokens[1]
75
+ results["#{tokens[0]} #{comparator}"] = tokens[2]
76
+ else
77
+ results[tokens[0]] = tokens[2]
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -1,5 +1,8 @@
1
1
  class Herder
2
2
  class Ticket < Herder::Model
3
+ include Herder::Interactable
4
+
3
5
  belongs_to :attendee
6
+ belongs_to :event
4
7
  end
5
8
  end
@@ -0,0 +1,5 @@
1
+ class Herder
2
+ class Venue < Herder::Model
3
+ has_many :events
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  class Herder
2
- VERSION = "0.0.2" unless defined? Herder::VERSION
2
+ VERSION = "0.0.4" unless defined? Herder::VERSION
3
3
  end
@@ -9,6 +9,10 @@ describe Herder::Attendee do
9
9
  Herder::Attendee.new.should be_a(Herder::Model)
10
10
  end
11
11
 
12
+ it "should inherit Herder::Interactable" do
13
+ Herder::Attendee.new.should be_a(Herder::Interactable)
14
+ end
15
+
12
16
  it "should have many tickets and emails" do
13
17
  Herder::Attendee.associations.map(&:attribute).should =~ [:tickets, :emails]
14
18
  Herder::Attendee.associations.map(&:class).uniq.should be == [ReactiveResource::Association::HasManyAssociation]
@@ -10,7 +10,7 @@ describe Herder::Email do
10
10
  end
11
11
 
12
12
  it "should belong to an attendee" do
13
- Herder::Ticket.associations.map(&:attribute).should =~ [:attendee]
14
- Herder::Ticket.associations.map(&:class).should be == [ReactiveResource::Association::BelongsToAssociation]
13
+ Herder::Email.associations.map(&:attribute).should =~ [:attendee]
14
+ Herder::Email.associations.map(&:class).should be == [ReactiveResource::Association::BelongsToAssociation]
15
15
  end
16
16
  end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ describe Herder::Event do
4
+ it "should setup right name" do
5
+ Herder::Event.element_name.should be == "event"
6
+ end
7
+
8
+ it "should inherit Herder::Model" do
9
+ Herder::Event.new.should be_a(Herder::Model)
10
+ end
11
+
12
+ it "should inherit Herder::Interactable" do
13
+ Herder::Event.new.should be_a(Herder::Interactable)
14
+ end
15
+
16
+ it "should belong to an attendee" do
17
+ Herder::Event.associations.map(&:attribute).should =~ [:tickets, :venue]
18
+ Herder::Event.associations.map(&:class).should be == [ReactiveResource::Association::HasManyAssociation, ReactiveResource::Association::BelongsToAssociation]
19
+ end
20
+ end
@@ -0,0 +1,132 @@
1
+ require "spec_helper"
2
+
3
+ describe Herder::Interactable::Query do
4
+ before :each do
5
+ @interactions = Herder::Interactable::Query.new type: Herder::Ticket, id: 1
6
+ end
7
+
8
+ describe "#initialize" do
9
+ it "should setup the default params" do
10
+ @interactions.send(:params).should be == {:interactable_id=>1, :interactable_type=>Herder::Ticket, :order=>"created_at DESC"}
11
+ end
12
+ end
13
+
14
+ describe "#each" do
15
+ it "should yield the query" do
16
+ result = [:a, :b]
17
+ Herder::Interaction.should_receive(:where).and_return(result)
18
+
19
+ @interactions.each.should be_a(Enumerator)
20
+ @interactions.each{}.should be == result
21
+ end
22
+ end
23
+
24
+ describe "#to_s" do
25
+ it "should stringify the result" do
26
+ result = [:a, :b]
27
+ Herder::Interaction.should_receive(:where).and_return(result)
28
+ @interactions.to_s.should be_a(String)
29
+ @interactions.to_s{}.should be == result.to_s
30
+ end
31
+ end
32
+
33
+ describe "#limit" do
34
+ it "should set the limit" do
35
+ @interactions.limit 10
36
+ @interactions.send(:params)[:limit].should be == 10
37
+ end
38
+ end
39
+
40
+ describe "#oldest" do
41
+ it "should set the order created_at ASC" do
42
+ @interactions.oldest
43
+ @interactions.send(:params)[:order].should be == "created_at ASC"
44
+ end
45
+ end
46
+
47
+ describe "#newest" do
48
+ it "should set the order created_at DESC" do
49
+ @interactions.newest
50
+ @interactions.send(:params)[:order].should be == "created_at DESC"
51
+ end
52
+ end
53
+
54
+ describe "#set" do
55
+ it "should set the key" do
56
+ @interactions.set(:foo)
57
+ @interactions.send(:params)[:key].should be == :foo
58
+ end
59
+ end
60
+
61
+ describe "#to" do
62
+ it "should set the value and create a new object" do
63
+ expected_params = {:interactable_id=>1, :interactable_type=>Herder::Ticket, :key=>:foo, :value=>:bar}
64
+ Herder::Interaction.should_receive(:create).with(expected_params)
65
+ @interactions.set(:foo).to(:bar)
66
+ @interactions.send(:params)[:value].should be == :bar
67
+ end
68
+ end
69
+
70
+ describe "#state" do
71
+ before :each do
72
+ expected_params = {:interactable_id=>1, :interactable_type=>Herder::Ticket, :order=>"created_at DESC", :limit=>1, :key=>:foo}
73
+ interaction = Herder::Interaction.new value: "bar"
74
+ Herder::Interaction.should_receive(:where).with(expected_params).and_return([interaction])
75
+ end
76
+
77
+ it "should determine the current state of a value" do
78
+ @interactions.state(:foo).should be == "bar"
79
+ end
80
+
81
+ it "should also work by directly calling the key" do
82
+ @interactions.foo.should be == "bar"
83
+ end
84
+ end
85
+
86
+ describe "#state?" do
87
+ it "should return true if the value is true" do
88
+ expected_params = {:interactable_id=>1, :interactable_type=>Herder::Ticket, :order=>"created_at DESC", :limit=>1, :key=>:foo}
89
+ interaction = Herder::Interaction.new value: true
90
+ Herder::Interaction.should_receive(:where).with(expected_params).and_return([interaction])
91
+ @interactions.state?(:foo).should be_true
92
+ end
93
+
94
+ it "should return true if the value is 'true'" do
95
+ interaction = Herder::Interaction.new value: "true"
96
+ Herder::Interaction.should_receive(:where).and_return([interaction])
97
+ @interactions.state?(:foo).should be_true
98
+ end
99
+
100
+ it "should also work by directly asking it by key" do
101
+ interaction = Herder::Interaction.new value: "true"
102
+ Herder::Interaction.should_receive(:where).and_return([interaction])
103
+ @interactions.foo?.should be_true
104
+ end
105
+
106
+
107
+ it "should return false if the value if falsy" do
108
+ interaction = Herder::Interaction.new value: "foobar"
109
+ Herder::Interaction.should_receive(:where).and_return([interaction])
110
+ @interactions.foo?.should be_false
111
+ end
112
+
113
+ it "should return false if the value has never been set" do
114
+ Herder::Interaction.should_receive(:where).and_return([])
115
+ @interactions.foo?.should be_false
116
+ end
117
+ end
118
+
119
+ describe "#states" do
120
+ it "should return the results" do
121
+ expected_params = {:interactable_id=>1, :interactable_type=>Herder::Ticket, :order=>"created_at DESC", :key=>:foo}
122
+ Herder::Interaction.should_receive(:where).with(expected_params).and_return([:foo, :bar])
123
+ @interactions.states(:foo).should be == [:foo, :bar]
124
+ end
125
+
126
+ it "should also be able to be called by key if a limit was set" do
127
+ expected_params = {:interactable_id=>1, :interactable_type=>Herder::Ticket, :order=>"created_at DESC", :limit=>10, :key=>:foo}
128
+ Herder::Interaction.should_receive(:where).with(expected_params).and_return([:foo, :bar])
129
+ @interactions.limit(10).foo.should be == [:foo, :bar]
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ describe Herder::Interactable do
4
+ class MockClass < Herder::Model
5
+ include Herder::Interactable
6
+ end
7
+
8
+ describe "interactions" do
9
+ it "should provide a class a interactions object" do
10
+ mock_class = MockClass.new
11
+ mock_class.interactions.should be_a(Herder::Interactable::Query)
12
+ mock_class.interactions.send(:params)[:interactable_type].should be == "MockClass"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,44 @@
1
+ require "spec_helper"
2
+
3
+ describe Herder::Interaction do
4
+ it "should setup right name" do
5
+ Herder::Interaction.element_name.should be == "interaction"
6
+ end
7
+
8
+ it "should inherit Herder::Model" do
9
+ Herder::Email.new.should be_a(Herder::Model)
10
+ end
11
+
12
+ describe "#toggle" do
13
+ it "should remove the interaction" do
14
+ interaction = Herder::Interaction.new key: "foo", value: true
15
+ query = mock "Query"
16
+ interaction.should_receive(:query).and_return(query)
17
+ query.should_receive(:set).with("foo").and_return(query)
18
+ query.should_receive(:to).with(false)
19
+ interaction.toggle
20
+ end
21
+ end
22
+
23
+ describe "#undo!" do
24
+ it "should remove the interaction" do
25
+ interaction = Herder::Interaction.new value: "foo"
26
+ interaction.should_receive(:destroy)
27
+ interaction.undo!
28
+ end
29
+ end
30
+
31
+ describe "#to_s" do
32
+ it "should be represented by value" do
33
+ interaction = Herder::Interaction.new value: "foo"
34
+ interaction.to_s.should be == "foo"
35
+ end
36
+ end
37
+
38
+ describe "#==" do
39
+ it "should compare by value" do
40
+ interaction = Herder::Interaction.new value: "foo"
41
+ interaction.should be == "foo"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,91 @@
1
+ require "spec_helper"
2
+
3
+ describe Herder::Model::Query do
4
+ before :each do
5
+ @query = Herder::Model::Query.new(Herder::Ticket)
6
+ end
7
+
8
+ describe "#initialize" do
9
+ it "should assign the model and init the params" do
10
+ @query.model.should be == Herder::Ticket
11
+ @query.params.should be == {}
12
+ end
13
+ end
14
+
15
+ describe "#where" do
16
+ it "should append to the params" do
17
+ @query.where("id = ?", 1)
18
+ @query.params.should be == {"id" => "1"}
19
+ end
20
+
21
+ it "should be chainable" do
22
+ @query.where("id = ?", 1).where("foo = bar")
23
+ @query.params.should be == {"id" => "1", "foo" => "bar"}
24
+ end
25
+
26
+ it "should overwrite previously stated values" do
27
+ @query.where("id = ?", 1).where("id = ?", 2)
28
+ @query.params.should be == {"id" => "2"}
29
+ end
30
+
31
+ it "should parse interactions seperately" do
32
+ @query.where("id = ?", 1).where("interactions.confirmed ~ ?", "true")
33
+ @query.params.should be == {"id" => "1", "interactions.confirmed ~" => "true"}
34
+ end
35
+
36
+ it "should allow for interactions date ranges" do
37
+ Timecop.freeze(Time.now) do
38
+ @query.where("id = ?", 1).where("interactions.created_at > ? AND interactions.created_at < ?", 10.day.ago, 1.days.ago)
39
+ @query.params.should be == {"id" => "1", "interactions.created_at >" => 10.days.ago.to_s, "interactions.created_at <" => 1.days.ago.to_s}
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#each" do
45
+ it "should yield the query" do
46
+ result = [:a, :b]
47
+ Herder::Ticket.should_receive(:find).and_return(result)
48
+
49
+ @query.each.should be_a(Enumerator)
50
+ @query.each{}.should be == result
51
+ end
52
+ end
53
+
54
+ describe "#to_s" do
55
+ it "should stringify the result" do
56
+ result = [:a, :b]
57
+ Herder::Ticket.should_receive(:find).and_return(result)
58
+ @query.to_s.should be_a(String)
59
+ @query.to_s{}.should be == result.to_s
60
+ end
61
+ end
62
+
63
+ describe "COMPARATORS" do
64
+ it "should translate interaction comparators" do
65
+ @query.where("interactions.a is 'a'").where("interactions.b isnt 'b'").where("interactions.c was 'c'").where("interactions.d wasnt 'c'")
66
+ @query.params.should be == {"interactions.a ="=>"a", "interactions.b !="=>"b", "interactions.c ~"=>"c", "interactions.d !~"=>"c"}
67
+ end
68
+ end
69
+
70
+ describe "#hashify" do
71
+ it "should accept hashes" do
72
+ @query.where(foo: "this is a sentence")
73
+ @query.params.should be == {"foo" => "this is a sentence"}
74
+ end
75
+
76
+ it "should accept strings" do
77
+ @query.where("foo = 'this is a sentence'")
78
+ @query.params.should be == {"foo" => "this is a sentence"}
79
+ end
80
+
81
+ it "should accept strings with formats as tokens" do
82
+ @query.where("foo = ?", "this is a sentence")
83
+ @query.params.should be == {"foo" => "this is a sentence"}
84
+ end
85
+
86
+ it "should be chain-able" do
87
+ @query.where("foo = ?", "this is a sentence1").where("bar = 'this is a sentence2'")
88
+ @query.params.should be == {"foo" => "this is a sentence1", "bar" => "this is a sentence2"}
89
+ end
90
+ end
91
+ end
@@ -14,8 +14,26 @@ describe Herder::Model do
14
14
  describe "#where" do
15
15
  it "should pass the query along to find" do
16
16
  options = {foo: :bar}
17
+ Herder::Model.should_receive(:find).with(:all, params: {"foo" => :bar})
18
+ Herder::Model.where(options).to_s
19
+ end
20
+
21
+ it "should accept strings" do
22
+ options = {"foo" => "bar"}
23
+ Herder::Model.should_receive(:find).with(:all, params: options)
24
+ Herder::Model.where("foo = 'bar'").to_s
25
+ end
26
+
27
+ it "should accept strings with formats as tokens" do
28
+ options = {"foo" => "bar"}
29
+ Herder::Model.should_receive(:find).with(:all, params: options)
30
+ Herder::Model.where("foo = ?", "bar").to_s
31
+ end
32
+
33
+ it "should be chain-able" do
34
+ options = {"foo" => "bar", "baz" => "qar"}
17
35
  Herder::Model.should_receive(:find).with(:all, params: options)
18
- Herder::Model.where(options)
36
+ Herder::Model.where("foo = ?", "bar").where("baz = ?", "qar").to_s
19
37
  end
20
38
  end
21
39
  end
@@ -9,8 +9,12 @@ describe Herder::Ticket do
9
9
  Herder::Ticket.new.should be_a(Herder::Model)
10
10
  end
11
11
 
12
+ it "should inherit Herder::Interactable" do
13
+ Herder::Ticket.new.should be_a(Herder::Interactable)
14
+ end
15
+
12
16
  it "should belong to an attendee" do
13
- Herder::Ticket.associations.map(&:attribute).should =~ [:attendee]
14
- Herder::Ticket.associations.map(&:class).should be == [ReactiveResource::Association::BelongsToAssociation]
17
+ Herder::Ticket.associations.map(&:attribute).should =~ [:attendee, :event]
18
+ Herder::Ticket.associations.map(&:class).should be == [ReactiveResource::Association::BelongsToAssociation, ReactiveResource::Association::BelongsToAssociation]
15
19
  end
16
20
  end
@@ -0,0 +1,16 @@
1
+ require "spec_helper"
2
+
3
+ describe Herder::Venue do
4
+ it "should setup right name" do
5
+ Herder::Venue.element_name.should be == "venue"
6
+ end
7
+
8
+ it "should inherit Herder::Model" do
9
+ Herder::Venue.new.should be_a(Herder::Model)
10
+ end
11
+
12
+ it "should have many events" do
13
+ Herder::Venue.associations.map(&:attribute).should =~ [:events]
14
+ Herder::Venue.associations.map(&:class).should be == [ReactiveResource::Association::HasManyAssociation]
15
+ end
16
+ end
@@ -1 +1,2 @@
1
1
  require "herder"
2
+ require "timecop"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: herder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-21 00:00:00.000000000 Z
12
+ date: 2012-07-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70333801744000 !ruby/object:Gem::Requirement
16
+ requirement: &70345550619080 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70333801744000
24
+ version_requirements: *70345550619080
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activeresource
27
- requirement: &70333801743580 !ruby/object:Gem::Requirement
27
+ requirement: &70345550617940 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70333801743580
35
+ version_requirements: *70345550617940
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: reactive_resource
38
- requirement: &70333801743160 !ruby/object:Gem::Requirement
38
+ requirement: &70345551200100 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70333801743160
46
+ version_requirements: *70345551200100
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: active_resource_pagination
49
- requirement: &70333801742740 !ruby/object:Gem::Requirement
49
+ requirement: &70345551199680 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70333801742740
57
+ version_requirements: *70345551199680
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: will_paginate
60
- requirement: &70333801742320 !ruby/object:Gem::Requirement
60
+ requirement: &70345551199260 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,18 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70333801742320
68
+ version_requirements: *70345551199260
69
+ - !ruby/object:Gem::Dependency
70
+ name: timecop
71
+ requirement: &70345551198840 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *70345551198840
69
80
  description: The herder that manages all animals talking to the hamster
70
81
  email:
71
82
  - cristiano@geeksoflondon.com
@@ -87,14 +98,26 @@ files:
87
98
  - lib/herder/attendee.rb
88
99
  - lib/herder/config.rb
89
100
  - lib/herder/email.rb
101
+ - lib/herder/event.rb
102
+ - lib/herder/interactable.rb
103
+ - lib/herder/interactable/query.rb
104
+ - lib/herder/interaction.rb
90
105
  - lib/herder/model.rb
106
+ - lib/herder/model/query.rb
91
107
  - lib/herder/ticket.rb
108
+ - lib/herder/venue.rb
92
109
  - lib/herder/version.rb
93
110
  - spec/herder/attendee_spec.rb
94
111
  - spec/herder/config_spec.rb
95
112
  - spec/herder/email_spec.rb
113
+ - spec/herder/event_spec.rb
114
+ - spec/herder/interactable/query_spec.rb
115
+ - spec/herder/interactable_spec.rb
116
+ - spec/herder/interaction_spec.rb
117
+ - spec/herder/model/query_spec.rb
96
118
  - spec/herder/model_spec.rb
97
119
  - spec/herder/ticket_spec.rb
120
+ - spec/herder/venue_spec.rb
98
121
  - spec/herder_spec.rb
99
122
  - spec/spec_helper.rb
100
123
  homepage: http://github.com/geeksoflondon/herder
@@ -125,7 +148,13 @@ test_files:
125
148
  - spec/herder/attendee_spec.rb
126
149
  - spec/herder/config_spec.rb
127
150
  - spec/herder/email_spec.rb
151
+ - spec/herder/event_spec.rb
152
+ - spec/herder/interactable/query_spec.rb
153
+ - spec/herder/interactable_spec.rb
154
+ - spec/herder/interaction_spec.rb
155
+ - spec/herder/model/query_spec.rb
128
156
  - spec/herder/model_spec.rb
129
157
  - spec/herder/ticket_spec.rb
158
+ - spec/herder/venue_spec.rb
130
159
  - spec/herder_spec.rb
131
160
  - spec/spec_helper.rb