quickie_motion 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ # Mac OS
2
+ .DS_Store
3
+
4
+ # TextMate
5
+ *.tmproj
6
+ tmtags
7
+
8
+ # Emacs
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ # Vim
14
+ *.swp
15
+
16
+ # Gem
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ .rvmrc
21
+
22
+ # Test
23
+ test/.repl_history
24
+ test/build
25
+ test/resources/*.nib
26
+ test/resources/*.momd
27
+ test/resources/*.storyboardc
@@ -0,0 +1,2 @@
1
+ 0.1.0
2
+ - Initial RubyMotion implementation based on Quickie 0.3.0 gem.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011-2012 Michael Dvorkin
2
+ twitter.com/mid
3
+ %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
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,85 @@
1
+ ## Quickie for RubyMotion ##
2
+ Quickie for RubyMotion is a gem for quick in-place testing of your RubyMotion code. It provides
3
+ four useful methods:
4
+
5
+ * <code>Object#should</code> and <code>Object#should\_not</code> for positive and negative assertions.
6
+ * <code>Object#stub</code> for method stubbing.
7
+ * <code>Kernel#mock</code> for creating object mocks.
8
+
9
+ ### Installation ###
10
+ # Installing as Ruby gem
11
+ $ gem install quickie_motion
12
+
13
+ # Cloning the repository
14
+ $ git clone git://github.com/michaeldv/quickie_motion.git
15
+
16
+ ### Usage ###
17
+ Generate RubyMotion project, then require "quickie_motion" in projects's Rakefile:
18
+
19
+ # -*- coding: utf-8 -*-
20
+ $:.unshift("/Library/RubyMotion/lib")
21
+ require "motion/project"
22
+ require "quickie_motion"
23
+
24
+ Motion::Project::App.setup do |app|
25
+ app.name = "your_app_name"
26
+ end
27
+
28
+ Add your Quickie tests to the AppDelegate as follows:
29
+
30
+ class AppDelegate
31
+ def application(application, didFinishLaunchingWithOptions:launchOptions)
32
+ #
33
+ # Your application code.
34
+ #
35
+ return true if RUBYMOTION_ENV == "release"
36
+ #
37
+ # Your tests.
38
+ #
39
+ quickie do
40
+ run_tests
41
+ run_more_tests
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def run_tests
48
+ 1.should == 1
49
+ end
50
+
51
+ def run_more_tests
52
+ true.should_not == false
53
+ end
54
+ end
55
+
56
+ For more information about the usage of assertions and stubs please check http://github.com/michaeldv/quickie.
57
+
58
+ ### Testing Quickie for RubyMotion ###
59
+ Quickie code is tested by the Quickie itself.
60
+
61
+ $ rake quickie
62
+ Build ./build/iPhoneSimulator-6.0-Development
63
+ Simulate ./build/iPhoneSimulator-6.0-Development/quickie_motion_test.app
64
+ .....................................
65
+
66
+ Passed: 37, not quite: 0, total tests: 37.
67
+ (main)>
68
+
69
+ For more details please check <code>quickie_motion_test</code> application in the <code>test</code> directory.
70
+
71
+ ### Note on Patches/Pull Requests ###
72
+ * Fork the project on Github.
73
+ * Make your feature addition or bug fix.
74
+ * Add tests for it making sure $ rake quickie passes 100%.
75
+ * Commit, do not mess with Rakefile, version, or history.
76
+ * Send me commit URL (*do not* send pull requests).
77
+
78
+ ### License ###
79
+ Copyright (c) 2010-2012 Michael Dvorkin
80
+
81
+ http://www.dvorkin.net
82
+
83
+ %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
84
+
85
+ Released under the MIT license. See LICENSE file for details.
@@ -0,0 +1,7 @@
1
+ require "bundler"
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ desc "Build quickie tests and run them"
5
+ task :quickie do
6
+ system "cd ./test && rake && cd .."
7
+ end
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2011-12 Michael Dvorkin
2
+ #
3
+ # Quickie is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ unless defined?(Motion::Project::Config)
7
+ raise "This file must be required within a RubyMotion project Rakefile."
8
+ end
9
+
10
+ Motion::Project::App.setup do |app|
11
+ dir = File.dirname(__FILE__)
12
+ app.files.unshift("#{dir}/quickie_motion/core_ext/kernel.rb")
13
+ app.files.unshift("#{dir}/quickie_motion/core_ext/object.rb")
14
+ app.files.unshift("#{dir}/quickie_motion/runner.rb")
15
+ app.files.unshift("#{dir}/quickie_motion/matcher.rb")
16
+ app.files.unshift("#{dir}/quickie_motion/stub.rb")
17
+ app.files.unshift("#{dir}/quickie_motion/mock.rb")
18
+ app.files.unshift("#{dir}/quickie_motion/version.rb")
19
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2011-2012 Michael Dvorkin
2
+ #
3
+ # Awesome Print is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ module Kernel
7
+ def quckie
8
+ current, Exception.log_exceptions = Exception.log_exceptions, false
9
+ yield
10
+ Quickie::Runner.summary
11
+ ensure
12
+ Exception.log_exceptions = current
13
+ end
14
+
15
+ def mock
16
+ Quickie::Mock.new
17
+ end
18
+
19
+ module_function :quckie, :mock
20
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2011-12 Michael Dvorkin
2
+ #
3
+ # Quickie is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ class Object
7
+ [ :should, :should_not ].each do |verb|
8
+ define_method verb do
9
+ Quickie::Matcher.new(self, verb)
10
+ end
11
+ alias_method :"#{verb}_be", verb
12
+ end
13
+
14
+ define_method :stub do |method, options = {}|
15
+ Quickie::Stub.new(self, method, options)
16
+ end
17
+ alias_method :stub!, :stub
18
+ #
19
+ # Define Object#singleton_class since it's not there (as of RubyMotion 1.26).
20
+ #
21
+ unless self.method_defined?(:singleton_class)
22
+ def singleton_class
23
+ class << self
24
+ self
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,82 @@
1
+ # Copyright (c) 2011-12 Michael Dvorkin
2
+ #
3
+ # Quickie is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ module Quickie
7
+ class Hell < RuntimeError
8
+ def oops
9
+ "#{message.chomp} in #{backtrace[2].sub(':', ', line ').sub(':', ' ')}"
10
+ end
11
+ end
12
+
13
+ class Matcher
14
+ def initialize(object, verb)
15
+ @object = object
16
+ @should = (verb == :should)
17
+ end
18
+
19
+ private
20
+
21
+ # Override an operator to be able to tell whether it succeeded or not.
22
+ #--------------------------------------------------------------------------
23
+ def self.override(operator)
24
+ define_method(operator) do |expected|
25
+ evaluate(operator, nil, expected)
26
+ end
27
+
28
+ negative_operator = case operator[0]
29
+ when '<' then operator.sub('<', '>')
30
+ when '>' then operator.sub('>', '<')
31
+ else operator.sub(/^=/, '!')
32
+ end
33
+
34
+ return unless @object.respond_to?(negative_operator)
35
+
36
+ define_method(negative_operator) do |expected|
37
+ evaluate(operator, negative_operator, expected)
38
+ end
39
+ end
40
+
41
+ # Note that we always evaluate positive operators, and then flip the actual
42
+ # result based on should/should_not request.
43
+ #--------------------------------------------------------------------------
44
+ def evaluate(operator, negative_operator, expected)
45
+ actual = !!@object.__send__(operator, expected)
46
+ actual ^= 1 if (!@should && !negative_operator) || (@should && negative_operator)
47
+
48
+ if actual
49
+ report :success
50
+ else
51
+ raise Hell, lyrics(negative_operator || operator, expected)
52
+ end
53
+
54
+ rescue Hell => e
55
+ report :failure, e.oops
56
+ end
57
+
58
+ # Format actual vs. expected message.
59
+ #--------------------------------------------------------------------------
60
+ def lyrics(operator, expected)
61
+ format = "expected: %s %s\n actual: %s %s"
62
+ format.sub!(":", " not:").sub!("\n", "\n ") unless @should
63
+ format % [ operator, expected.inspect, ' ' * operator.size, @object.inspect ]
64
+ end
65
+
66
+ # Report test success and/or failure. When running within IRB or Pry the
67
+ # message gets displayed immediately, otherwise all the messages are shown
68
+ # by the Runner in at_exit block.
69
+ #--------------------------------------------------------------------------
70
+ def report(status, message = nil)
71
+ print(status == :success ? '.' : 'F') unless ENV["quickie_motion_test"]
72
+ Runner.update(status, message)
73
+ status == :success
74
+ end
75
+
76
+ # The matcher magic starts here ;-)
77
+ #--------------------------------------------------------------------------
78
+ %w[ == === =~ > >= < <= => ].each do |operator|
79
+ override operator
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,62 @@
1
+ # Copyright (c) 2011-12 Michael Dvorkin
2
+ #
3
+ # Quickie is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ module Quickie
7
+ class Mock
8
+ alias :__methods :methods
9
+ alias :__respond_to? :respond_to?
10
+
11
+ begin
12
+ current, Exception.log_exceptions = Exception.log_exceptions, false
13
+ instance_methods.each do |method|
14
+ unless method =~ /(?:__|:)/ || [ :==, :===, :!=, :ai, :class, :object_id, :respond_to_missing?, :to_s ].include?(method)
15
+ undef_method method rescue nil # Suppress cannot undefine method `???' because it is a native method (RuntimeError)
16
+ end
17
+ end
18
+ ensure
19
+ Exception.log_exceptions = current
20
+ end
21
+
22
+ def initialize
23
+ @stash = {}
24
+ end
25
+
26
+ def stub(method, options = {})
27
+ unless __methods.include?(method)
28
+ options[:return] ||= nil
29
+ @stash[method] = options
30
+ else
31
+ super(method, options)
32
+ end
33
+ self
34
+ end
35
+ alias :stub! :stub
36
+
37
+ def inspect
38
+ self.to_s
39
+ end
40
+
41
+ def instance_variables
42
+ []
43
+ end
44
+
45
+ def methods
46
+ (__methods - [ :__methods, :__respond_to?, :instance_variables, :respond_to_missing? ] + @stash.keys).sort
47
+ end
48
+
49
+ def method_missing(method, *args)
50
+ if @stash.key?(method) then
51
+ @stash[method][:return]
52
+ else
53
+ raise NoMethodError, "undefined method `%s', expected one of %p" % [ method, methods ]
54
+ end
55
+ end
56
+
57
+ def respond_to?(method)
58
+ return true if @stash.key?(method.to_sym)
59
+ __respond_to?(method)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,30 @@
1
+ # Copyright (c) 2011-12 Michael Dvorkin
2
+ #
3
+ # Quickie is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ module Quickie
7
+ class Runner
8
+
9
+ class << self
10
+ def reset
11
+ @trace = []
12
+ @stats = Hash.new(0)
13
+ end
14
+
15
+ def update(status, message = nil)
16
+ @stats[status] += 1
17
+ @trace << message if message
18
+ end
19
+
20
+ def summary
21
+ puts
22
+ puts "\n" << @trace.join("\n\n") unless @trace.empty?
23
+ puts "\nPassed: #{@stats[:success]}, not quite: #{@stats[:failure]}, total tests: #{@stats.values.inject(:+)}."
24
+ reset
25
+ end
26
+ end
27
+
28
+ reset
29
+ end
30
+ end
@@ -0,0 +1,109 @@
1
+ # Copyright (c) 2011-12 Michael Dvorkin
2
+ #
3
+ # Quickie is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ module Quickie
7
+ class Stub
8
+ #
9
+ # To set up a stub with optional return value:
10
+ # obj.stub(:method, :return => something)
11
+ #
12
+ # To remove existing stub and restore original method:
13
+ # obj.stub(:method, :remove)
14
+ #
15
+ #--------------------------------------------------------------------------
16
+ def initialize(object, method, options = {})
17
+ options = { options => true } if options.is_a?(Symbol)
18
+ @object, @options = object, options
19
+ @@stash ||= []
20
+ #
21
+ # Create a new stub by intercepting the method or remove existing stub
22
+ # by restoring the original method.
23
+ #
24
+ unless @options[:remove]
25
+ intercept(method)
26
+ else
27
+ restore(method)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # Same as class << @object; self; end -- comes with Ruby 1.9.
34
+ #--------------------------------------------------------------------------
35
+ def metaclass
36
+ @object.singleton_class
37
+ end
38
+
39
+ # Unique name the original method gets stashed under when creating a stub.
40
+ #--------------------------------------------------------------------------
41
+ def moniker(method)
42
+ :"__#{method}__#{@object.__id__}"
43
+ end
44
+
45
+ # Return method's visibility, nil if public.
46
+ #--------------------------------------------------------------------------
47
+ def visibility(method)
48
+ if metaclass.private_method_defined?(method)
49
+ :private
50
+ elsif metaclass.protected_method_defined?(method)
51
+ :protected
52
+ end
53
+ end
54
+
55
+ # Set up a stub by stashing the original method under different name and
56
+ # then rediefining the method to return the requested value.
57
+ #--------------------------------------------------------------------------
58
+ def intercept(method)
59
+ new_name = moniker(method)
60
+ unless @object.respond_to? new_name
61
+ stash(method, new_name)
62
+ redefine(method)
63
+ end
64
+ end
65
+
66
+ # Preserve original method by creating its alias with the unique name.
67
+ #--------------------------------------------------------------------------
68
+ def stash(method, new_name)
69
+ metaclass.class_eval do
70
+ if method_defined?(method) || private_method_defined?(method)
71
+ alias_method new_name, method
72
+ end
73
+ end
74
+ @@stash << new_name
75
+ end
76
+
77
+ # Create a stub that returns requested value.
78
+ #--------------------------------------------------------------------------
79
+ def redefine(method)
80
+ return_value = @options[:return]
81
+ metaclass.class_eval do
82
+ define_method method do |*args, &block|
83
+ return_value
84
+ end
85
+ end
86
+ #
87
+ # Set visibility attribute if the origial method is not public.
88
+ #
89
+ private_or_protected = visibility(method)
90
+ metaclass.class_eval("#{private_or_protected} :#{method}") if private_or_protected
91
+ end
92
+
93
+ # Remove the stub and restore the original method.
94
+ #--------------------------------------------------------------------------
95
+ def restore(method)
96
+ stashed_name = moniker(method)
97
+ if @@stash.include? stashed_name # Was it ever stubbed?
98
+ metaclass.instance_eval do
99
+ if method_defined?(stashed_name) || private_method_defined?(stashed_name)
100
+ remove_method method # Remove the stub.
101
+ alias_method method, stashed_name # Restore the original method from stash.
102
+ remove_method stashed_name # Remove stashed copy.
103
+ end
104
+ end
105
+ @@stash.delete stashed_name
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,10 @@
1
+ # Copyright (c) 2011-12 Michael Dvorkin
2
+ #
3
+ # Quickie is freely distributable under the terms of MIT license.
4
+ # See LICENSE file or http://www.opensource.org/licenses/mit-license.php
5
+ #------------------------------------------------------------------------------
6
+ module Quickie
7
+ def self.version
8
+ "0.1.0"
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ $:.unshift("/Library/RubyMotion/lib")
3
+ require "motion/project"
4
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/quickie_motion")
5
+
6
+ Motion::Project::App.setup do |app|
7
+ app.name = "quickie_motion_test"
8
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quickie_motion
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Dvorkin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Quickie adds Object#should, Object#should_not, and Object#stub methods
31
+ for quick and easy testing of your RubyMotion code
32
+ email: mike@dvorkin.net
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - CHANGELOG
38
+ - Gemfile
39
+ - LICENSE
40
+ - Rakefile
41
+ - README.md
42
+ - lib/quickie_motion/core_ext/kernel.rb
43
+ - lib/quickie_motion/core_ext/object.rb
44
+ - lib/quickie_motion/matcher.rb
45
+ - lib/quickie_motion/mock.rb
46
+ - lib/quickie_motion/runner.rb
47
+ - lib/quickie_motion/stub.rb
48
+ - lib/quickie_motion/version.rb
49
+ - lib/quickie_motion.rb
50
+ - .gitignore
51
+ - test/Rakefile
52
+ homepage: http://github.com/michaeldv/quickie_motion
53
+ licenses: []
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ segments:
65
+ - 0
66
+ hash: -1131033836946887671
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ segments:
74
+ - 0
75
+ hash: -1131033836946887671
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 1.8.24
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Micro framework for in-place testing of RubyMotion code
82
+ test_files:
83
+ - test/Rakefile