pipeline_dealers 0.0.1 → 0.0.2

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/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