smooth 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/Gemfile +10 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +24 -0
  7. data/app/assets/images/smooth/.keep +0 -0
  8. data/app/assets/javascripts/smooth/.keep +0 -0
  9. data/app/controllers/.keep +0 -0
  10. data/app/helpers/.keep +0 -0
  11. data/app/mailers/.keep +0 -0
  12. data/app/models/.keep +0 -0
  13. data/app/views/.keep +0 -0
  14. data/config/routes.rb +2 -0
  15. data/lib/smooth.rb +64 -0
  16. data/lib/smooth/api.rb +72 -0
  17. data/lib/smooth/api/policy.rb +18 -0
  18. data/lib/smooth/api/tracking.rb +31 -0
  19. data/lib/smooth/cache.rb +19 -0
  20. data/lib/smooth/command.rb +55 -0
  21. data/lib/smooth/command/instrumented.rb +51 -0
  22. data/lib/smooth/configuration.rb +25 -0
  23. data/lib/smooth/documentation.rb +31 -0
  24. data/lib/smooth/dsl.rb +36 -0
  25. data/lib/smooth/event.rb +27 -0
  26. data/lib/smooth/example.rb +6 -0
  27. data/lib/smooth/ext/core.rb +5 -0
  28. data/lib/smooth/ext/mutations.rb +1 -0
  29. data/lib/smooth/query.rb +62 -0
  30. data/lib/smooth/resource.rb +173 -0
  31. data/lib/smooth/resource/tracking.rb +17 -0
  32. data/lib/smooth/serializer.rb +94 -0
  33. data/lib/smooth/version.rb +3 -0
  34. data/smooth.gemspec +36 -0
  35. data/spec/dummy/README.rdoc +28 -0
  36. data/spec/dummy/Rakefile +6 -0
  37. data/spec/dummy/app/apis/application_api.rb +34 -0
  38. data/spec/dummy/app/assets/images/.keep +0 -0
  39. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  40. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  41. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  42. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  43. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  44. data/spec/dummy/app/mailers/.keep +0 -0
  45. data/spec/dummy/app/models/.keep +0 -0
  46. data/spec/dummy/app/models/author.rb +2 -0
  47. data/spec/dummy/app/models/book.rb +2 -0
  48. data/spec/dummy/app/models/concerns/.keep +0 -0
  49. data/spec/dummy/app/resources/books.rb +103 -0
  50. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  51. data/spec/dummy/bin/bundle +3 -0
  52. data/spec/dummy/bin/rails +4 -0
  53. data/spec/dummy/bin/rake +4 -0
  54. data/spec/dummy/config.ru +4 -0
  55. data/spec/dummy/config/application.rb +30 -0
  56. data/spec/dummy/config/boot.rb +5 -0
  57. data/spec/dummy/config/database.yml +25 -0
  58. data/spec/dummy/config/environment.rb +5 -0
  59. data/spec/dummy/config/environments/development.rb +37 -0
  60. data/spec/dummy/config/environments/production.rb +82 -0
  61. data/spec/dummy/config/environments/test.rb +39 -0
  62. data/spec/dummy/config/initializers/assets.rb +8 -0
  63. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  65. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  66. data/spec/dummy/config/initializers/inflections.rb +16 -0
  67. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  68. data/spec/dummy/config/initializers/session_store.rb +3 -0
  69. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  70. data/spec/dummy/config/locales/en.yml +23 -0
  71. data/spec/dummy/config/routes.rb +3 -0
  72. data/spec/dummy/config/secrets.yml +22 -0
  73. data/spec/dummy/db/development.sqlite3 +0 -0
  74. data/spec/dummy/db/migrate/20140822065900_create_books.rb +11 -0
  75. data/spec/dummy/db/migrate/20140822065916_create_authors.rb +9 -0
  76. data/spec/dummy/db/schema.rb +30 -0
  77. data/spec/dummy/db/test.sqlite3 +0 -0
  78. data/spec/dummy/lib/assets/.keep +0 -0
  79. data/spec/dummy/log/.keep +0 -0
  80. data/spec/dummy/public/404.html +67 -0
  81. data/spec/dummy/public/422.html +67 -0
  82. data/spec/dummy/public/500.html +66 -0
  83. data/spec/dummy/public/favicon.ico +0 -0
  84. data/spec/lib/smooth/api/policy_spec.rb +5 -0
  85. data/spec/lib/smooth/api_spec.rb +23 -0
  86. data/spec/lib/smooth/cache_spec.rb +8 -0
  87. data/spec/lib/smooth/command_spec.rb +36 -0
  88. data/spec/lib/smooth/configuration_spec.rb +16 -0
  89. data/spec/lib/smooth/event_spec.rb +20 -0
  90. data/spec/lib/smooth/example_spec.rb +5 -0
  91. data/spec/lib/smooth/query_spec.rb +5 -0
  92. data/spec/lib/smooth/resource_spec.rb +38 -0
  93. data/spec/lib/smooth/serializer_spec.rb +26 -0
  94. data/spec/spec_helper.rb +18 -0
  95. metadata +394 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4909a00991f205fc93b1ed479717c74635f3bef5
4
+ data.tar.gz: 3dbf7cda0d581469b22a297f6a0e8b9022e76583
5
+ SHA512:
6
+ metadata.gz: b8026b76b623987b8428fce674926a2b1a7e171d87eb86ec4c0321b481d6223205d0f9d9be5c393453534e61937446211ac1b59ddf3257c86985ff5b336d891c
7
+ data.tar.gz: ade1e5f9874ea6e897ff152964d29ea4b1bea9837d8b313ad5adc66bd155ae90607a649c7a9b6debf6c892a12740a934bdbbe2d18e7868d4b293db344249f911
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ log/*.log
19
+ spec/dummy/log/*.log
20
+ spec/dummy/tmp/**/*
21
+ .vimrc
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in smooth.gemspec
4
+ gemspec
5
+
6
+ group :test, :development do
7
+ gem 'pry'
8
+ gem 'pry-nav'
9
+ gem 'mutations', github: "datapimp/mutations", branch: "inline-documentation"
10
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jonathan Soeder
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Smooth
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'smooth'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install smooth
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1,24 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ #!/usr/bin/env rake
4
+ begin
5
+ require 'bundler/setup'
6
+ rescue LoadError
7
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
8
+ end
9
+
10
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
11
+ load 'rails/tasks/engine.rake'
12
+
13
+ Bundler::GemHelper.install_tasks
14
+
15
+ Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
16
+
17
+ require 'rspec/core'
18
+ require 'rspec/core/rake_task'
19
+
20
+ desc "Run all specs in spec directory (excluding plugin specs)"
21
+
22
+ RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
23
+
24
+ task :default => :spec
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,64 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ begin
4
+ require 'hashie'
5
+ require 'active_support/core_ext'
6
+ require 'active_support/notifications'
7
+ require 'active_model_serializers'
8
+ require 'mutations'
9
+ require 'pry'
10
+ rescue LoadError
11
+ require 'rubygems'
12
+ require 'hashie'
13
+ require 'active_support/core_ext'
14
+ require 'pry'
15
+ end
16
+
17
+
18
+ require "smooth/ext/core"
19
+ require "smooth/documentation"
20
+ require "smooth/event"
21
+
22
+ require "smooth/api"
23
+ require "smooth/cache"
24
+ require "smooth/command"
25
+ require "smooth/example"
26
+ require "smooth/query"
27
+ require "smooth/resource"
28
+ require "smooth/serializer"
29
+
30
+ require "smooth/configuration"
31
+ require "smooth/version"
32
+
33
+ module Smooth
34
+ extend Smooth::Api::Tracking
35
+ extend Smooth::Resource::Tracking
36
+ extend Smooth::Event::Adapter
37
+
38
+ def self.command
39
+ config.command_class
40
+ end
41
+
42
+ def self.query
43
+ config.query_class
44
+ end
45
+
46
+ def self.serializer
47
+ config.serializer_class
48
+ end
49
+
50
+ def self.config
51
+ Smooth::Configuration.instance
52
+ end
53
+
54
+ class Engine < ::Rails::Engine
55
+ initializer 'smooth.load_resources', :before => :build_middleware_stack do |app|
56
+ app_root = app.config.root.join("app")
57
+
58
+ %w{smooth apis resources}.each do |check_folder|
59
+ app_root.join(check_folder).children.each {|f| require(f) } if app_root.join(check_folder).exist?
60
+ end
61
+ end
62
+
63
+ end if defined?(::Rails)
64
+ end
@@ -0,0 +1,72 @@
1
+ require 'smooth/dsl'
2
+
3
+ module Smooth
4
+ class Api
5
+ include Smooth::Documentation
6
+
7
+ def self.default
8
+ @default ||= Smooth::Api.new
9
+ end
10
+
11
+ attr_accessor :name,
12
+ :_version_config,
13
+ :_resources,
14
+ :_policies
15
+
16
+ def initialize(name, options={})
17
+ @name = name
18
+ @options = options
19
+
20
+ @_resources = {}
21
+ @_policies = {}
22
+ end
23
+
24
+ def version config=nil
25
+ @_version_config = config if config
26
+ @_version_config
27
+ end
28
+
29
+ def policy policy_name, options={}, &block
30
+ if obj = _policies[policy_name.to_sym]
31
+ obj.apply_options(options) unless options.empty?
32
+ obj.instance_eval(&block) if block_given?
33
+ obj
34
+
35
+ elsif options.empty? && !block_given?
36
+ nil
37
+
38
+ elsif block_given?
39
+ obj = Smooth::Api::Policy.new(policy_name, options, &block)
40
+ _resources[policy_name.to_sym] = obj
41
+ end
42
+ end
43
+
44
+ def has_resource? resource_name
45
+ resources.has_key?(resource_name.to_sym)
46
+ end
47
+
48
+ def resource resource_name, options={}, &block
49
+ api_name = self.name
50
+
51
+ if existing = _resources[resource_name.to_sym]
52
+ existing.apply_options(options) unless options.empty?
53
+ existing.instance_eval(&block) if block_given?
54
+ existing
55
+
56
+ elsif options.empty? && !block_given?
57
+ existing = nil
58
+
59
+ elsif block_given?
60
+ created = Smooth::Resource.new(resource_name, options, &block).tap do |obj|
61
+ obj.api_name = api_name
62
+ end
63
+
64
+ _resources[resource_name.to_sym] = created
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+ require 'smooth/api/tracking'
72
+ require 'smooth/api/policy'
@@ -0,0 +1,18 @@
1
+ module Smooth
2
+ class Api
3
+ class Policy
4
+ include Smooth::Documentation
5
+
6
+ attr_accessor :name
7
+
8
+ def initialize name, options={}
9
+ @name = name
10
+ @options = options
11
+ end
12
+
13
+ def apply_options *opts
14
+ @options.send(:merge!, *opts)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module Smooth
2
+ class Api
3
+ module Tracking
4
+ def apis
5
+ @@apis ||= {}
6
+ end
7
+
8
+ def fetch_api name, &block
9
+ existing = apis[name.to_sym]
10
+
11
+ if existing.nil? && block_given?
12
+ existing = apis[name.to_sym] = block.call(name.to_sym)
13
+ end
14
+
15
+ existing
16
+ end
17
+
18
+ def current_api
19
+ apis[current_api_name] ||= Smooth::Api.default()
20
+ end
21
+
22
+ def current_api_name= value
23
+ @@current_api_name = value
24
+ end
25
+
26
+ def current_api_name
27
+ (@@current_api_name || :default).to_sym
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,19 @@
1
+ require 'singleton'
2
+
3
+ module Smooth
4
+ def self.cache
5
+ Smooth::Cache.instance
6
+ end
7
+
8
+ class Cache
9
+ include Singleton
10
+
11
+ def method_missing meth, *args, &block
12
+ if defined? ::Rails
13
+ return ::Rails.cache.send(meth, *args, &block)
14
+ end
15
+
16
+ super
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ require 'smooth/ext/mutations'
2
+ require 'smooth/command/instrumented'
3
+
4
+ class Smooth::Command < Mutations::Command
5
+ include Instrumented
6
+
7
+ class_attribute :resource_name,
8
+ :command_action,
9
+ :event_namespace
10
+
11
+ def self.scope setting
12
+ @@scope = setting
13
+ end
14
+
15
+ def self.params *args, &block
16
+ send(:required, *args, &block)
17
+ end
18
+
19
+ def self.event_namespace
20
+ @event_namespace || "#{ command_action }.#{ resource_name.singularize.underscore }".downcase
21
+ end
22
+
23
+ def event_namespace; self.class.event_namespace; end
24
+
25
+ # DSL Hooks
26
+ #
27
+ #
28
+ def self.configure options, resource=nil
29
+ resource ||= Smooth.current_resource
30
+ klass = define_or_open(options, resource)
31
+
32
+ Array(options.blocks).each do |blk|
33
+ klass.class_eval(&blk)
34
+ end
35
+
36
+ klass
37
+ end
38
+
39
+ def self.define_or_open(options, resource)
40
+ resource_name = resource.name.to_s.singularize
41
+ base = Smooth.command
42
+
43
+ name = options.name.to_s.camelize
44
+ klass = "#{ name }#{ resource_name }"
45
+
46
+ if command_klass = Object.const_get(klass) rescue nil
47
+ return command_klass
48
+ end
49
+
50
+ Object.const_set(klass, Class.new(base)).tap do |k|
51
+ k.resource_name = resource.name.to_s
52
+ k.command_action = options.name.to_s
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,51 @@
1
+ module Smooth
2
+ class Command < Mutations::Command
3
+ module Instrumented
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ base.enable_event_tracking! # if Smooth.config.enable_event_tracking_by_default?
7
+ end
8
+
9
+ module Overrides
10
+ def run
11
+ run_with_instrumentation
12
+ end
13
+ end
14
+
15
+ module Restored
16
+ def run
17
+ run_with_outcome
18
+ end
19
+ end
20
+
21
+ module ClassMethods
22
+ def enable_event_tracking!
23
+ send(:include, Smooth::Event::Adapter)
24
+ send(:include, Overrides)
25
+ end
26
+
27
+ def disable_event_tracking!
28
+ send(:include, Restored)
29
+ end
30
+ end
31
+
32
+ def run_with_instrumentation
33
+ outcome = run_with_outcome
34
+
35
+ if outcome.success?
36
+ result = outcome.result
37
+ track_event("#{ event_namespace }", result: result, inputs: inputs)
38
+ result
39
+ else
40
+ track_event("errors/#{ event_namespace }", errors: outcome.errors, inputs: inputs)
41
+ outcome
42
+ end
43
+ end
44
+
45
+ def run_with_outcome
46
+ return validation_outcome if has_errors?
47
+ validation_outcome(execute)
48
+ end
49
+ end
50
+ end
51
+ end