quickie 0.1.0

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/.gitignore ADDED
@@ -0,0 +1,22 @@
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
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ .rvmrc
data/CHANGELOG ADDED
@@ -0,0 +1,2 @@
1
+ 0.1.0
2
+ - Initial Release.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,14 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ quickie (0.1.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+
10
+ PLATFORMS
11
+ ruby
12
+
13
+ DEPENDENCIES
14
+ quickie!
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011 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.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ ## Quickie ##
2
+ Quickie is micro library for quick in-place testing of your Ruby code. It adds two useful
3
+ methods: <code>Object#should</code> and <code>Object#should\_not</code> for positive and
4
+ negative assertions. With Quickie you can conveniently bundle tests together with your
5
+ Ruby code, typically within <code>if $0 == \_\_FILE\_\_</code> conditional statement.
6
+
7
+ ### System Requirements ###
8
+ Ruby 1.9.2 or later.
9
+
10
+ ### Installation ###
11
+ # Installing as Ruby gem
12
+ $ gem install quickie
13
+
14
+ # Cloning the repository
15
+ $ git clone git://github.com/michaeldv/quickie.git
16
+
17
+ ### Usage Example ###
18
+
19
+ $ cat > sample.rb
20
+ class Account # Back account class.
21
+ attr_reader :balance # Current account balance.
22
+
23
+ def initialize(amount) # Open the account.
24
+ @balance = amount # Accept initial deposit.
25
+ end
26
+
27
+ def deposit(amount) # Accept account deposit.
28
+ @balance += amount # Update current balance.
29
+ end
30
+
31
+ def withdraw(amount) # Withdraw from the account.
32
+ cash = [ @balance, amount ].min # Can't withdraw more than the balance.
33
+ @balance -= cash # Update current balance.
34
+ cash
35
+ end
36
+
37
+ def status # Display account status.
38
+ "Current balance: $#{balance}"
39
+ end
40
+ end
41
+
42
+ if $0 == __FILE__ # Execute only when running current Ruby file.
43
+ require "quickie" # Require the gem.
44
+
45
+ acc = Account.new(100) # Deposit $100 when opening the account.
46
+ acc.balance.should == 100 # Initial balance should be $100.
47
+ acc.deposit(200) # Deposit $200 more.
48
+ acc.balance.should != 100 # The balance should get updated.
49
+ acc.balance.should == 300 # It should be $100 + $200 = $300.
50
+
51
+ String.should === acc.status # Account#status returns a string.
52
+ acc.status.should_not =~ /\$$/ # Status string should contain the balance.
53
+ acc.status.should =~ /\$\d+$/ # The balance is one or more digits.
54
+
55
+ acc.withdraw(500).should == 300 # Withdrawal that exeeds the balance is not allowed.
56
+ acc.balance.should == 0 # Current balance should drop to zero.
57
+ acc.status.should !~ /\$[1-9]+$/ # Status no longer shows positive number.
58
+ acc.status.should =~ /\$0$/ # It shows $0.
59
+ end
60
+ ^D
61
+ $ ruby sample.rb
62
+ ..........
63
+
64
+ Passed: 10, not quite: 0, total tests: 10.
65
+
66
+ ### Testing Quickie ###
67
+ Quickie code is tested by the Quickie itself.
68
+
69
+ $ ruby test/quickie_test.rb
70
+ ....................
71
+
72
+ Passed: 20, not quite: 0, total tests: 20.
73
+
74
+ ### Note on Patches/Pull Requests ###
75
+ * Fork the project on Github.
76
+ * Make your feature addition or bug fix.
77
+ * Add test for it, making sure $ ruby test/*.rb all pass.
78
+ * Commit, do not mess with Rakefile, version, or history.
79
+ * Send me a pull request.
80
+
81
+ ### License ###
82
+
83
+ Copyright (c) 2011-12 Michael Dvorkin
84
+ twitter.com/mid
85
+ %w(mike dvorkin.net) * "@" || %w(mike fatfreecrm.com) * "@"
86
+ Released under the MIT license. See LICENSE file for details.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,13 @@
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
+ end
@@ -0,0 +1,72 @@
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
+ puts "\n#{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
+ %w[ == === =~ > >= < <= => ].each do |operator|
18
+ self.class.override operator
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ #--------------------------------------------------------------------------
25
+ def self.override(operator)
26
+ define_method(operator) do |expected|
27
+ evaluate(operator, nil, expected)
28
+ end
29
+
30
+ negative_operator = case operator[0]
31
+ when '<' then operator.sub('<', '>')
32
+ when '>' then operator.sub('>', '<')
33
+ else operator.sub(/^=/, '!')
34
+ end
35
+
36
+ return unless @object.respond_to?(negative_operator)
37
+
38
+ define_method(negative_operator) do |expected|
39
+ evaluate(operator, negative_operator, expected)
40
+ end
41
+ end
42
+
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
+ report :failure
52
+ raise Hell, lyrics(negative_operator || operator, expected)
53
+ end
54
+
55
+ rescue Hell => e
56
+ e.oops
57
+ end
58
+
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
+ #--------------------------------------------------------------------------
67
+ def report(status)
68
+ print '.' if status == :success
69
+ Runner.update(status)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,18 @@
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
+ @@stats = Hash.new(0)
9
+
10
+ def self.update(status)
11
+ at_exit {
12
+ puts "\n\nPassed: #{@@stats[:success]}, not quite: #{@@stats[:failure]}, total tests: #{@@stats.values.inject(:+)}."
13
+ } if @@stats.empty?
14
+
15
+ @@stats[status] += 1
16
+ end
17
+ end
18
+ 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
data/lib/quickie.rb ADDED
@@ -0,0 +1,15 @@
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
+ #
7
+ # Check Ruby version in case someone is playng with cloned source repo. Note
8
+ # that quickie.gemspec explicitly sets required_ruby_version to ">= 1.9.2".
9
+ #
10
+ abort "Quickie requires Ruby 1.9.2 or later" if RUBY_VERSION < "1.9.2"
11
+
12
+ require File.dirname(__FILE__) + "/quickie/runner"
13
+ require File.dirname(__FILE__) + "/quickie/matcher"
14
+ require File.dirname(__FILE__) + "/quickie/version"
15
+ require File.dirname(__FILE__) + "/quickie/core_ext/object"
@@ -0,0 +1,112 @@
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
+ require "stringio"
7
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/quickie")
8
+
9
+ # Use Quickie to test itself. The methodology is as follows:
10
+ #
11
+ # 1. Write regular Quickie test.
12
+ # 2. Capture the output of the test.
13
+ # 3. Make sure captured output matches the expectation.
14
+ #
15
+ # In addition, we hack the Quickie stats so that captured tests are not
16
+ # counted in the actual results.
17
+ #--------------------------------------------------------------------------
18
+ def capture
19
+ stats = Quickie::Runner.class_variable_get('@@stats')
20
+ captured = StringIO.new
21
+ standard, $stdout = $stdout, captured
22
+ yield
23
+ captured.string
24
+ ensure
25
+ $stdout = standard
26
+ if captured.string == '.'
27
+ stats[:success] -= 1
28
+ else
29
+ stats[:failure] -= 1
30
+ end
31
+ Quickie::Runner.class_variable_set('@@stats', stats)
32
+ end
33
+
34
+ #--------------------------------------------------------------------------
35
+ class String
36
+ def fix(line)
37
+ self.sub!(/^/, "\n") # Insert newline.
38
+ self.sub!("?", line.to_s) # Insert actual line number.
39
+ self.sub!(/\n+Passed.+$/, "") # Ignore the stats.
40
+ self
41
+ end
42
+ end
43
+
44
+ # Should - passing specs.
45
+ #--------------------------------------------------------------------------
46
+ capture { "abc".should == "abc" }.should == "."
47
+ capture { "abc".should != "xyz" }.should == "."
48
+ capture { "abc".should =~ /AB/i }.should == "."
49
+ capture { "abc".should !~ /XY/i }.should == "."
50
+ capture { 1234567.should_be > 0 }.should == "."
51
+
52
+ # Should Not - passing specs.
53
+ #--------------------------------------------------------------------------
54
+ capture { "abc".should_not != "abc" }.should == "."
55
+ capture { "abc".should_not == "xyz" }.should == "."
56
+ capture { "abc".should_not !~ /AB/i }.should == "."
57
+ capture { "abc".should_not =~ /XY/i }.should == "."
58
+ capture { 1234567.should_not_be < 0 }.should == "."
59
+
60
+ # Should - failing specs.
61
+ #--------------------------------------------------------------------------
62
+ capture { "abc".should != "abc" }.should == <<-EOS.fix(__LINE__)
63
+ expected: != "abc"
64
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
65
+ EOS
66
+
67
+ capture { "abc".should == "xyz" }.should == <<-EOS.fix(__LINE__)
68
+ expected: == "xyz"
69
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
70
+ EOS
71
+
72
+ capture { "abc".should !~ /AB/i }.should == <<-EOS.fix(__LINE__)
73
+ expected: !~ /AB/i
74
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
75
+ EOS
76
+
77
+ capture { "abc".should =~ /XY/i }.should == <<-EOS.fix(__LINE__)
78
+ expected: =~ /XY/i
79
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
80
+ EOS
81
+
82
+ capture { 1234567.should_be < 0 }.should == <<-EOS.fix(__LINE__)
83
+ expected: < 0
84
+ actual: 1234567 in test/quickie_test.rb, line ? in `block in <main>'
85
+ EOS
86
+
87
+ # Should Not - failing specs.
88
+ #--------------------------------------------------------------------------
89
+ capture { "abc".should_not == "abc" }.should == <<-EOS.fix(__LINE__)
90
+ expected not: == "abc"
91
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
92
+ EOS
93
+
94
+ capture { "abc".should_not != "xyz" }.should == <<-EOS.fix(__LINE__)
95
+ expected not: != "xyz"
96
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
97
+ EOS
98
+
99
+ capture { "abc".should_not =~ /AB/i }.should == <<-EOS.fix(__LINE__)
100
+ expected not: =~ /AB/i
101
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
102
+ EOS
103
+
104
+ capture { "abc".should_not !~ /XY/i }.should == <<-EOS.fix(__LINE__)
105
+ expected not: !~ /XY/i
106
+ actual: "abc" in test/quickie_test.rb, line ? in `block in <main>'
107
+ EOS
108
+
109
+ capture { 1234567.should_not_be > 0 }.should == <<-EOS.fix(__LINE__)
110
+ expected not: > 0
111
+ actual: 1234567 in test/quickie_test.rb, line ? in `block in <main>'
112
+ EOS
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: quickie
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-01-03 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Quickie adds Object#should and Object#should_not methods for quick testing
15
+ of your Ruby code
16
+ email: mike@dvorkin.net
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - CHANGELOG
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - LICENSE
25
+ - Rakefile
26
+ - README.md
27
+ - lib/quickie/core_ext/object.rb
28
+ - lib/quickie/matcher.rb
29
+ - lib/quickie/runner.rb
30
+ - lib/quickie/version.rb
31
+ - lib/quickie.rb
32
+ - test/quickie_test.rb
33
+ - .gitignore
34
+ homepage: http://github.com/michaeldv/quickie
35
+ licenses: []
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.9.2
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project: quickie
54
+ rubygems_version: 1.8.11
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Micro framework for in-place testing of Ruby code
58
+ test_files: []