moon 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.
Files changed (67) hide show
  1. data/README.rdoc +2 -0
  2. data/Rakefile +10 -3
  3. data/lib/moon.rb +0 -2
  4. data/lib/moon/action.rb +4 -3
  5. data/lib/moon/action/inject_timestamps.rb +44 -0
  6. data/lib/moon/action/model.rb +1 -2
  7. data/lib/moon/action/model/destroy.rb +4 -26
  8. data/lib/moon/action/model/index.rb +10 -17
  9. data/lib/moon/action/model/show.rb +9 -23
  10. data/lib/moon/action/model/store.rb +20 -0
  11. data/lib/moon/action/models/finder.rb +14 -14
  12. data/lib/moon/action/models/initializer.rb +6 -5
  13. data/lib/moon/action/models/updater.rb +1 -4
  14. data/lib/moon/action/rebuild_arrays.rb +1 -4
  15. data/lib/moon/action/{reference_object.rb → reference.rb} +1 -1
  16. data/lib/moon/action/respond_blank.rb +9 -0
  17. data/lib/moon/action/transfer.rb +30 -0
  18. data/lib/moon/action/valid_models_required.rb +13 -6
  19. data/lib/moon/application.rb +12 -7
  20. data/lib/moon/application/configuration.rb +55 -0
  21. data/lib/moon/application/rack.rb +17 -7
  22. data/lib/moon/context.rb +1 -1
  23. data/lib/moon/formatter.rb +4 -13
  24. data/lib/moon/formatter/generic.rb +17 -4
  25. data/lib/moon/response/json.rb +1 -0
  26. data/lib/moon/response/json/blank.rb +9 -0
  27. data/lib/moon/response/json/collection.rb +2 -2
  28. data/lib/moon/response/json/model.rb +3 -3
  29. data/lib/moon/validator.rb +17 -45
  30. data/lib/moon/validator/format.rb +4 -23
  31. data/lib/moon/validator/length.rb +8 -33
  32. data/lib/moon/validator/presence.rb +4 -17
  33. data/spec/lib/moon/action/inject_timestamps_spec.rb +46 -0
  34. data/spec/lib/moon/action/model/destroy_spec.rb +6 -44
  35. data/spec/lib/moon/action/model/index_spec.rb +8 -25
  36. data/spec/lib/moon/action/model/show_spec.rb +33 -25
  37. data/spec/lib/moon/action/model/store_spec.rb +77 -0
  38. data/spec/lib/moon/action/models/finder_spec.rb +25 -11
  39. data/spec/lib/moon/action/models/initializer_spec.rb +7 -5
  40. data/spec/lib/moon/action/models/updater_spec.rb +5 -3
  41. data/spec/lib/moon/action/rebuild_arrays_spec.rb +3 -3
  42. data/spec/lib/moon/action/{reference_object_spec.rb → reference_spec.rb} +1 -1
  43. data/spec/lib/moon/action/respond_blank_spec.rb +24 -0
  44. data/spec/lib/moon/action/transfer_spec.rb +30 -0
  45. data/spec/lib/moon/action/valid_models_required_spec.rb +19 -17
  46. data/spec/lib/moon/application/configuration_spec.rb +75 -0
  47. data/spec/lib/moon/application/rack_spec.rb +6 -5
  48. data/spec/lib/moon/formatter/generic_spec.rb +13 -3
  49. data/spec/lib/moon/formatter_spec.rb +4 -10
  50. data/spec/lib/moon/response/json/blank_spec.rb +19 -0
  51. data/spec/lib/moon/response/json/collection_spec.rb +5 -4
  52. data/spec/lib/moon/response/json/model_spec.rb +5 -4
  53. data/spec/lib/moon/validator/format_spec.rb +8 -25
  54. data/spec/lib/moon/validator/length_spec.rb +10 -36
  55. data/spec/lib/moon/validator/presence_spec.rb +11 -28
  56. data/spec/lib/moon/validator_spec.rb +10 -59
  57. metadata +34 -28
  58. data/lib/moon/action/base.rb +0 -16
  59. data/lib/moon/action/model/create.rb +0 -45
  60. data/lib/moon/action/model/update.rb +0 -42
  61. data/lib/moon/application/routes.rb +0 -16
  62. data/lib/moon/formatter/base.rb +0 -15
  63. data/spec/lib/moon/action/base_spec.rb +0 -29
  64. data/spec/lib/moon/action/model/create_spec.rb +0 -111
  65. data/spec/lib/moon/action/model/update_spec.rb +0 -91
  66. data/spec/lib/moon/application/routes_spec.rb +0 -26
  67. data/spec/lib/moon/formatter/base_spec.rb +0 -30
@@ -3,6 +3,8 @@
3
3
 
4
4
  No fixed API yet. Documentation will follow...
5
5
 
6
+ http://travis-ci.org/phifty/moon.png
7
+
6
8
  == Development
7
9
 
8
10
  Development has been done test-driven and the code follows at most the Clean Code paradigms. Code smells has been
data/Rakefile CHANGED
@@ -1,4 +1,13 @@
1
- require 'rake/rdoctask'
1
+ require 'rubygems'
2
+ require 'rdoc'
3
+ require 'rdoc/task'
4
+
5
+ # Cucumber
6
+ require 'cucumber/rake/task'
7
+
8
+ Cucumber::Rake::Task.new(:features) do |task|
9
+ task.cucumber_opts = "--format pretty"
10
+ end
2
11
 
3
12
  # RSpec
4
13
  require 'rspec/core/rake_task'
@@ -35,12 +44,10 @@ end
35
44
 
36
45
  namespace :gem do
37
46
 
38
- desc "Builds the gem"
39
47
  task :build do
40
48
  system "gem build *.gemspec && mkdir -p pkg/ && mv *.gem pkg/"
41
49
  end
42
50
 
43
- desc "Builds and installs the gem"
44
51
  task :install => :build do
45
52
  system "gem install pkg/"
46
53
  end
@@ -1,6 +1,4 @@
1
1
  require 'gom'
2
- require 'gom/filesystem-adapter'
3
- require 'gom/couchdb-adapter'
4
2
 
5
3
  module Moon
6
4
 
@@ -1,12 +1,13 @@
1
1
 
2
2
  module Moon::Action
3
3
 
4
- autoload :Base, File.join(File.dirname(__FILE__), "action", "base")
5
- autoload :BuildOptionHashes, File.join(File.dirname(__FILE__), "action", "build_option_hashes")
4
+ autoload :InjectTimestamps, File.join(File.dirname(__FILE__), "action", "inject_timestamps")
6
5
  autoload :Model, File.join(File.dirname(__FILE__), "action", "model")
7
6
  autoload :Models, File.join(File.dirname(__FILE__), "action", "models")
8
7
  autoload :RebuildArrays, File.join(File.dirname(__FILE__), "action", "rebuild_arrays")
9
- autoload :ReferenceObject, File.join(File.dirname(__FILE__), "action", "reference_object")
8
+ autoload :Reference, File.join(File.dirname(__FILE__), "action", "reference")
9
+ autoload :RespondBlank, File.join(File.dirname(__FILE__), "action", "respond_blank")
10
+ autoload :Transfer, File.join(File.dirname(__FILE__), "action", "transfer")
10
11
  autoload :ValidModelsRequired, File.join(File.dirname(__FILE__), "action", "valid_models_required")
11
12
 
12
13
  end
@@ -0,0 +1,44 @@
1
+
2
+ class Moon::Action::InjectTimestamps
3
+
4
+ def initialize(model_key)
5
+ @model_key = model_key
6
+ end
7
+
8
+ def perform(context)
9
+ @context = context
10
+ fetch_model
11
+ fetch_id
12
+ fetch_now
13
+ inject_created_at unless has_id?
14
+ inject_update_at
15
+ nil
16
+ end
17
+
18
+ private
19
+
20
+ def fetch_model
21
+ @model = @context.models[@model_key]
22
+ end
23
+
24
+ def fetch_id
25
+ @id = GOM::Object.id @model
26
+ end
27
+
28
+ def fetch_now
29
+ @now = Time.now
30
+ end
31
+
32
+ def has_id?
33
+ !!@id
34
+ end
35
+
36
+ def inject_created_at
37
+ @model.created_at = @now
38
+ end
39
+
40
+ def inject_update_at
41
+ @model.updated_at = @now
42
+ end
43
+
44
+ end
@@ -1,10 +1,9 @@
1
1
 
2
2
  module Moon::Action::Model
3
3
 
4
- autoload :Create, File.join(File.dirname(__FILE__), "model", "create")
5
4
  autoload :Destroy, File.join(File.dirname(__FILE__), "model", "destroy")
6
5
  autoload :Index, File.join(File.dirname(__FILE__), "model", "index")
7
6
  autoload :Show, File.join(File.dirname(__FILE__), "model", "show")
8
- autoload :Update, File.join(File.dirname(__FILE__), "model", "update")
7
+ autoload :Store, File.join(File.dirname(__FILE__), "model", "store")
9
8
 
10
9
  end
@@ -2,12 +2,12 @@
2
2
  # Generic model destroy action. Removes the specified model from the storage.
3
3
  class Moon::Action::Model::Destroy
4
4
 
5
- def initialize(context)
6
- @context = context
5
+ def initialize(model_symbol)
6
+ @model_symbol = model_symbol
7
7
  end
8
8
 
9
- def perform
10
- model = self.model
9
+ def perform(context)
10
+ model = context.models[@model_symbol]
11
11
  model_class = model.class
12
12
  if model
13
13
  GOM::Storage.remove model
@@ -17,26 +17,4 @@ class Moon::Action::Model::Destroy
17
17
  end
18
18
  end
19
19
 
20
- def model
21
- @context.models[self.class.model_symbol]
22
- end
23
-
24
- def self.model_symbol=(value)
25
- @model_symbol = value
26
- end
27
-
28
- def self.model_symbol
29
- @model_symbol
30
- end
31
-
32
- def self.perform(context)
33
- new(context).perform
34
- end
35
-
36
- def self.[](model_symbol)
37
- klass = self.dup
38
- klass.model_symbol = model_symbol
39
- klass
40
- end
41
-
42
20
  end
@@ -2,30 +2,23 @@
2
2
  # Common model index action
3
3
  class Moon::Action::Model::Index
4
4
 
5
- def initialize(context)
6
- @context = context
7
- end
8
-
9
- def perform
10
- Moon::Response::JSON::Collection.new @context.collections[self.class.collection_key]
5
+ def initialize(collection_key)
6
+ @collection_key = collection_key
11
7
  end
12
8
 
13
- def self.collection_key=(value)
14
- @collection_key = value
9
+ def perform(context)
10
+ @context = context
11
+ Moon::Response::JSON::Collection.new collection, formatters
15
12
  end
16
13
 
17
- def self.collection_key
18
- @collection_key
19
- end
14
+ private
20
15
 
21
- def self.perform(context)
22
- new(context).perform
16
+ def collection
17
+ @context.collections[@collection_key]
23
18
  end
24
19
 
25
- def self.[](collection_key)
26
- klass = self.dup
27
- klass.collection_key = collection_key
28
- klass
20
+ def formatters
21
+ @context.application.configuration.formatters
29
22
  end
30
23
 
31
24
  end
@@ -2,31 +2,17 @@
2
2
  # Common model show action
3
3
  class Moon::Action::Model::Show
4
4
 
5
- def initialize(context)
6
- @context = context
5
+ def initialize(model_key)
6
+ @model_key = model_key
7
7
  end
8
8
 
9
- def perform
10
- model_key = self.class.model_key
11
- Moon::Response::JSON::Model.new model_key, @context.models[model_key]
12
- end
13
-
14
- def self.model_key=(value)
15
- @model_key = value
16
- end
17
-
18
- def self.model_key
19
- @model_key
20
- end
21
-
22
- def self.perform(context)
23
- new(context).perform
24
- end
25
-
26
- def self.[](model_key)
27
- klass = self.dup
28
- klass.model_key = model_key
29
- klass
9
+ def perform(context)
10
+ model = context.models[@model_key]
11
+ if model
12
+ Moon::Response::JSON::Model.new @model_key, context.models[@model_key], context.application.configuration.formatters
13
+ else
14
+ Moon::Response::JSON::Message.new 404, "Model not found."
15
+ end
30
16
  end
31
17
 
32
18
  end
@@ -0,0 +1,20 @@
1
+
2
+ # Generic model update action. Stores the specified model to the storage.
3
+ class Moon::Action::Model::Store
4
+
5
+ def initialize(model_symbol)
6
+ @model_symbol = model_symbol
7
+ end
8
+
9
+ def perform(context)
10
+ model = context.models[@model_symbol]
11
+ if model
12
+ storage_name = GOM::Object.storage_name(model) || context.application.storage_name
13
+ GOM::Storage.store model, storage_name
14
+ nil
15
+ else
16
+ Moon::Response::JSON::Message.new 200, "No model initialized."
17
+ end
18
+ end
19
+
20
+ end
@@ -1,33 +1,33 @@
1
1
 
2
- # This action takes parameters that ends with '_id' out of the context and searches the fitting model
3
- # for it. The result is assign to the context.
2
+ # This action takes parameter and session keys that ends with '_id' out of the context and searches the fitting model
3
+ # for it. The result is assign to the context models.
4
4
  class Moon::Action::Models::Finder
5
5
 
6
- def initialize(context)
6
+ def perform(context)
7
7
  @context = context
8
- end
9
-
10
- def perform
11
- find_models
8
+ find_session_models
9
+ find_parameter_models
12
10
  nil
13
11
  end
14
12
 
15
13
  private
16
14
 
17
- def find_models
15
+ def find_session_models
16
+ @context.session.each do |key, value|
17
+ find_model key, value, "current_" if self.class.point_to_model?(key)
18
+ end
19
+ end
20
+
21
+ def find_parameter_models
18
22
  @context.parameters.each do |key, value|
19
23
  find_model key, value if self.class.point_to_model?(key)
20
24
  end
21
25
  end
22
26
 
23
- def find_model(key, id)
27
+ def find_model(key, id, prefix = "")
24
28
  model_name = self.class.model_name key
25
29
  model = GOM::Storage.fetch id
26
- @context.models[model_name.downcase.to_sym] = model
27
- end
28
-
29
- def self.perform(context)
30
- new(context).perform
30
+ @context.models[:"#{prefix}#{model_name.downcase}"] = model
31
31
  end
32
32
 
33
33
  private
@@ -3,16 +3,17 @@
3
3
  # a model from it.
4
4
  class Moon::Action::Models::Initializer
5
5
 
6
- def self.perform(context)
7
- initialize_models context
6
+ def perform(context)
7
+ @context = context
8
+ initialize_models
8
9
  nil
9
10
  end
10
11
 
11
12
  private
12
13
 
13
- def self.initialize_models(context)
14
- context.parameters.each do |key, value|
15
- context.models[key.to_sym] = Builder.new(key, value).model
14
+ def initialize_models
15
+ @context.parameters.each do |key, value|
16
+ @context.models[key.to_sym] = Builder.new(key, value).model
16
17
  end
17
18
  end
18
19
 
@@ -2,11 +2,8 @@
2
2
  # Uses the parameters in the context and tries to update the models.
3
3
  class Moon::Action::Models::Updater
4
4
 
5
- def initialize(context)
5
+ def perform(context)
6
6
  @context = context
7
- end
8
-
9
- def perform
10
7
  @context.models.each do |model_key, model|
11
8
  Model.new(model, @context.parameters[model_key]).update
12
9
  end
@@ -2,11 +2,8 @@
2
2
  # Converts each hash with numeric keys { "0" => "one", "1" => "two" } into arrays [ "one", "two" ].
3
3
  class Moon::Action::RebuildArrays
4
4
 
5
- def initialize(context)
5
+ def perform(context)
6
6
  @context = context
7
- end
8
-
9
- def perform
10
7
  @context.parameters = self.class.rebuild_arrays @context.parameters
11
8
  nil
12
9
  end
@@ -1,6 +1,6 @@
1
1
 
2
2
  # The action creates a reference to the given store object and stores it in the given model attribute.
3
- class Moon::Action::ReferenceObject
3
+ class Moon::Action::Reference
4
4
 
5
5
  def initialize(options)
6
6
  from, to = options.values_at :from, :to
@@ -0,0 +1,9 @@
1
+
2
+ # The action responses a blank json response without any conditions.
3
+ class Moon::Action::RespondBlank
4
+
5
+ def perform(context)
6
+ Moon::Response::JSON::Blank.new
7
+ end
8
+
9
+ end
@@ -0,0 +1,30 @@
1
+
2
+ # The action transfers a value from the given store object and stores it in the given model attribute.
3
+ class Moon::Action::Transfer
4
+
5
+ def initialize(options)
6
+ from, to = options.values_at :from, :to
7
+ @store_method, @store_key = from
8
+ @model_key, @model_attribute = to
9
+ end
10
+
11
+ def perform(context)
12
+ @context = context
13
+ fetch_value
14
+ store_value
15
+ nil
16
+ end
17
+
18
+ private
19
+
20
+ def fetch_value
21
+ store = @context.send @store_method.to_sym
22
+ @value = store[@store_key.to_sym]
23
+ end
24
+
25
+ def store_value
26
+ model = @context.models[@model_key.to_sym]
27
+ model.send :"#{@model_attribute}=", @value
28
+ end
29
+
30
+ end
@@ -2,20 +2,27 @@
2
2
  # The action checks if every model in the context is valid.
3
3
  class Moon::Action::ValidModelsRequired
4
4
 
5
- def self.perform(context)
6
- validation_errors = validate_models context
5
+ def perform(context)
6
+ @context = context
7
+ validation_errors = validate_models
7
8
  validation_errors.empty? ? nil : Moon::Response::JSON::ValidationErrors.new(validation_errors)
8
9
  end
9
10
 
10
11
  private
11
12
 
12
- def self.validate_models(context)
13
+ def validate_models
13
14
  validation_errors = { }
14
- context.models.each do |key, model|
15
- validator = Moon::Validator[model.class].new model
16
- validation_errors[key] = validator.messages unless validator.ok?
15
+ @context.models.each do |key, model|
16
+ messages = validate_model key, model
17
+ validation_errors[key] = messages unless messages.empty?
17
18
  end
18
19
  validation_errors
19
20
  end
20
21
 
22
+ def validate_model(key, model)
23
+ checks = @context.application.configuration.validators[model.class]
24
+ validator = Moon::Validator.new @context, checks
25
+ validator.messages model
26
+ end
27
+
21
28
  end