clever_reach 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZGVkNzU2NTg3NTEyZWUwMDdmMGMzMjFhMGQ0NDZhY2YyMDk2ZTI2OQ==
5
+ data.tar.gz: !binary |-
6
+ ZWQ0ZmQ0OTllNzA3YzljYWE1ZGI4MjRhMTM2ZGZjMDEyZmZmOGY5Yg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ Mjg0MGU2MjNjODRhYWE1OTY3NGZhYjFkOWNkYzcyMjE3MDNmMjU4ZWMwYmZm
10
+ Zjk5OTU1NGU1OWNmMmE5ZDg0OGM2NWRlZGQ0OTRlMGZlNGYzMDE2NGIwMzE0
11
+ OWU3ZmEyNDJlZWMwOGRhODNjNTdlMGI4YjA1OWEyNGRhZjRjZDA=
12
+ data.tar.gz: !binary |-
13
+ NTE1Yzg1ZWVkNzRkNDVhYzkyNTYzNDFjNjVlNDJiNTU4NGI3ZjZhNzI0NWUz
14
+ NjdkMDk5MTIyOTcxNGE3YTExNWQyOGVjYzYzYzAyZDdiYWZjYWIzZDJhNjY2
15
+ ZmJmNDBkNmZmNDRhMDM3MjA4NzA3ODIzOTY4NzY1NTE1OTM5MzE=
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *~
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in cleverreach.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012, 2013 Stephan Schubert <stephan@frozencherry.de>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # clever_reach
2
+
3
+ Ruby bindings for CleverReach's API
4
+
5
+ [![Code Climate](https://codeclimate.com/github/jazen/clever_reach.png)](https://codeclimate.com/github/jazen/clever_reach)
6
+
7
+ ## Installation
8
+
9
+ In your Gemfile:
10
+
11
+ ``` ruby
12
+ gem 'clever_reach'
13
+ ```
14
+
15
+ ## Introduction
16
+
17
+ ``` ruby
18
+ require 'clever_reach'
19
+
20
+ CleverReach.configure do |config|
21
+ config.api_key = "12345" # Replace with your API key
22
+ end
23
+
24
+ api = CleverReach::Base.new
25
+ resp = api.client_get_details
26
+ resp.to_hash # => { :id => '12345', :first_name => 'Stephan', ... }
27
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "clever_reach/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "clever_reach"
7
+ s.version = CleverReach::VERSION
8
+ s.authors = ["Stephan Schubert"]
9
+ s.email = ["stephan@frozencherry.de"]
10
+ s.homepage = "https://github.com/jazen/clever_reach"
11
+ s.summary = "Ruby bindings for CleverReach's API"
12
+ s.description = "Ruby bindings for CleverReach's API"
13
+ s.licenses = %w(MIT)
14
+
15
+ s.rubyforge_project = "clever_reach"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ # specify any dependencies here; for example:
23
+ s.add_development_dependency 'rspec'
24
+ s.add_development_dependency 'savon_spec'
25
+
26
+ s.add_runtime_dependency 'savon', '~> 1.0'
27
+ end
@@ -0,0 +1,16 @@
1
+ require "clever_reach/version"
2
+
3
+ module CleverReach
4
+ autoload :Base, 'clever_reach/base'
5
+ autoload :Configuration, 'clever_reach/configuration'
6
+ autoload :Errors, 'clever_reach/errors'
7
+ autoload :ResponseDecorator, 'clever_reach/response_decorator'
8
+
9
+ def self.config
10
+ Configuration.instance
11
+ end
12
+
13
+ def self.configure
14
+ yield config
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ require 'savon'
2
+
3
+ module CleverReach
4
+ class Base
5
+ attr_reader :api_key
6
+
7
+ def initialize
8
+ @api_key = CleverReach.config.api_key
9
+ end
10
+
11
+ def client
12
+ @client ||= Savon.client(CleverReach.config.wsdl_url)
13
+ end
14
+
15
+ def method_missing(name, *args)
16
+ options = args.last.is_a?(Hash) ? args.pop : {}
17
+ response = request(name, options)
18
+
19
+ ResponseDecorator.new(response).tap do |r|
20
+ raise Errors.lookup(r.status_code) unless r.valid?
21
+ end
22
+ end
23
+
24
+ private # ----------------------------------------------
25
+
26
+ def request(method_name, body)
27
+ # The 'apiKey' MUST come first in the *ordered* hash.
28
+ body = { 'apiKey' => @api_key }.merge(body)
29
+
30
+ client.request(method_name) do
31
+ soap.body = body
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ require 'singleton'
2
+
3
+ module CleverReach
4
+ class Configuration
5
+ include Singleton
6
+
7
+ @@defaults = {
8
+ wsdl_url: 'http://api.cleverreach.com/soap/interface_v5.1.php?wsdl'
9
+ }
10
+
11
+ attr_accessor :wsdl_url, :api_key, :list_id
12
+
13
+ def self.defaults
14
+ @@defaults
15
+ end
16
+
17
+ def initialize
18
+ @@defaults.each { |k,v| send("#{k}=", v) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,113 @@
1
+ module CleverReach
2
+ module Errors
3
+ # http://support.cleverreach.de/entries/20674817-fehlercode-api
4
+
5
+ class BaseError < StandardError
6
+ end
7
+
8
+ class InvalidAPIKey < BaseError
9
+ def initialize
10
+ super('invalid API key')
11
+ end
12
+ end
13
+
14
+ class NeedSessionBeforeUsage < BaseError
15
+ def initialize
16
+ super('need session before usage')
17
+ end
18
+ end
19
+
20
+ class PermissionDenied < BaseError
21
+ def initialize
22
+ super('permission denied')
23
+ end
24
+ end
25
+
26
+ class DataNotFound < BaseError
27
+ def initialize
28
+ super('data not found')
29
+ end
30
+ end
31
+
32
+ class EmailInvalid < BaseError
33
+ def initialize
34
+ super('email invalid')
35
+ end
36
+ end
37
+
38
+ class EmailBlacklisted < BaseError
39
+ def initialize
40
+ super('email blacklisted')
41
+ end
42
+ end
43
+
44
+ class DuplicateData < BaseError
45
+ def initialize
46
+ super('duplicate data')
47
+ end
48
+ end
49
+
50
+ class SubscriberAlreadyActive < BaseError
51
+ def initialize
52
+ super('subscriber already active')
53
+ end
54
+ end
55
+
56
+ class InsertingOrderFailed < BaseError
57
+ def initialize
58
+ super('inserting order failed')
59
+ end
60
+ end
61
+
62
+ class BatchTooBig < BaseError
63
+ def initialize
64
+ super('batch too big (max 50)')
65
+ end
66
+ end
67
+
68
+ class SubscriberAlreadyInactive < BaseError
69
+ def initialize
70
+ super('subscriber already inactive')
71
+ end
72
+ end
73
+
74
+ class GivenEmailIsTooShort < BaseError
75
+ def initialize
76
+ super('given email is too short')
77
+ end
78
+ end
79
+
80
+ class NoFormsAvailable < BaseError
81
+ def initialize
82
+ super('no forms available')
83
+ end
84
+ end
85
+
86
+ class ErrorSavingFilter < BaseError
87
+ def initialize
88
+ super('error saving filter')
89
+ end
90
+ end
91
+
92
+ ErrorMap = {
93
+ 1 => InvalidAPIKey,
94
+ 5 => NeedSessionBeforeUsage,
95
+ 10 => PermissionDenied,
96
+ 20 => DataNotFound,
97
+ 30 => EmailInvalid,
98
+ 40 => EmailBlacklisted,
99
+ 50 => DuplicateData,
100
+ 60 => SubscriberAlreadyActive,
101
+ 70 => InsertingOrderFailed,
102
+ 80 => BatchTooBig,
103
+ 90 => SubscriberAlreadyInactive,
104
+ 100 => GivenEmailIsTooShort,
105
+ 110 => NoFormsAvailable,
106
+ 120 => ErrorSavingFilter,
107
+ }
108
+
109
+ def self.lookup(code)
110
+ ErrorMap[code]
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,44 @@
1
+ module CleverReach
2
+ class ResponseDecorator < SimpleDelegator
3
+
4
+ def initialize(response)
5
+ super
6
+ @response = response
7
+ end
8
+
9
+ def valid?
10
+ # Let's be flexible when checking for the status.
11
+ answer_hash[:status] =~ /success/i
12
+ end
13
+
14
+ def status_code
15
+ answer_hash[:statuscode].to_i
16
+ end
17
+
18
+ def to_hash
19
+ data = answer_hash[:data]
20
+ clean! data.dup
21
+ end
22
+
23
+ private # ----------------------------------------------
24
+
25
+ def response_hash_key
26
+ @response.body.keys.find { |k| k.to_s =~ /_response$/ }
27
+ end
28
+
29
+ def answer_hash
30
+ @response.body[response_hash_key][:return]
31
+ end
32
+
33
+ def clean!(hash)
34
+ hash.reject! do |k,v|
35
+ if v.is_a? Hash
36
+ clean!(v); false
37
+ else
38
+ k.to_s =~ /^@/
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module CleverReach
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe CleverReach::Base do
4
+
5
+ let(:wsdl_url) { "http://api.test.com/wsdl" }
6
+ let(:api_key) { "12345" }
7
+ let(:client) { subject.client }
8
+
9
+ before :all do
10
+ CleverReach.configure do |config|
11
+ config.wsdl_url = wsdl_url
12
+ config.api_key = api_key
13
+ end
14
+ end
15
+
16
+ describe "#new" do # -------------------------------------
17
+
18
+ it "should use the configured API key" do
19
+ subject.api_key.should == api_key
20
+ end
21
+
22
+ end
23
+
24
+ describe "#client" do # ----------------------------------
25
+
26
+ it "should return configured Savon::Client" do
27
+ client.should be_instance_of(Savon::Client)
28
+ client.wsdl.document.should == wsdl_url
29
+ end
30
+
31
+ it "should re-use the client" do
32
+ client.should == client
33
+ end
34
+
35
+ end
36
+
37
+ describe "Response w/ errors" do # -----------------------
38
+
39
+ let(:body_with_errors) do
40
+ { :foo_response => { :return => { :status => 'ERROR', :statuscode => '30' } } }
41
+ end
42
+
43
+ let(:response) { stub(body: body_with_errors) }
44
+
45
+ before :each do
46
+ subject.should_receive(:request).with(:foo, anything).and_return(response)
47
+ end
48
+
49
+ it "should raise the appropiate error" do
50
+ lambda { subject.foo }.should raise_error(CleverReach::Errors::EmailInvalid)
51
+ end
52
+
53
+ end
54
+
55
+ # TODO Can't figure out how to stub/mock requests for Savon.
56
+ # I'v opened a new issue on github asking for some documentation.
57
+ #
58
+ # https://github.com/rubiii/savon/issues/307
59
+ #
60
+ # it "blah" do
61
+ # savon.expects(:client_get_details).with('apiKey' => api_key).returns({})
62
+ # subject.client_get_details
63
+ # end
64
+
65
+ # describe "A request" do # --------------------------------
66
+
67
+ # it "should return a ResponseDecorator" do
68
+ # subject.foobar.should be_instance_of(ResponseDecorator)
69
+ # end
70
+
71
+ # end
72
+
73
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe CleverReach::Configuration do
4
+
5
+ let(:klass) { CleverReach::Configuration }
6
+ let(:subject) { CleverReach.config }
7
+
8
+ it "should be a singleton" do
9
+ klass.included_modules.should include(Singleton)
10
+ end
11
+
12
+ describe "Default configuration" do
13
+
14
+ let(:defaults) do
15
+ {
16
+ wsdl_url: 'http://api.cleverreach.com/soap/interface_v5.1.php?wsdl'
17
+ }
18
+ end
19
+
20
+ it "should have some default settings" do
21
+ klass.defaults.should == defaults
22
+ end
23
+
24
+ it "should use the default settings automatically" do
25
+ keys = subject.instance_variables.map { |name| name.to_s.sub('@', '').to_sym }
26
+ keys.should include(*defaults.keys)
27
+ end
28
+
29
+ end
30
+
31
+ describe "Specifying a list id" do
32
+
33
+ before :each do
34
+ CleverReach.configure do |config|
35
+ config.list_id = '123'
36
+ end
37
+ end
38
+
39
+ it "should be readable" do
40
+ subject.list_id.should == '123'
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe CleverReach::Errors do
4
+
5
+ describe CleverReach::Errors::BaseError do # -------------
6
+
7
+ let(:subject) { CleverReach::Errors::BaseError.new }
8
+
9
+ it "should be subclass of StandardError" do
10
+ subject.should be_kind_of(StandardError)
11
+ end
12
+
13
+ end
14
+
15
+ describe "Custom errors" do # ----------------------------
16
+
17
+ let(:error_scope) { CleverReach::Errors }
18
+ let(:error_class) { error_scope::BaseError }
19
+
20
+ it "should define an error for 'invalid API Key'" do
21
+ error = error_scope::InvalidAPIKey.new
22
+ error.should be_kind_of(error_class)
23
+ error.message.should == 'invalid API key'
24
+ end
25
+
26
+ it "should define an error for 'need session before usage'" do
27
+ error = error_scope::NeedSessionBeforeUsage.new
28
+ error.should be_kind_of(error_class)
29
+ error.message.should == 'need session before usage'
30
+ end
31
+
32
+ it "should define an error for 'permission denied'" do
33
+ error = error_scope::PermissionDenied.new
34
+ error.should be_kind_of(error_class)
35
+ error.message.should == 'permission denied'
36
+ end
37
+
38
+ it "should define an error for 'data not found'" do
39
+ error = error_scope::DataNotFound.new
40
+ error.should be_kind_of(error_class)
41
+ error.message.should == 'data not found'
42
+ end
43
+
44
+ it "should define an error for 'email invalid'" do
45
+ error = error_scope::EmailInvalid.new
46
+ error.should be_kind_of(error_class)
47
+ error.message.should == 'email invalid'
48
+ end
49
+
50
+ it "should define an error for 'email blacklisted'" do
51
+ error = error_scope::EmailBlacklisted.new
52
+ error.should be_kind_of(error_class)
53
+ error.message.should == 'email blacklisted'
54
+ end
55
+
56
+ it "should define an error for 'duplicate data'" do
57
+ error = error_scope::DuplicateData.new
58
+ error.should be_kind_of(error_class)
59
+ error.message.should == 'duplicate data'
60
+ end
61
+
62
+ it "should define an error for 'subscriber already active'" do
63
+ error = error_scope::SubscriberAlreadyActive.new
64
+ error.should be_kind_of(error_class)
65
+ error.message.should == 'subscriber already active'
66
+ end
67
+
68
+ it "should define an error for 'inserting order failed'" do
69
+ error = error_scope::InsertingOrderFailed.new
70
+ error.should be_kind_of(error_class)
71
+ error.message.should == 'inserting order failed'
72
+ end
73
+
74
+ it "should define an error for 'batch to big (max 50)'" do
75
+ error = error_scope::BatchTooBig.new
76
+ error.should be_kind_of(error_class)
77
+ error.message.should == 'batch too big (max 50)'
78
+ end
79
+
80
+ it "should define an error for 'subscriber already inactive'" do
81
+ error = error_scope::SubscriberAlreadyInactive.new
82
+ error.should be_kind_of(error_class)
83
+ error.message.should == 'subscriber already inactive'
84
+ end
85
+
86
+ it "should define an error for 'given email is too short'" do
87
+ error = error_scope::GivenEmailIsTooShort.new
88
+ error.should be_kind_of(error_class)
89
+ error.message.should == 'given email is too short'
90
+ end
91
+
92
+ it "should define an error for 'no forms available'" do
93
+ error = error_scope::NoFormsAvailable.new
94
+ error.should be_kind_of(error_class)
95
+ error.message.should == 'no forms available'
96
+ end
97
+
98
+ it "should define an error for 'error saving filter'" do
99
+ error = error_scope::ErrorSavingFilter.new
100
+ error.should be_kind_of(error_class)
101
+ error.message.should == 'error saving filter'
102
+ end
103
+
104
+ end
105
+
106
+ describe ".lookup" do # ----------------------------------
107
+
108
+ CleverReach::Errors::ErrorMap.each do |code, klass|
109
+ it "should map error code #{code} to an error class '#{klass.name}'" do
110
+ subject.lookup(code).should == klass
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+
117
+ end
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe CleverReach::ResponseDecorator do
4
+
5
+ let(:body) do
6
+ { :client_get_details_response => {
7
+ :return => {
8
+ :status => "SUCCESS",
9
+ :message => { :"@xsi:type" => "xsd:string" },
10
+ :statuscode => "0",
11
+ :data => {
12
+ :id => "12345",
13
+ :firstname => "Stephan",
14
+ :name => "Schubert",
15
+ :company => "avianta UG",
16
+ :email => "stephan@frozencherry.de",
17
+ :login_domain => "12345.cleverreach.com",
18
+ :item => { :foo => "1", :"@xsi:type" => "foo" },
19
+ :"@xsi:type" => "tns:clientData"
20
+ },
21
+ :"@xsi:type" => "tns:returnClient" },
22
+ :"@xmlns:ns1"=>"CRS"
23
+ }
24
+ }
25
+ end
26
+
27
+ let(:response) { stub(body: body) }
28
+ let(:subject) { CleverReach::ResponseDecorator.new(response) }
29
+
30
+ describe "Method Delegation" do # ------------------------
31
+ let(:response) { stub(body: body, foo: 1) }
32
+
33
+ it "should check the underlying object" do
34
+ subject.foo.should == 1
35
+ end
36
+ end
37
+
38
+ describe "#to_hash" do # ----------------------------------
39
+
40
+ it "should return a cleaned hash with just the valuable data" do
41
+ subject.to_hash.should == {
42
+ id: "12345",
43
+ firstname: "Stephan",
44
+ name: "Schubert",
45
+ company: "avianta UG",
46
+ email: "stephan@frozencherry.de",
47
+ login_domain: "12345.cleverreach.com",
48
+ item: { foo: "1" }
49
+ }
50
+ end
51
+
52
+ end
53
+
54
+ describe "Response w/o errors" do # ----------------------
55
+ it { should be_valid }
56
+
57
+ it "should have status code 0" do
58
+ subject.status_code.should be_zero
59
+ end
60
+ end
61
+
62
+ describe "Response w/ errors" do # -----------------------
63
+ let(:body) do
64
+ { :some_method_response => {
65
+ :return => { :status => 'ERROR', :statuscode => '40' }
66
+ }
67
+ }
68
+ end
69
+
70
+ it { should_not be_valid }
71
+
72
+ it "should have a non-zero status code" do
73
+ subject.status_code.should_not be_zero
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe CleverReach do
4
+
5
+ let(:klass) { CleverReach }
6
+
7
+ it "should have a VERSION" do
8
+ klass::VERSION.should_not be_nil
9
+ end
10
+
11
+ describe "Configuration" do # ----------------------------
12
+
13
+ it "should have a configuration instance" do
14
+ klass.config.should be_instance_of(klass::Configuration)
15
+ end
16
+
17
+ it "should support configuration with a block" do
18
+ klass::Configuration.class_eval { attr_accessor :foo }
19
+
20
+ klass.configure do |config|
21
+ config.foo = :bar
22
+ end
23
+
24
+ klass.config.foo.should == :bar
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,29 @@
1
+ # Setup rubygems/bundler
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+
5
+ require 'savon'
6
+ require 'savon_spec'
7
+
8
+ # The gem itself
9
+ require 'clever_reach'
10
+
11
+ # This file was generated by the `rspec --init` command. Conventionally, all
12
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
13
+ # Require this file using `require "spec_helper"` to ensure that it is only
14
+ # loaded once.
15
+ #
16
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
17
+ RSpec.configure do |config|
18
+ config.treat_symbols_as_metadata_keys_with_true_values = true
19
+ config.run_all_when_everything_filtered = true
20
+ config.filter_run :focus
21
+
22
+ config.include Savon::Spec::Macros
23
+
24
+ # Run specs in random order to surface order dependencies. If you find an
25
+ # order dependency and want to debug it, you can fix the order by providing
26
+ # the seed, which is printed after each run.
27
+ # --seed 1234
28
+ config.order = 'random'
29
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clever_reach
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stephan Schubert
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ version_requirements: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ requirement: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ! '>='
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ prerelease: false
27
+ - !ruby/object:Gem::Dependency
28
+ name: savon_spec
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ prerelease: false
41
+ - !ruby/object:Gem::Dependency
42
+ name: savon
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.0'
54
+ prerelease: false
55
+ description: Ruby bindings for CleverReach's API
56
+ email:
57
+ - stephan@frozencherry.de
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - Gemfile
65
+ - LICENSE
66
+ - README.md
67
+ - Rakefile
68
+ - clever_reach.gemspec
69
+ - lib/clever_reach.rb
70
+ - lib/clever_reach/base.rb
71
+ - lib/clever_reach/configuration.rb
72
+ - lib/clever_reach/errors.rb
73
+ - lib/clever_reach/response_decorator.rb
74
+ - lib/clever_reach/version.rb
75
+ - spec/clever_reach/base_spec.rb
76
+ - spec/clever_reach/configuration_spec.rb
77
+ - spec/clever_reach/errors_spec.rb
78
+ - spec/clever_reach/response_decorator_spec.rb
79
+ - spec/clever_reach_spec.rb
80
+ - spec/spec_helper.rb
81
+ homepage: https://github.com/jazen/clever_reach
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project: clever_reach
101
+ rubygems_version: 2.1.11
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Ruby bindings for CleverReach's API
105
+ test_files:
106
+ - spec/clever_reach/base_spec.rb
107
+ - spec/clever_reach/configuration_spec.rb
108
+ - spec/clever_reach/errors_spec.rb
109
+ - spec/clever_reach/response_decorator_spec.rb
110
+ - spec/clever_reach_spec.rb
111
+ - spec/spec_helper.rb
112
+ has_rdoc: