morpheus 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/.autotest +12 -0
  2. data/.rspec +1 -0
  3. data/README.md +77 -0
  4. data/Rakefile +16 -0
  5. data/lib/morpheus.rb +2 -2
  6. data/lib/morpheus/base.rb +1 -1
  7. data/lib/morpheus/client/inflections.rb +1 -1
  8. data/lib/morpheus/configuration.rb +41 -43
  9. data/lib/morpheus/errors.rb +1 -1
  10. data/lib/morpheus/mixins/associations.rb +3 -1
  11. data/lib/morpheus/mixins/attributes.rb +66 -67
  12. data/lib/morpheus/mixins/conversion.rb +9 -13
  13. data/lib/morpheus/mixins/filtering.rb +4 -1
  14. data/lib/morpheus/mixins/finders.rb +4 -1
  15. data/lib/morpheus/mixins/introspection.rb +12 -16
  16. data/lib/morpheus/mixins/persistence.rb +25 -26
  17. data/lib/morpheus/mixins/reflections.rb +4 -1
  18. data/lib/morpheus/mixins/request_handling.rb +4 -1
  19. data/lib/morpheus/mixins/response_parsing.rb +12 -12
  20. data/lib/morpheus/mixins/url_support.rb +4 -1
  21. data/lib/morpheus/request.rb +34 -34
  22. data/lib/morpheus/response.rb +2 -2
  23. data/lib/morpheus/response_parser.rb +9 -4
  24. data/lib/morpheus/version.rb +1 -1
  25. data/morpheus.gemspec +4 -4
  26. data/spec/dummy/app/resources/author.rb +0 -1
  27. data/spec/dummy/app/resources/book.rb +0 -1
  28. data/spec/dummy/app/resources/dog.rb +3 -3
  29. data/spec/dummy/app/resources/meeting.rb +1 -2
  30. data/spec/dummy/config/application.rb +7 -36
  31. data/spec/dummy/config/environments/production.rb +1 -1
  32. data/spec/dummy/config/initializers/morpheus.rb +1 -1
  33. data/spec/dummy/config/locales/en.yml +1 -1
  34. data/spec/dummy/config/routes.rb +0 -56
  35. data/spec/morpheus/associations/association_spec.rb +51 -33
  36. data/spec/morpheus/associations/belongs_to_association_spec.rb +14 -2
  37. data/spec/morpheus/associations/has_many_association_spec.rb +31 -11
  38. data/spec/morpheus/associations/has_one_association_spec.rb +14 -2
  39. data/spec/morpheus/base_spec.rb +104 -100
  40. data/spec/morpheus/client/associations_spec.rb +43 -36
  41. data/spec/morpheus/client/log_subscriber_spec.rb +33 -0
  42. data/spec/morpheus/client/railtie_spec.rb +5 -0
  43. data/spec/morpheus/configuration_spec.rb +92 -113
  44. data/spec/morpheus/mixins/associations_spec.rb +90 -108
  45. data/spec/morpheus/mixins/attributes_spec.rb +71 -77
  46. data/spec/morpheus/mixins/conversion_spec.rb +49 -59
  47. data/spec/morpheus/mixins/filtering_spec.rb +13 -0
  48. data/spec/morpheus/mixins/finders_spec.rb +180 -217
  49. data/spec/morpheus/mixins/introspection_spec.rb +81 -124
  50. data/spec/morpheus/mixins/persistence_spec.rb +140 -133
  51. data/spec/morpheus/mixins/{reflection_spec.rb → reflections_spec.rb} +28 -28
  52. data/spec/morpheus/mixins/request_handling_spec.rb +21 -0
  53. data/spec/morpheus/mixins/response_parsing_spec.rb +10 -2
  54. data/spec/morpheus/mixins/url_support_spec.rb +29 -0
  55. data/spec/morpheus/reflection_spec.rb +21 -0
  56. data/spec/morpheus/relation_spec.rb +34 -58
  57. data/spec/morpheus/request_cache_spec.rb +33 -2
  58. data/spec/morpheus/request_queue_spec.rb +37 -0
  59. data/spec/morpheus/request_spec.rb +102 -1
  60. data/spec/morpheus/response_parser_spec.rb +17 -0
  61. data/spec/morpheus/response_spec.rb +55 -51
  62. data/spec/morpheus/type_caster_spec.rb +128 -118
  63. data/spec/morpheus/url_builder_spec.rb +41 -0
  64. data/spec/shared/active_model_lint_test.rb +2 -2
  65. data/spec/spec_helper.rb +7 -14
  66. data/spec/support/configuration.rb +3 -4
  67. metadata +32 -16
  68. data/README.rdoc +0 -44
  69. data/autotest/discover.rb +0 -7
  70. data/lib/morpheus/mock.rb +0 -66
  71. data/spec/morpheus/mock_spec.rb +0 -133
@@ -1,6 +1,9 @@
1
1
  module Morpheus
2
2
  module Filtering
3
- extend ActiveSupport::Concern
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
4
7
 
5
8
  module ClassMethods
6
9
 
@@ -1,6 +1,9 @@
1
1
  module Morpheus
2
2
  module Finders
3
- extend ActiveSupport::Concern
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
4
7
 
5
8
  module ClassMethods
6
9
 
@@ -1,25 +1,21 @@
1
1
  module Morpheus
2
2
  module Introspection
3
- extend ActiveSupport::Concern
4
3
 
5
- module InstanceMethods
6
-
7
- def persisted?
8
- !id.nil?
9
- end
10
-
11
- def new_record?
12
- !persisted?
13
- end
4
+ def persisted?
5
+ !id.nil?
6
+ end
14
7
 
15
- def destroyed?
16
- false
17
- end
8
+ def new_record?
9
+ !persisted?
10
+ end
18
11
 
19
- def respond_to?(method, include_private = false)
20
- attributes.include?(method) ? true : super
21
- end
12
+ def destroyed?
13
+ false
14
+ end
22
15
 
16
+ def respond_to?(method, include_private = false)
17
+ attributes.include?(method) ? true : super
23
18
  end
19
+
24
20
  end
25
21
  end
@@ -1,36 +1,35 @@
1
1
  module Morpheus
2
2
  module Persistence
3
- extend ActiveSupport::Concern
4
-
5
- module InstanceMethods
6
-
7
- def save(with_validations = true)
8
- attributes_for_save = { self.class.attributes_root => attributes_without_basic_attributes.reject { |k,v| v.nil? } }
9
-
10
- if with_validations
11
- return false unless valid?
12
- end
13
-
14
- if new_record?
15
- built_object = self.class.post(*UrlBuilder.save(self.class, nil, attributes_for_save))
16
- else
17
- built_object = self.class.put(*UrlBuilder.save(self.class, id, attributes_for_save))
18
- end
19
- built_object.instance_variables.each do |iv|
20
- self.instance_variable_set(iv, built_object.instance_variable_get(iv))
21
- end
22
- @valid
23
- end
24
3
 
25
- def update_attributes(new_attributes)
26
- merge_attributes(new_attributes)
27
- save
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ def save(with_validations = true)
9
+ attributes_for_save = { self.class.attributes_root => attributes_without_basic_attributes.reject { |k,v| v.nil? } }
10
+
11
+ if with_validations
12
+ return false unless valid?
28
13
  end
29
14
 
30
- def destroy
31
- self.class.delete(UrlBuilder.destroy(self.class, id))
15
+ if new_record?
16
+ built_object = self.class.post(*UrlBuilder.save(self.class, nil, attributes_for_save))
17
+ else
18
+ built_object = self.class.put(*UrlBuilder.save(self.class, id, attributes_for_save))
32
19
  end
20
+ built_object.instance_variables.each do |iv|
21
+ self.instance_variable_set(iv, built_object.instance_variable_get(iv))
22
+ end
23
+ @valid
24
+ end
25
+
26
+ def update_attributes(new_attributes)
27
+ merge_attributes(new_attributes)
28
+ save
29
+ end
33
30
 
31
+ def destroy
32
+ self.class.delete(UrlBuilder.destroy(self.class, id))
34
33
  end
35
34
 
36
35
  module ClassMethods
@@ -1,6 +1,9 @@
1
1
  module Morpheus
2
2
  module Reflections
3
- extend ActiveSupport::Concern
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
4
7
 
5
8
  module ClassMethods
6
9
 
@@ -1,6 +1,9 @@
1
1
  module Morpheus
2
2
  module RequestHandling
3
- extend ActiveSupport::Concern
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
4
7
 
5
8
  module ClassMethods
6
9
 
@@ -1,6 +1,9 @@
1
1
  module Morpheus
2
2
  module ResponseParsing
3
- extend ActiveSupport::Concern
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
4
7
 
5
8
  module ClassMethods
6
9
 
@@ -10,18 +13,15 @@ module Morpheus
10
13
 
11
14
  end
12
15
 
13
- module InstanceMethods
14
-
15
- def build_from_response(response)
16
- content = Yajl::Parser.parse(response.body)['content']
17
- if content.keys.include?('type')
18
- content['type'].constantize.new.merge_attributes(content)
19
- else
20
- merge_attributes(content)
21
- end
16
+ def build_from_response(response)
17
+ content = Yajl::Parser.parse(response.body)['content']
18
+ if content.keys.include?('type')
19
+ content['type'].constantize.new.merge_attributes(content)
20
+ else
21
+ merge_attributes(content)
22
22
  end
23
- private :build_from_response
24
-
25
23
  end
24
+ private :build_from_response
25
+
26
26
  end
27
27
  end
@@ -1,6 +1,9 @@
1
1
  module Morpheus
2
2
  module UrlSupport
3
- extend ActiveSupport::Concern
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
4
7
 
5
8
  module ClassMethods
6
9
 
@@ -2,40 +2,40 @@ module Morpheus
2
2
  class Request < Typhoeus::Request
3
3
  attr_reader :path, :params, :method
4
4
 
5
- def initialize(path, options = {})
6
- if options[:method] == :put
7
- options[:method] = :post
8
- options[:params].merge!(:_method => :put)
9
- end
10
-
11
- options[:username] = Configuration.username if Configuration.username
12
- options[:password] = Configuration.password if Configuration.password
13
-
14
- super(Configuration.host + path, options)
15
- end
16
-
17
- def cache_key
18
- [method, url, params].hash
19
- end
20
-
21
- def response=(response)
22
- RequestCache.cache[cache_key] = response
23
- response.tag_for_caching!
24
- super
25
- end
26
-
27
- def response
28
- RequestQueue.run! if RequestQueue.has_request?(self)
29
- RequestCache.cache[cache_key] || super
30
- end
31
-
32
- def self.enqueue(method, path, params)
33
- options = { :method => method }
34
- options.merge!(:params => params) if params
35
- new(path, options).tap do |request|
36
- RequestQueue.enqueue(request)
37
- end
38
- end
5
+ def initialize(path, options = {})
6
+ if options[:method] == :put
7
+ options[:method] = :post
8
+ options[:params].merge!(:_method => :put)
9
+ end
10
+
11
+ options[:username] = Configuration.username if Configuration.username
12
+ options[:password] = Configuration.password if Configuration.password
13
+
14
+ super(Configuration.host + path, options)
15
+ end
16
+
17
+ def cache_key
18
+ [method, url, params].hash
19
+ end
20
+
21
+ def response=(response)
22
+ RequestCache.cache[cache_key] = response
23
+ response.tag_for_caching!
24
+ super
25
+ end
26
+
27
+ def response
28
+ RequestQueue.run! if RequestQueue.has_request?(self)
29
+ RequestCache.cache[cache_key]|| super
30
+ end
31
+
32
+ def self.enqueue(method, path, params)
33
+ options = { :method => method }
34
+ options.merge!(:params => params) unless params.blank?
35
+ new(path, options).tap do |request|
36
+ RequestQueue.enqueue(request)
37
+ end
38
+ end
39
39
 
40
40
  end
41
41
  end
@@ -11,11 +11,11 @@ module Morpheus
11
11
  @cached = tagged_for_caching?
12
12
  end
13
13
  end
14
-
14
+
15
15
  def tag_for_caching!
16
16
  @tagged_for_caching = true
17
17
  end
18
-
18
+
19
19
  def tagged_for_caching?
20
20
  @tagged_for_caching ||= false
21
21
  end
@@ -10,8 +10,13 @@ module Morpheus
10
10
 
11
11
  def self.parse(owner, request, metadata)
12
12
  parser = new(owner, request, metadata)
13
-
14
- ActiveSupport::Notifications.instrument('request.morpheus', :url => request.url, :params => request.params, :method => request.method, :class => owner, :response => request.response) do
13
+ ActiveSupport::Notifications.instrument('request.morpheus',
14
+ :url => request.url,
15
+ :params => request.params,
16
+ :method => request.method,
17
+ :class => owner,
18
+ :response => request.response
19
+ ) do
15
20
  @parsed_response = parser.parse
16
21
  end
17
22
  RequestCache.cache.clear unless request.method == :get
@@ -40,7 +45,7 @@ module Morpheus
40
45
  def content
41
46
  @content ||= Yajl::Parser.parse(@response.body).try(:[], 'content')
42
47
  end
43
-
48
+
44
49
  def response_errors
45
50
  @response_errors ||= Yajl::Parser.parse(@response.body).try(:[], 'errors')
46
51
  end
@@ -56,7 +61,7 @@ module Morpheus
56
61
  end
57
62
  end
58
63
  end
59
-
64
+
60
65
  def build_object_with_attributes(attributes)
61
66
  if attributes.keys.include?('type')
62
67
  attributes['type'].constantize.new(attributes)
@@ -1,3 +1,3 @@
1
1
  module Morpheus
2
- VERSION = '0.3.6'
2
+ VERSION = '0.3.7'
3
3
  end
data/morpheus.gemspec CHANGED
@@ -17,11 +17,11 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_dependency 'yajl-ruby', '~> 0.8.2'
19
19
  gem.add_dependency 'typhoeus', '~> 0.2.4'
20
- gem.add_dependency 'activemodel', '~> 3.0.0'
21
- gem.add_dependency 'activesupport', '~> 3.0.0'
22
- gem.add_dependency 'i18n', '~> 0.5.0'
20
+ gem.add_dependency 'activemodel', '> 3.0.0'
21
+ gem.add_dependency 'activesupport', '> 3.0.0'
22
+ gem.add_dependency 'i18n', '> 0.5.0'
23
23
 
24
- gem.add_development_dependency 'rails', '~> 3.0.0'
24
+ gem.add_development_dependency 'rails', '> 3.0.0'
25
25
  gem.add_development_dependency 'sqlite3', '~> 1.3.3'
26
26
  gem.add_development_dependency 'rspec-rails', '~> 2.7.0'
27
27
  gem.add_development_dependency 'rcov', '~> 0.9.11'
@@ -1,5 +1,4 @@
1
1
  class Author < Morpheus::Base
2
2
  property :name
3
-
4
3
  has_many :books
5
4
  end
@@ -1,5 +1,4 @@
1
1
  class Book < Morpheus::Base
2
2
  property :title
3
-
4
3
  belongs_to :author
5
4
  end
@@ -1,10 +1,10 @@
1
1
  class Dog < Morpheus::Base
2
2
  property :name
3
3
  property :breed
4
-
5
4
  validates_presence_of :name
6
-
5
+
7
6
  def bark!
8
- "Bow-wow-wow"
7
+ 'Bow-wow-wow'
9
8
  end
9
+
10
10
  end
@@ -1,6 +1,5 @@
1
1
  class Meeting < Morpheus::Base
2
- property :title
3
-
2
+ property :title
4
3
  belongs_to :conference
5
4
  has_many :attendees
6
5
  has_one :speaker
@@ -1,45 +1,16 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
- require "active_model/railtie"
4
- require "active_record/railtie"
5
- require "action_controller/railtie"
6
- require "action_view/railtie"
7
- require "action_mailer/railtie"
3
+ require 'active_model/railtie'
4
+ require 'active_record/railtie'
5
+ require 'action_controller/railtie'
6
+ require 'action_view/railtie'
7
+ require 'action_mailer/railtie'
8
8
 
9
9
  Bundler.require
10
- require "morpheus"
10
+ require 'morpheus'
11
11
 
12
12
  module Dummy
13
13
  class Application < Rails::Application
14
- # Settings in config/environments/* take precedence over those specified here.
15
- # Application configuration should go into files in config/initializers
16
- # -- all .rb files in that directory are automatically loaded.
17
-
18
- # Custom directories with classes and modules you want to be autoloadable.
19
- config.autoload_paths += %W(#{config.root}/resources)
20
-
21
- # Only load the plugins named here, in the order given (default is alphabetical).
22
- # :all can be used as a placeholder for all plugins not explicitly named.
23
- # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
24
-
25
- # Activate observers that should always be running.
26
- # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
27
-
28
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
29
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
30
- # config.time_zone = 'Central Time (US & Canada)'
31
-
32
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
33
- # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
34
- # config.i18n.default_locale = :de
35
-
36
- # JavaScript files you want as :defaults (application.js is always included).
37
- # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
38
-
39
- # Configure the default encoding used in templates for Ruby 1.9.
40
- config.encoding = "utf-8"
41
-
42
- # Configure sensitive parameters which will be filtered from the log file.
43
- config.filter_parameters += [:password]
14
+ config.encoding = 'utf-8'
44
15
  end
45
16
  end
@@ -10,7 +10,7 @@ Dummy::Application.configure do
10
10
  config.action_controller.perform_caching = true
11
11
 
12
12
  # Specifies the header that your server uses for sending files
13
- config.action_dispatch.x_sendfile_header = "X-Sendfile"
13
+ config.action_dispatch.x_sendfile_header = 'X-Sendfile'
14
14
 
15
15
  # For nginx:
16
16
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'