pipeline_dealers 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # 0.0.2
2
+ - Made base model more robust
3
+ - Made filtering & limiting work for TestClient.
4
+ - Added interactive console example
5
+ - Add rspec example
6
+
7
+ # 0.0.1
8
+ - Initial release
data/README.md CHANGED
@@ -19,7 +19,7 @@ client = Pipelinedealers::Client.new(api_key: "z3kr3tp@zzw0rd")
19
19
 
20
20
  # Get all companies
21
21
  client.companies.all.each do |company|
22
- puts company.name
22
+ puts company.name
23
23
  end
24
24
 
25
25
  # Find company by ID
@@ -48,6 +48,7 @@ describe "MyClass" do
48
48
  end
49
49
  ```
50
50
  *Note:* Be sure to stub the client in your code. This only works if you use the same client reference in both the specs and your application.
51
+ For more examples, see [these examples](examples/howto_rspec) and [how to run them](examples/howto_rspec/README.md)
51
52
 
52
53
  ## Contributing
53
54
 
@@ -61,4 +62,4 @@ end
61
62
 
62
63
  The awesome people at
63
64
 
64
- [![Springest](http://static-1.cdnhub.nl/images/logo-springest.jpg "Logo springest.com")](http://www.springest.com/about-springest)
65
+ [![Springest](http://static-1.cdnhub.nl/images/logo-springest.jpg "Logo springest.com")](http://www.springest.com/)
@@ -0,0 +1,2 @@
1
+ Run these specs from the top of the gem repository like this:
2
+ $ bundle exec examples/howto\_rspec/SPEC\_spec.rb
@@ -0,0 +1,30 @@
1
+ require "pipeline_dealers"
2
+ require "pipeline_dealers/test"
3
+
4
+
5
+ class SomeClass
6
+ def pld_client
7
+ # Normally this gets executed, but not during this test
8
+ PipelineDealers::Client.new(SOME_OPTIONS)
9
+ end
10
+
11
+ def create_company
12
+ company = pld_client.companies.create(name: "MyCompany")
13
+ company.notes.create(content: "whoo, awesome")
14
+ end
15
+ end
16
+
17
+ describe SomeClass do
18
+ let(:client) { PipelineDealers::TestClient.new }
19
+ before { subject.stub(:pld_client).and_return(client) }
20
+
21
+ describe "#create_company" do
22
+ it "creates a company" do
23
+ expect { subject.create_company }.to change(client.companies, :count).by(1)
24
+ end
25
+
26
+ it "creates a note" do
27
+ expect { subject.create_company }.to change(client.notes, :count).by(1)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "bundler"
4
+ require "irb"
5
+
6
+ Bundler.setup
7
+
8
+ require "pipeline_dealers"
9
+ require "pipeline_dealers/test"
10
+
11
+ # Hack to force context
12
+ module IRB
13
+ def self.start_session(binding)
14
+ unless @__initialized
15
+ args = ARGV
16
+ ARGV.replace(ARGV.dup)
17
+ IRB.setup(nil)
18
+ ARGV.replace(args)
19
+ @__initialized = true
20
+ end
21
+ workspace = WorkSpace.new(binding)
22
+ irb = Irb.new(workspace)
23
+ @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
24
+ @CONF[:MAIN_CONTEXT] = irb.context
25
+
26
+ catch(:IRB_EXIT) do
27
+ irb.eval_input
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+ module Context
34
+ extend self
35
+ def test_client
36
+ @test_client ||= PipelineDealers::TestClient.new
37
+ end
38
+ end
39
+
40
+
41
+ puts "You can access the test_client with 'test_client'."
42
+ IRB.start_session(Context)
@@ -8,6 +8,19 @@ module PipelineDealers
8
8
 
9
9
  @cache[key]
10
10
  end
11
+
12
+ # This base version just sets the condition fields from the collection
13
+ # to the model, if they're not set manually
14
+ def save(collection, model)
15
+ if collection.options.has_key?(:where)
16
+ collection.options[:where].each do |field, value|
17
+ if model.send(field).nil?
18
+ setter = :"#{field}="
19
+ model.send(setter, value)
20
+ end
21
+ end
22
+ end
23
+ end
11
24
  end
12
25
  end
13
26
  end
@@ -9,7 +9,7 @@ module PipelineDealers
9
9
  delegate :connection, to: :backend
10
10
  delegate :collection_url, to: :model_klass
11
11
 
12
- attr_reader :model_klass, :backend, :client
12
+ attr_reader :model_klass, :backend, :client, :options
13
13
 
14
14
  def initialize(backend, options)
15
15
  @options = options
@@ -34,6 +34,10 @@ module PipelineDealers
34
34
  end
35
35
  end
36
36
 
37
+ def each &block
38
+ raise "Should be implemented by backend!"
39
+ end
40
+
37
41
  def select &block
38
42
  results = []
39
43
 
@@ -47,7 +51,8 @@ module PipelineDealers
47
51
  def collect &operation
48
52
  results = []
49
53
 
50
- self.each do
54
+ self.each do |model|
55
+ results << operation.call(model)
51
56
  end
52
57
 
53
58
  results
@@ -78,7 +83,7 @@ module PipelineDealers
78
83
  attributes = @options[:new_defaults].merge(attributes)
79
84
  end
80
85
 
81
- model_klass.new(collection: self, record_new: true, attributes: attributes)
86
+ model_klass.new(collection: self, client: @client, record_new: true, attributes: attributes)
82
87
  end
83
88
 
84
89
  def create(attributes = {})
@@ -14,6 +14,8 @@ module PipelineDealers
14
14
  end
15
15
 
16
16
  def save(collection, model)
17
+ super
18
+
17
19
  model_attr_name = model.class.attribute_name
18
20
 
19
21
  if model_attr_name.nil?
@@ -5,7 +5,7 @@ module PipelineDealers
5
5
  def find id
6
6
  status, result = @backend.connection.get(collection_url + "/#{id}.json", {})
7
7
  if status == 200
8
- model_klass.new(collection: self, persisted: true, attributes: result)
8
+ model_klass.new(client: @client, collection: self, persisted: true, attributes: result)
9
9
  else
10
10
  raise Error::NotFound
11
11
  end
@@ -16,16 +16,6 @@ module PipelineDealers
16
16
  operation.call(result)
17
17
  end
18
18
  end
19
-
20
- def collect &operation
21
- results = []
22
-
23
- Fetcher.new(@backend.connection, self, model_klass, @options).each do |result|
24
- results << operation.call(result)
25
- end
26
-
27
- results
28
- end
29
19
  end
30
20
  end
31
21
  end
@@ -1,8 +1,6 @@
1
- require_relative "collection"
2
-
3
1
  module PipelineDealers
4
2
  module Backend
5
- class Test
3
+ class Test < Base
6
4
  attr_reader :items
7
5
 
8
6
  def cache key
@@ -11,7 +9,7 @@ module PipelineDealers
11
9
 
12
10
  def initialize(client)
13
11
  @client = client
14
- @items = Hash.new([])
12
+ @items = Hash.new
15
13
  @last_id = 41
16
14
  end
17
15
 
@@ -20,14 +18,20 @@ module PipelineDealers
20
18
  end
21
19
 
22
20
  def save(collection, model)
21
+ super
22
+
23
+ @items[model.class] ||= []
23
24
  @items[model.class] << model
25
+
24
26
  if model.id.nil?
25
27
  model.send(:instance_variable_set, :@id, @last_id += 1)
26
28
  end
27
29
  end
28
30
 
29
31
  def destroy(collection, to_remove)
30
- @items[to_remove.class].reject! { |model| model == to_remove }
32
+ if @items.has_key?(to_remove.class)
33
+ @items[to_remove.class].reject! { |model| model == to_remove }
34
+ end
31
35
  end
32
36
  end
33
37
  end
@@ -18,15 +18,31 @@ module PipelineDealers
18
18
  items.each &operation
19
19
  end
20
20
 
21
- def collect &operation
22
- items.collect &operation
23
- end
24
-
25
21
  protected
26
22
 
27
23
  def items
28
- @backend.items[@model_klass]
29
- @backend.items[@model_klass]
24
+ if @options.has_key?(:limit)
25
+ filtered_items[0..(@options[:limit]-1)]
26
+ else
27
+ filtered_items
28
+ end
29
+ end
30
+
31
+ def filtered_items
32
+ if not @options.has_key?(:where)
33
+ @backend.items[@model_klass] || []
34
+ else
35
+ (@backend.items[@model_klass] || []).select do |model|
36
+ res = @options[:where].detect do |field, value| # 'return' true when a condition does NOT hold
37
+ if !@model_klass.attributes.has_key?(field) && field != :id
38
+ raise("Model #{@model_klass} doesn't have a field #{field.inspect}")
39
+ else
40
+ model.send(field) != value
41
+ end
42
+ end
43
+ res == nil # All conditions did hold
44
+ end
45
+ end
30
46
  end
31
47
  end
32
48
  end
@@ -50,8 +50,8 @@ module PipelineDealers
50
50
  def initialize(options = {})
51
51
  @options = options
52
52
  @persisted = options.delete(:persisted) == true
53
- @client = options.delete(:client)
54
- @collection = options.delete(:collection)
53
+ @client = options.delete(:client) || raise("No client given")
54
+ @collection = options.delete(:collection) || raise("No collection given")
55
55
 
56
56
  import_attributes! options.delete(:attributes)
57
57
  end
@@ -1,3 +1,3 @@
1
1
  module PipelineDealers
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -28,7 +28,7 @@ module PipelineDealers::Backend
28
28
  end
29
29
 
30
30
  context "that has been persisted" do
31
- let(:model) { TestModel.new(collection: collection, persisted: true, attributes: { "id" => 123, name: "Springest"}) }
31
+ let(:model) { TestModel.new(client: double("Client"), collection: collection, persisted: true, attributes: { "id" => 123, name: "Springest"}) }
32
32
  after(:each) { model.save }
33
33
 
34
34
  it "uses the PUT method" do
@@ -44,8 +44,8 @@ describe PipelineDealers::Backend::Http::Collection do
44
44
  ]
45
45
  end
46
46
 
47
- let(:model_a) { TestModel.new(collection: subject, attributes: { name: "Maarten" }) }
48
- let(:model_b) { TestModel.new(collection: subject, attributes: { name: "Hoogendoorn" }) }
47
+ let(:model_a) { TestModel.new(client: double("Client"), collection: subject, attributes: { name: "Maarten" }) }
48
+ let(:model_b) { TestModel.new(client: double("Client"), collection: subject, attributes: { name: "Hoogendoorn" }) }
49
49
 
50
50
  it "fetches the correct models" do
51
51
  connection.should_receive(:get).ordered.once.with(*expected_params_a).and_return(response_a)
@@ -84,7 +84,7 @@ describe PipelineDealers::Backend::Http::Collection do
84
84
  ]
85
85
  end
86
86
 
87
- let(:model_a) { TestModel.new(collection: subject, attributes: { name: "Maarten"}) }
87
+ let(:model_a) { TestModel.new(client: double("client"), collection: subject, attributes: { name: "Maarten"}) }
88
88
 
89
89
  it "fetches only the resouces before the limit" do
90
90
  connection.should_receive(:get).once.with(*expected_params).and_return(response)
@@ -2,7 +2,8 @@ require "pipeline_dealers"
2
2
 
3
3
  module PipelineDealers
4
4
  class Model
5
- describe CustomField do
5
+ describe CustomField, focus: true do
6
+ subject { described_class.new(client: double("Client"), collection: double("Client")) }
6
7
  let(:model) { nil }
7
8
 
8
9
  describe "decode" do
@@ -32,10 +33,14 @@ module PipelineDealers
32
33
 
33
34
  context "dropdown" do
34
35
  subject do
35
- CustomField.new(attributes: {
36
- "field_type" => "dropdown",
37
- "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
38
- })
36
+ CustomField.new(
37
+ client: double("Client"),
38
+ collection: double("Collection"),
39
+ attributes: {
40
+ "field_type" => "dropdown",
41
+ "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
42
+ }
43
+ )
39
44
  end
40
45
 
41
46
  it "decodes correctly" do
@@ -45,10 +50,14 @@ module PipelineDealers
45
50
 
46
51
  context "multi_select" do
47
52
  subject do
48
- CustomField.new(attributes: {
49
- "field_type" => "multi_select",
50
- "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
51
- })
53
+ CustomField.new(
54
+ client: double("Client"),
55
+ collection: double("Collection"),
56
+ attributes: {
57
+ "field_type" => "multi_select",
58
+ "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
59
+ }
60
+ )
52
61
  end
53
62
 
54
63
  it "decodes correctly" do
@@ -92,10 +101,14 @@ module PipelineDealers
92
101
 
93
102
  context "dropdown" do
94
103
  subject do
95
- CustomField.new(attributes: {
96
- "field_type" => "dropdown",
97
- "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
98
- })
104
+ CustomField.new(
105
+ client: double("Client"),
106
+ collection: double("Collection"),
107
+ attributes: {
108
+ "field_type" => "dropdown",
109
+ "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
110
+ }
111
+ )
99
112
  end
100
113
 
101
114
  it "encodes correctly" do
@@ -105,10 +118,14 @@ module PipelineDealers
105
118
 
106
119
  context "multi_select" do
107
120
  subject do
108
- CustomField.new(attributes: {
109
- "field_type" => "multi_select",
110
- "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
111
- })
121
+ CustomField.new(
122
+ client: double("Client"),
123
+ collection: double("Collection"),
124
+ attributes: {
125
+ "field_type" => "multi_select",
126
+ "custom_field_label_dropdown_entries" => [{"id" => 123, "value" => "My Item"}]
127
+ }
128
+ )
112
129
  end
113
130
 
114
131
  it "encodes correctly" do
@@ -49,13 +49,13 @@ describe PipelineDealers::Model::HasCustomFields do
49
49
  }
50
50
  }
51
51
 
52
- subject { ModelWithCustomFields.new(collection: collection, persisted: true, attributes: { "id" => 123, name: "Springest", custom_fields: custom_attributes} ) }
52
+ subject { ModelWithCustomFields.new(client: double("Client"), collection: collection, persisted: true, attributes: { "id" => 123, name: "Springest", custom_fields: custom_attributes} ) }
53
53
 
54
54
  context "reading custom fields" do
55
55
  before { client.stub(:custom_fields).and_return { PLD::CustomField::Collection.new(backend, klass: CustomModelField, cached: true, cache_key: :custom_field_cache_key) } }
56
56
 
57
57
  let(:custom_field_models) do
58
- custom_field_labels.collect { |label| CustomModelField.new(collection: model_custom_fields, persisted: true, attributes: label["entries"]) }
58
+ custom_field_labels.collect { |label| CustomModelField.new(client: double("Client"), collection: model_custom_fields, persisted: true, attributes: label["entries"]) }
59
59
  end
60
60
 
61
61
  it "fetcheing the translation map is cache" do
@@ -5,7 +5,7 @@ describe PipelineDealers::Model do
5
5
  subject { TestModel }
6
6
 
7
7
  context "initialization" do
8
- let(:model) { subject.new(attributes: {name: "Springest"}) }
8
+ let(:model) { subject.new(client: double("Client"), collection: double("Connection"), attributes: {name: "Springest"}) }
9
9
 
10
10
  it "can access the name by the name method" do
11
11
  model.name.should == "Springest"
@@ -21,7 +21,7 @@ describe PipelineDealers::Model do
21
21
  end
22
22
 
23
23
  context "setting attributes" do
24
- let(:model) { subject.new({}) }
24
+ let(:model) { subject.new(client: double("Client"), collection: double("Collection"), attributes: {}) }
25
25
  context "name is set using accessor" do
26
26
  before { model.name = "Springest" }
27
27
 
@@ -3,7 +3,8 @@ require "pipeline_dealers/test"
3
3
 
4
4
  module PipelineDealers
5
5
  describe "Client with TestBackend" do
6
- subject { TestClient.new }
6
+ let(:client) { TestClient.new }
7
+ subject { client }
7
8
 
8
9
  describe "storing a model" do
9
10
  describe "#create" do
@@ -27,6 +28,14 @@ module PipelineDealers
27
28
  it "is accessable from all instances" do
28
29
  other_client.companies.first.should == subject.companies.first
29
30
  end
31
+
32
+ context "when stored" do
33
+ let!(:company) { subject.companies.create(name: "Springest") }
34
+
35
+ it "makes it able to find it using .first" do
36
+ subject.companies.first.should == company
37
+ end
38
+ end
30
39
  end
31
40
 
32
41
  describe "destroying a model" do
@@ -76,5 +85,51 @@ module PipelineDealers
76
85
  end
77
86
  end
78
87
  end
88
+
89
+ describe "Notes on nested model" do
90
+ let!(:model) { subject.companies.create(name: "AWESOME") }
91
+
92
+ context "no notes added" do
93
+ it "has no notes" do
94
+ model.notes.all.to_a.should == []
95
+ end
96
+ end
97
+
98
+ context "after a note has been added" do
99
+ it "has one note" do
100
+ expect do
101
+ model.notes.create(content: "Note Content")
102
+ end.to change { model.notes.all.to_a.length }.by(1)
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "selection options on collections" do
108
+ let!(:company_a) { client.companies.create(name: "Company A") }
109
+ let!(:company_b) { client.companies.create(name: "Company B") }
110
+
111
+ context "without any selections" do
112
+ subject { client.companies.all.to_a }
113
+ it { should =~ [company_a, company_b] }
114
+ end
115
+
116
+ context "with limit" do
117
+ subject { client.companies.limit(1).to_a }
118
+ its(:length) { should == 1 }
119
+ it { should =~ [company_a] }
120
+ end
121
+
122
+ context "filtered" do
123
+ context "on company a" do
124
+ subject { client.companies.where(id: company_a.id).all.to_a }
125
+ it { should =~ [company_a] }
126
+ end
127
+
128
+ context "on company b" do
129
+ subject { client.companies.where(id: company_b.id).all.to_a }
130
+ it { should =~ [company_b] }
131
+ end
132
+ end
133
+ end
79
134
  end
80
135
  end
data/todo.md CHANGED
@@ -11,3 +11,5 @@
11
11
  5. Lead statuses
12
12
  6. Predefined contacts tags
13
13
  7. Event categories
14
+
15
+ - Add counting to all collections (per_page = 1, count nr pages)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pipeline_dealers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-04 00:00:00.000000000 Z
12
+ date: 2013-03-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -196,6 +196,7 @@ extra_rdoc_files: []
196
196
  files:
197
197
  - .gitignore
198
198
  - .rspec
199
+ - CHANGELOG.md
199
200
  - Gemfile
200
201
  - Guardfile
201
202
  - LICENSE.txt
@@ -208,9 +209,12 @@ files:
208
209
  - examples/company_people.rb
209
210
  - examples/config.rb
210
211
  - examples/find_person.rb
212
+ - examples/howto_rspec/README.md
213
+ - examples/howto_rspec/notes_spec.rb
211
214
  - examples/list_custom_fields.rb
212
215
  - examples/people_create_and_destroy.rb
213
216
  - examples/people_list_all.rb
217
+ - examples/test_console.rb
214
218
  - lib/pipeline_dealers.rb
215
219
  - lib/pipeline_dealers/backend/base.rb
216
220
  - lib/pipeline_dealers/backend/base/backend.rb