motion_model 0.3.1 → 0.3.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 +8 -0
- data/README.md +56 -12
- data/lib/motion_model/model/column.rb +8 -2
- data/lib/motion_model/model/model.rb +14 -4
- data/lib/motion_model/model/model_casts.rb +9 -1
- data/lib/motion_model/version.rb +1 -1
- data/spec/column_options_spec.rb +22 -0
- data/spec/date_spec.rb +13 -0
- data/spec/formotion_spec.rb +33 -0
- metadata +8 -2
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,11 @@ | |
| 1 | 
            +
            2012-12-30: Added Formotion module. This allows for tighter integration with Formotion
         | 
| 2 | 
            +
                        Changed options for columns such that any arbitrary values can be inserted
         | 
| 3 | 
            +
                        allowing for future expansion.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            2012-12-14: Added lots of framework to validations
         | 
| 6 | 
            +
                        Added validations for length, format, email, presence
         | 
| 7 | 
            +
                        Added array type (thanks justinmcp)
         | 
| 8 | 
            +
             | 
| 1 9 | 
             
            2012-12-07: Added MIT license file.
         | 
| 2 10 | 
             
                        InputHelpers: Whitespace cleanup. Fixed keyboard show/hide to scroll to correct position.
         | 
| 3 11 | 
             
                        MotionModel::Column: Whitespace cleanup, added code to support cascading delete (:dependent => :destroy)
         | 
    
        data/README.md
    CHANGED
    
    | @@ -19,15 +19,12 @@ are: | |
| 19 19 | 
             
              counting.
         | 
| 20 20 |  | 
| 21 21 | 
             
            - validatable.rb: Provides a basic validation framework for any
         | 
| 22 | 
            -
              arbitrary class.  | 
| 23 | 
            -
               | 
| 22 | 
            +
              arbitrary class. You can also create custom validations to suit
         | 
| 23 | 
            +
              your app's unique needs.
         | 
| 24 24 |  | 
| 25 | 
            -
            - input_helpers: Hooking  | 
| 26 | 
            -
               | 
| 27 | 
            -
              Not something I'd like to write more often that I have to. | 
| 28 | 
            -
              helpers are certainly not the focus of this release, but
         | 
| 29 | 
            -
              I am using these in an app to create Apple-like input forms in
         | 
| 30 | 
            -
              static tables.
         | 
| 25 | 
            +
            - input_helpers: Hooking a collection up to a data form, populating
         | 
| 26 | 
            +
              the form, and retrieving the data afterwards can be a bunch of code.
         | 
| 27 | 
            +
              Not something I'd like to write more often that I have to.
         | 
| 31 28 |  | 
| 32 29 | 
             
            MotionModel is MIT licensed, which means you can pretty much do whatever
         | 
| 33 30 | 
             
            you like with it. See the LICENSE file in this project.
         | 
| @@ -94,12 +91,12 @@ class Task | |
| 94 91 | 
             
            end
         | 
| 95 92 | 
             
            ```          
         | 
| 96 93 |  | 
| 97 | 
            -
            You can also include the ` | 
| 94 | 
            +
            You can also include the `Validatable` module to get field validation. For example:
         | 
| 98 95 |  | 
| 99 96 | 
             
            ```ruby
         | 
| 100 97 | 
             
            class Task
         | 
| 101 98 | 
             
              include MotionModel::Model
         | 
| 102 | 
            -
              include MotionModel:: | 
| 99 | 
            +
              include MotionModel::Validatable
         | 
| 103 100 |  | 
| 104 101 | 
             
              columns :name        => :string,
         | 
| 105 102 | 
             
                      :description => :string,
         | 
| @@ -131,6 +128,7 @@ a_task.due_date = '2012-09-19'    # due_date is cast to NSDate | |
| 131 128 | 
             
            Currently supported types are:
         | 
| 132 129 |  | 
| 133 130 | 
             
            * `:string`
         | 
| 131 | 
            +
            * `text`
         | 
| 134 132 | 
             
            * `:boolean`, `:bool`
         | 
| 135 133 | 
             
            * `:int`, `:integer`
         | 
| 136 134 | 
             
            * `:float`, `:double`
         | 
| @@ -452,10 +450,56 @@ Core Extensions | |
| 452 450 | 
             
              Again, a reversing rule is required for both singularize and 
         | 
| 453 451 | 
             
              pluralize to work properly.
         | 
| 454 452 |  | 
| 455 | 
            -
             | 
| 453 | 
            +
            Experimental: Formotion Support
         | 
| 456 454 | 
             
            ----------------------
         | 
| 457 455 |  | 
| 458 | 
            -
             | 
| 456 | 
            +
            MotionModel now has support for the cool [Formotion gem](https://github.com/clayallsopp/formotion).
         | 
| 457 | 
            +
            Note that the Formotion project on GitHub appears to be way ahead of the gem on Rubygems, so you
         | 
| 458 | 
            +
            might want to build it yourself if you want the latest gee-whiz features (like `:picker_type`, as
         | 
| 459 | 
            +
            I've shown in this example).
         | 
| 460 | 
            +
             | 
| 461 | 
            +
            This feature is extremely experimental, but here's how it works:
         | 
| 462 | 
            +
             | 
| 463 | 
            +
            ```ruby
         | 
| 464 | 
            +
            class Event
         | 
| 465 | 
            +
              include MotionModel::Model
         | 
| 466 | 
            +
              include MotionModel::Formotion  # <== Formotion support
         | 
| 467 | 
            +
             | 
| 468 | 
            +
              columns :name => :string,
         | 
| 469 | 
            +
                      :date => {:type => :date, :formotion => {:picker_type => :date_time}},
         | 
| 470 | 
            +
                      :location => :string
         | 
| 471 | 
            +
            end
         | 
| 472 | 
            +
            ```
         | 
| 473 | 
            +
             | 
| 474 | 
            +
            This declares the class. The only difference is that you include `MotionModel::Formotion`.
         | 
| 475 | 
            +
            If you want to pass additional information on to Formotion, simply include it in the
         | 
| 476 | 
            +
            `:formotion` hash as shown above.
         | 
| 477 | 
            +
             | 
| 478 | 
            +
            MotionModel has sensible defaults for each type supported, so any field of `:date`
         | 
| 479 | 
            +
            type will default to a date picker in the Formotion form. However, if you want it
         | 
| 480 | 
            +
            to be a string for some reason, just pass in:
         | 
| 481 | 
            +
             | 
| 482 | 
            +
            ```ruby
         | 
| 483 | 
            +
            :date => {:type => :date, :formotion => {:type => :string}}
         | 
| 484 | 
            +
            ```
         | 
| 485 | 
            +
             | 
| 486 | 
            +
            To initialize a form from a model in your controller:
         | 
| 487 | 
            +
             | 
| 488 | 
            +
            ```ruby
         | 
| 489 | 
            +
            @form = Formotion::Form.new(@event.to_formotion('event details'))
         | 
| 490 | 
            +
            @form_controller = MyFormController.alloc.initWithForm(@form)
         | 
| 491 | 
            +
            ```
         | 
| 492 | 
            +
             | 
| 493 | 
            +
            The magic is in: `MotionModel::Model#to_formotion(section_header)`.
         | 
| 494 | 
            +
             | 
| 495 | 
            +
            and on the flip side you do something like this in your submit handler:
         | 
| 496 | 
            +
             | 
| 497 | 
            +
            ```ruby
         | 
| 498 | 
            +
            @event.from_formotion!(data)
         | 
| 499 | 
            +
            ```
         | 
| 500 | 
            +
             | 
| 501 | 
            +
            This performs sets on each field. You'll, of course, want to check your
         | 
| 502 | 
            +
            validations before dismissing the form.
         | 
| 459 503 |  | 
| 460 504 | 
             
            Problems/Comments
         | 
| 461 505 | 
             
            ------------------
         | 
| @@ -9,8 +9,14 @@ module MotionModel | |
| 9 9 | 
             
                  def initialize(name = nil, type = nil, options = {})
         | 
| 10 10 | 
             
                    @name = name
         | 
| 11 11 | 
             
                    @type = type
         | 
| 12 | 
            -
                     | 
| 13 | 
            -
                    @ | 
| 12 | 
            +
                    raise RuntimeError.new "columns need a type declared." if type.nil?
         | 
| 13 | 
            +
                    @default = options.delete :default
         | 
| 14 | 
            +
                    @destroy = options.delete :dependent
         | 
| 15 | 
            +
                    @options = options
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  def options
         | 
| 19 | 
            +
                    @options
         | 
| 14 20 | 
             
                  end
         | 
| 15 21 |  | 
| 16 22 | 
             
                  def classify
         | 
| @@ -264,7 +264,7 @@ module MotionModel | |
| 264 264 | 
             
                      when Symbol, String
         | 
| 265 265 | 
             
                        add_field(name, options)
         | 
| 266 266 | 
             
                      when Hash
         | 
| 267 | 
            -
                        add_field(name, options | 
| 267 | 
            +
                        add_field(name, options.delete(:type), options)
         | 
| 268 268 | 
             
                      else
         | 
| 269 269 | 
             
                        raise ArgumentError.new("arguments to `columns' must be a symbol, a hash, or a hash of hashes.")
         | 
| 270 270 | 
             
                      end
         | 
| @@ -485,6 +485,18 @@ module MotionModel | |
| 485 485 | 
             
                  self.class.type(column_name)
         | 
| 486 486 | 
             
                end
         | 
| 487 487 |  | 
| 488 | 
            +
                # Options hash for column, excluding the core
         | 
| 489 | 
            +
                # options such as type, default, etc.
         | 
| 490 | 
            +
                #
         | 
| 491 | 
            +
                # Options are completely arbitrary so you can
         | 
| 492 | 
            +
                # stuff anything in this hash you want. For
         | 
| 493 | 
            +
                # example:
         | 
| 494 | 
            +
                #
         | 
| 495 | 
            +
                #    columns :date => {:type => :date, :formotion => {:picker_type => :date_time}}
         | 
| 496 | 
            +
                def options(column_name)
         | 
| 497 | 
            +
                  column_named(column_name).options
         | 
| 498 | 
            +
                end
         | 
| 499 | 
            +
             | 
| 488 500 | 
             
                # True if this object responds to the method or
         | 
| 489 501 | 
             
                # property, otherwise false.
         | 
| 490 502 | 
             
                alias_method :old_respond_to?, :respond_to?
         | 
| @@ -513,9 +525,7 @@ module MotionModel | |
| 513 525 | 
             
                end
         | 
| 514 526 |  | 
| 515 527 | 
             
                def initialize_data_columns(column, options) #nodoc
         | 
| 516 | 
            -
             | 
| 517 | 
            -
                  cast_value = cast_to_type(column, options[column])
         | 
| 518 | 
            -
                  @data[column] = cast_value
         | 
| 528 | 
            +
                   self.send("#{column}=".to_sym, options[column] || self.class.default(column))
         | 
| 519 529 | 
             
                end
         | 
| 520 530 |  | 
| 521 531 | 
             
                def collection #nodoc
         | 
| @@ -19,7 +19,14 @@ module MotionModel | |
| 19 19 | 
             
                end
         | 
| 20 20 |  | 
| 21 21 | 
             
                def cast_to_date(arg)
         | 
| 22 | 
            -
                   | 
| 22 | 
            +
                  case arg
         | 
| 23 | 
            +
                    when String
         | 
| 24 | 
            +
                      return NSDate.dateWithNaturalLanguageString(arg.gsub('-','/'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation)
         | 
| 25 | 
            +
                    when Time
         | 
| 26 | 
            +
                      return NSDate.dateWithNaturalLanguageString(arg.strftime('%Y/%m/%d %H:%M'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation)
         | 
| 27 | 
            +
                    else
         | 
| 28 | 
            +
                      return arg
         | 
| 29 | 
            +
                  end
         | 
| 23 30 | 
             
                end
         | 
| 24 31 |  | 
| 25 32 | 
             
                def cast_to_array(arg)
         | 
| @@ -35,6 +42,7 @@ module MotionModel | |
| 35 42 | 
             
                  when :int, :integer, :belongs_to_id then cast_to_integer(arg)
         | 
| 36 43 | 
             
                  when :float, :double then cast_to_float(arg)
         | 
| 37 44 | 
             
                  when :date then cast_to_date(arg)
         | 
| 45 | 
            +
                  when :text then arg.to_s
         | 
| 38 46 | 
             
                  when :array then cast_to_array(arg)
         | 
| 39 47 | 
             
                  else
         | 
| 40 48 | 
             
                    raise ArgumentError.new("type #{column_name} : #{type(column_name)} is not possible to cast.")
         | 
    
        data/lib/motion_model/version.rb
    CHANGED
    
    
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            class ModelWithOptions
         | 
| 2 | 
            +
              include MotionModel::Model
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              columns :date => {:type => :date, :formotion => {:picker_type => :date_time}}
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            describe "column options" do
         | 
| 8 | 
            +
              it "accepts the hash form of column declaration" do
         | 
| 9 | 
            +
                lambda{ModelWithOptions.new}.should.not.raise
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              it "retrieves non-nil options for a column declaration" do
         | 
| 13 | 
            +
                instance = ModelWithOptions.new
         | 
| 14 | 
            +
                instance.options(:date).should.not.be.nil
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              it "retrieves correct options for a column declaration" do
         | 
| 18 | 
            +
                instance = ModelWithOptions.new
         | 
| 19 | 
            +
                instance.options(:date)[:formotion].should.not.be.nil
         | 
| 20 | 
            +
                instance.options(:date)[:formotion][:picker_type].should == :date_time
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
    
        data/spec/date_spec.rb
    ADDED
    
    | @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            describe "time conversions" do
         | 
| 2 | 
            +
              it "NSDate and Time should agreee on minutes since epoch" do
         | 
| 3 | 
            +
                t = Time.new
         | 
| 4 | 
            +
                d = NSDate.dateWithTimeIntervalSince1970(t.to_f)
         | 
| 5 | 
            +
                t.to_f.should == d.timeIntervalSince1970
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              it "Parsing '3/18/12 @ 7:00 PM' With Natural Language should work right" do
         | 
| 9 | 
            +
                NSDate.dateWithNaturalLanguageString('3/18/12 @ 7:00 PM'.gsub('-','/'), locale:NSUserDefaults.standardUserDefaults.dictionaryRepresentation).
         | 
| 10 | 
            +
                  strftime("%m-%d-%Y | %I:%M %p").
         | 
| 11 | 
            +
                  should == "03-18-2012 | 07:00 PM"
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            class ModelWithOptions
         | 
| 2 | 
            +
              include MotionModel::Model
         | 
| 3 | 
            +
              include MotionModel::Formotion
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              columns :name => :string,
         | 
| 6 | 
            +
                      :date => {:type => :date, :formotion => {:picker_type => :date_time}},
         | 
| 7 | 
            +
                      :location => :string
         | 
| 8 | 
            +
            end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            describe "formotion" do
         | 
| 11 | 
            +
              before do
         | 
| 12 | 
            +
                @subject = ModelWithOptions.create(:name => 'get together', :date => '12-11-13 @ 9:00 PM', :location => 'my house')
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              it "generates a formotion hash" do
         | 
| 16 | 
            +
                @subject.to_formotion.should.not.be.nil
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              it "has the correct section title" do
         | 
| 20 | 
            +
                @subject.to_formotion('test section')[:sections].first[:title].should == 'test section'
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              it "has 3 rows" do
         | 
| 24 | 
            +
                @subject.to_formotion('test section')[:sections].first[:rows].length.should == 3
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              it "binds data from rendered form into model fields" do
         | 
| 28 | 
            +
                @subject.from_formotion!({:name => '007 Reunion', :date => '3-3-13', :location => "Q's Lab"})
         | 
| 29 | 
            +
                @subject.name.should == '007 Reunion'
         | 
| 30 | 
            +
                @subject.date.strftime("%Y-%d-%d %H:%M:%S").should == '2013-03-03 12:00:00'
         | 
| 31 | 
            +
                @subject.location.should == "Q's Lab"
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: motion_model
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.3. | 
| 4 | 
            +
              version: 0.3.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:  | 
| 12 | 
            +
            date: 2013-01-03 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: bubble-wrap
         | 
| @@ -52,8 +52,11 @@ files: | |
| 52 52 | 
             
            - lib/motion_model/version.rb
         | 
| 53 53 | 
             
            - motion_model.gemspec
         | 
| 54 54 | 
             
            - spec/cascading_delete_spec.rb
         | 
| 55 | 
            +
            - spec/column_options_spec.rb
         | 
| 56 | 
            +
            - spec/date_spec.rb
         | 
| 55 57 | 
             
            - spec/ext_spec.rb
         | 
| 56 58 | 
             
            - spec/finder_spec.rb
         | 
| 59 | 
            +
            - spec/formotion_spec.rb
         | 
| 57 60 | 
             
            - spec/model_casting_spec.rb
         | 
| 58 61 | 
             
            - spec/model_hook_spec.rb
         | 
| 59 62 | 
             
            - spec/model_spec.rb
         | 
| @@ -87,8 +90,11 @@ specification_version: 3 | |
| 87 90 | 
             
            summary: Simple model and validation mixins for RubyMotion
         | 
| 88 91 | 
             
            test_files:
         | 
| 89 92 | 
             
            - spec/cascading_delete_spec.rb
         | 
| 93 | 
            +
            - spec/column_options_spec.rb
         | 
| 94 | 
            +
            - spec/date_spec.rb
         | 
| 90 95 | 
             
            - spec/ext_spec.rb
         | 
| 91 96 | 
             
            - spec/finder_spec.rb
         | 
| 97 | 
            +
            - spec/formotion_spec.rb
         | 
| 92 98 | 
             
            - spec/model_casting_spec.rb
         | 
| 93 99 | 
             
            - spec/model_hook_spec.rb
         | 
| 94 100 | 
             
            - spec/model_spec.rb
         |