command-unit 0.0.0 → 0.0.1

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Njk2YmM5MjE0MTgzYjlhMGZlZDdhOTNlZWMzMWZlN2I2YjdhNzk4ZA==
4
+ N2YxZTJjNGQzMGNlMWU5ODdjN2U4MTMyYmQ1NWQ4YTQ3ZDQ1N2MzOQ==
5
5
  data.tar.gz: !binary |-
6
- YjdiNzVmYzE3MzFiYmQyMzIwNWQ3ZmZlYzk3M2ZkODE5NTE0MjVmNA==
6
+ M2RhYjRmMTM3ZDQyNmViNWY3N2RjMTY0Y2EyMTdhMTRhYjUyZjI4Ng==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MDQ4ZTIzZjQ5MjdjMTdlYmU1MjUwYjIwZWFlZTBjNmM1MjUzYjc3Mjk0MTQ2
10
- MmZjMzg4YTA3MTYyNDg0N2NiNzZhOGI5N2IxZTQ1OTI0NjNmMzBjODU1OTY1
11
- ODM5MTFiZjBlYjZhMDZiZWJkNjgwMWE2ZDdmYzdkZDIwMDE2MWU=
9
+ M2FhYWYzZDE3OGE3OTFjMmFkZWMxYmE0NTRmMTZhMWMzZGYxYjVmOWE5YjM4
10
+ N2ExYmI2NWEyOTNkZWUyNzdiMmU3MDU2ZDU2NzY2NDE1YmZhMzdlZWFlNzdh
11
+ OTZhNTZkOGVjNDY5NzBmOWNlMTc2OWIxY2U1MDVjMDU0NzY2ZTg=
12
12
  data.tar.gz: !binary |-
13
- YWM5ZjU5OGEyZTA3NDQxZTE0YmE1YmQxMTliODhlNmRmOTlkMzdkOWY4NThl
14
- NWI5OWUwMjU1M2NlN2IxN2M3Y2Q5Mzc2N2U4YzRiMTUyNmM5ZWIzOTA5YWZk
15
- YjY2ZDljZTRlMGYwNGNkNzgwMDkxNDViNTg0YmZmMjE4Y2ZjYmY=
13
+ NjlmYjUyZTk3NTc5ZjA0MzU2Y2IyYmYwNmUwYmU3ODY1MmZkOGE1ZWE2ZjQ1
14
+ NmYzNTkzMjk2Y2Y0OWEyMzNiOTFlNWIxNjViOTI5YTVjZGI0ZWRmNmIxZGJm
15
+ MGE2MTU2MGJjNDgxOTg4MTc4MWNiZmI2Nzc2ZDM2YjhjODUwN2Q=
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .idea
3
+ *.iml
data/README.md CHANGED
@@ -1,2 +1,23 @@
1
1
  # Command Unit
2
- A very simple test runner, primarily written to support development of [Righteous Git Hooks](http://github.com/samsalisbury/righteous-git-hooks).
2
+ Lightweight test runner, primarily written to support development of [Righteous Git Hooks](http://github.com/samsalisbury/righteous-git-hooks).
3
+
4
+ Written in Ruby, designed to test command line apps, whether they're written in Ruby, Shell, Bash, C#, Java, whatever ;)
5
+
6
+ ## Design goals:
7
+ * As few dependencies as possible
8
+ * Should be self-testing
9
+ * Suitable for testing command line tools
10
+
11
+ Tests are written in Command Unit itself, so no need for any external dependencies yet. I might make this a fundamental requirement of future development, but I'll see how far the project can go on basic Ruby first.
12
+
13
+ ## This is alpha software
14
+ So far I've only tested this on Ruby 1.9.3, others may work but I'm not considering support on any other platforms until I've got a stable/useful release out.
15
+
16
+ ## Installation
17
+ `gem install command-unit`
18
+
19
+ ## Development
20
+ Unpack the gem with `gem unpack command-unit`
21
+ Run tests:
22
+ $ cd command-unit-0.0.1
23
+ $ ruby test/test.rb
data/command-unit.gemspec CHANGED
@@ -1,11 +1,11 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "command-unit"
3
- s.version = "0.0.0"
3
+ s.version = "0.0.1"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.author = "Samuel R. Salisbury"
6
6
  s.email = "samsalisbury@gmail.com"
7
7
  s.homepage = "http://github.com/samsalisbury/command-unit"
8
- s.summary = "ALPHA: Simple test runner for command line tools."
8
+ s.summary = "ALPHA: Lightweight test runner for command line tools."
9
9
  s.description = "ALPHA: Test runner for one-shot command line tools. This was built to support writing git hooks over at http://github.com/samsalisbury/righteous-git-hooks"
10
10
 
11
11
  s.rubyforge_project = s.name
data/lib/command-unit.rb CHANGED
@@ -1,60 +1,154 @@
1
1
  module CommandUnit
2
2
 
3
+ @@scenario_count = 0
4
+
3
5
  @@scenarios = []
4
6
  @@current_scenario = nil
5
7
  attr_reader :current_scenario
6
8
 
7
- def scenario(description, &block)
8
- @@scenarios.push Scenario.new(description, &block)
9
+ def scenario(namespace_or_description, description_or_nil=nil, &block)
10
+ raise "You must provide a description (String) for each scenario." if namespace_or_description.nil? or description_or_nil.is_a? Symbol
11
+ raise "namespace must be a symbol, if you meant it as a description, use a string instead." if description_or_nil.is_a? String and not namespace_or_description.is_a? Symbol
12
+
13
+ if description_or_nil.nil?
14
+ description = namespace_or_description
15
+ namespace = nil
16
+ else
17
+ description = description_or_nil
18
+ namespace = namespace_or_description
19
+ end
20
+
21
+ @@scenarios.push Scenario.new(namespace, description, &block)
22
+ return @@scenarios.last
9
23
  end
10
24
 
11
- def run
12
- @@scenarios.each do |scenario|
13
- scenario.run
25
+ def run(namespace_or_scenario_or_nowt = nil)
26
+ if namespace_or_scenario_or_nowt.nil?
27
+ # Run the lot...
28
+ @@scenarios.each do |scenario|
29
+ scenario.run
30
+ end
31
+ else
32
+ if namespace_or_scenario_or_nowt.is_a? Symbol
33
+ @@scenarios.each do |scenario|
34
+ next unless scenario.namespace == namespace_or_scenario_or_nowt
35
+ scenario.run
36
+ end
37
+ elsif namespace_or_scenario.is_a? Scenario
38
+ namespace_or_scenario_or_nowt.run
39
+ else
40
+ raise "You must pass either a Scenario, a Symbol (namespace), or nil into run. You passed a #{namespace_or_scenario_or_nowt.class}"
41
+ end
14
42
  end
15
43
  end
16
44
 
45
+ require 'stringio'
46
+
47
+ def capture_stdout
48
+ out = StringIO.new
49
+ $stdout = out
50
+ yield
51
+ r = out.string
52
+ return r
53
+ ensure
54
+ $stdout = STDOUT
55
+ end
56
+
57
+ def ensure_inside_scenario
58
+ raise "#{caller[0]} must be called from inside a scenario block" if @@current_scenario == nil
59
+ end
60
+
61
+ def scenario_set_up(&scenario_set_up_block)
62
+ ensure_inside_scenario
63
+ @@current_scenario.scenario_set_up_block = scenario_set_up_block
64
+ end
65
+
66
+ def scenario_tear_down(&scenario_tear_down_block)
67
+ ensure_inside_scenario
68
+ @@current_scenario.scenario_tear_down_block = scenario_tear_down_block
69
+ end
70
+
71
+ def tear_down(&tear_down_block)
72
+ ensure_inside_scenario
73
+ @@current_scenario.tear_down_block = tear_down_block
74
+ end
75
+
17
76
  def set_up(&set_up_block)
18
- raise 'set_up must be called from inside a scenario block' if @@current_scenario == nil
77
+ ensure_inside_scenario
19
78
  @@current_scenario.set_up_block = set_up_block
20
79
  end
21
80
 
22
81
  def when_i(desc, &when_i_block)
23
- raise 'when_i must be called from inside a scenario block' if @@current_scenario == nil
82
+ ensure_inside_scenario
24
83
  @@current_scenario.add_test Test.new(desc, &when_i_block)
25
84
  end
26
85
 
27
86
  def i_expect(desc, &i_expect_block)
28
- raise 'i_expect must be called from inside a scenario block' if @@current_scenario == nil
87
+ ensure_inside_scenario
29
88
  @@current_scenario.current_test.add_expectation Expectation.new(desc, &i_expect_block)
30
89
  end
31
90
 
91
+ def success(desc = '')
92
+ ExpectationResult.new(desc, true)
93
+ end
94
+
95
+ def failure(desc = '')
96
+ ExpectationResult.new(desc, false)
97
+ end
98
+
32
99
  class Scenario
33
- def initialize(desc, &block)
100
+ def initialize(namespace, desc, &block)
101
+ @namespace = namespace
102
+ @id = @@scenario_count += 1
34
103
  @desc = desc
35
104
  @block = block
36
105
  @set_up_block = nil
37
106
  @tests = []
38
107
  @current_test = nil
39
108
  @tear_down_block = nil
109
+ @scenario_set_up_block = nil
110
+ @scenario_tear_down_block = nil
111
+ @tests_run = 0
112
+ @expectations_run = 0
113
+ @expectations_met = 0
114
+ @expectations_not_met = 0
115
+ @inconclusive_expectations = 0
40
116
  end
41
117
 
42
118
  def run
43
- puts "Running scenario: #{@desc}"
119
+ puts "\nRunning scenario #{@id}: #{@desc}"
44
120
  @@current_scenario = self
45
121
  @block.call
122
+ context = {}
123
+ @scenario_set_up_block.call(context) unless @scenario_set_up_block.nil?
46
124
  @tests.each do |test|
47
- puts "When I #{test.when_i_text}"
48
- context = {}
125
+ puts "\tWhen I #{test.when_i_text}"
126
+ @tests_run += 1
49
127
  @set_up_block.call(context) unless @set_up_block.nil?
50
128
  test.when_i_block.call(context) unless test.when_i_block.nil?
51
- print 'I expect '
52
129
  test.expectations.each do |expectation|
53
- puts expectation.desc
54
- expectation.block.call(context) unless expectation.block.nil?
130
+ print "\t\tI expect #{expectation.desc}..."
131
+ result = expectation.block.call(context)
132
+ @expectations_run += 1
133
+ if result.respond_to? :success?
134
+ if result.success?
135
+ @expectations_met +=1
136
+ puts "Success! #{result.message}"
137
+ else
138
+ @expectations_not_met +=1
139
+ puts "Failure! #{result.message}"
140
+ end
141
+ else
142
+ @inconclusive_expectations += 1
143
+ puts "Inconclusive! #{result}"
144
+ end
55
145
  end
146
+ @tear_down_block.call(context) unless @tear_down_block.nil?
56
147
  end
148
+ @scenario_tear_down_block.call(context) unless @scenario_tear_down_block.nil?
57
149
  @@current_scenario = nil
150
+
151
+ puts "Scenario #{@id} finished, #{@tests_run} tests, #{@expectations_run} expectations with #{@expectations_met} successful and #{@expectations_not_met} failures."
58
152
  end
59
153
 
60
154
  def add_test(test)
@@ -62,7 +156,8 @@ module CommandUnit
62
156
  @current_test = test
63
157
  end
64
158
 
65
- attr_accessor :desc, :block, :set_up_block, :tests, :tear_down_block, :current_test
159
+ attr_accessor :desc, :block, :set_up_block, :tests, :tear_down_block, :current_test,
160
+ :scenario_set_up_block, :scenario_tear_down_block, :namespace
66
161
  end
67
162
 
68
163
  class Test
@@ -85,4 +180,15 @@ module CommandUnit
85
180
  attr_accessor :desc, :block
86
181
  end
87
182
 
88
- end
183
+ class ExpectationResult
184
+ def initialize(description, expectation_met)
185
+ @message = description
186
+ @success = expectation_met
187
+ end
188
+ attr_reader :message
189
+ def success?
190
+ @success
191
+ end
192
+
193
+ end
194
+ end
data/test/quick-test.rb CHANGED
@@ -1,12 +1,26 @@
1
+ require_relative '../lib/command-unit'
2
+
1
3
  include CommandUnit
2
4
 
3
5
  scenario 'When blahblahs are whatnots' do
4
6
 
7
+ scenario_set_up do |context|
8
+ puts 'scenario_set_up called!'
9
+ end
10
+
11
+ scenario_tear_down do |context|
12
+ puts 'scenario_tear_down called!'
13
+ end
14
+
5
15
  set_up do |context|
6
16
  puts 'set_up called!'
7
17
  context[:thing] = 'some property set in set_up'
8
18
  end
9
19
 
20
+ tear_down do |context|
21
+ puts 'tear_down called!'
22
+ end
23
+
10
24
  when_i "don't do anything" do |context|
11
25
  # Doing nothing
12
26
  puts 'when_i called!'
@@ -18,6 +32,33 @@ scenario 'When blahblahs are whatnots' do
18
32
  context[:thing3] = 'thang'
19
33
  end
20
34
 
35
+ when_i "create another test" do |context|
36
+ # Doing nothing
37
+ puts 'when_i called!'
38
+ context[:thing2] = 'thing'
39
+ end
40
+
41
+ i_expect 'that the second test is also run' do |context|
42
+ puts 'i_expect called!'
43
+ context[:thing3] = 'thang'
44
+ end
45
+
46
+ when_i "create a third test with 2 expectations" do |context|
47
+ # Doing nothing
48
+ puts 'when_i called!'
49
+ context[:thing2] = 'thing'
50
+ end
51
+
52
+ i_expect 'that both expectations are called' do |context|
53
+ puts 'i_expect called!'
54
+ context[:thing3] = 'thang'
55
+ end
56
+
57
+ i_expect 'that this second expectation will also be called!' do |context|
58
+ puts 'i_expect called!'
59
+ context[:thing3] = 'thang'
60
+ end
61
+
21
62
  end
22
63
 
23
64
  run
data/test/test.rb ADDED
@@ -0,0 +1,59 @@
1
+ require_relative '../lib/command-unit'
2
+
3
+ include CommandUnit
4
+
5
+ scenario :command_unit, 'Running a scenario with no tests or assertions' do
6
+
7
+ when_i 'execute the scenario' do |context|
8
+ context[:scenario] = scenario 'This is an empty scenario' do
9
+
10
+ end
11
+ context[:out] = capture_stdout { context[:scenario].run }
12
+ end
13
+
14
+ i_expect 'to see the scenario title' do |context|
15
+ if context[:out].include? 'This is an empty scenario'
16
+ success
17
+ else
18
+ failure "Output was: '#{context[:out]}'"
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ scenario :command_unit, 'Running a scenario with 1 test and 1 passing assertion' do
25
+
26
+ set_up do |context|
27
+ context[:scenario] = scenario 'This scenario has 1 test with 1 assertion' do
28
+ when_i 'have 1 test in the scenario' do
29
+ # Empty test test ;)
30
+ end
31
+ i_expect 'that this should pass' do
32
+ success
33
+ end
34
+ end
35
+ end
36
+
37
+ when_i 'run the scenario' do |context|
38
+ context[:out] = capture_stdout do context[:scenario].run end
39
+ end
40
+
41
+ i_expect 'to see the when_i text and the i_expect text' do |context|
42
+ if context[:out].include? 'have 1 test in the scenario' and context[:out].include? 'that this should pass'
43
+ success
44
+ else
45
+ failure
46
+ end
47
+ end
48
+
49
+ i_expect 'to see the correct number of tests and expectations reported' do |context|
50
+ if context[:out].include? '1 tests, 1 expectations with 1 successful and 0 failures'
51
+ success
52
+ else
53
+ failure
54
+ end
55
+
56
+ end
57
+ end
58
+
59
+ run :command_unit
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command-unit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel R. Salisbury
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-16 00:00:00.000000000 Z
11
+ date: 2013-08-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ! 'ALPHA: Test runner for one-shot command line tools. This was built
14
14
  to support writing git hooks over at http://github.com/samsalisbury/righteous-git-hooks'
@@ -17,11 +17,13 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - .gitignore
20
21
  - .ruby-version
21
22
  - README.md
22
23
  - command-unit.gemspec
23
24
  - lib/command-unit.rb
24
25
  - test/quick-test.rb
26
+ - test/test.rb
25
27
  homepage: http://github.com/samsalisbury/command-unit
26
28
  licenses: []
27
29
  metadata: {}
@@ -44,5 +46,5 @@ rubyforge_project: command-unit
44
46
  rubygems_version: 2.0.6
45
47
  signing_key:
46
48
  specification_version: 4
47
- summary: ! 'ALPHA: Simple test runner for command line tools.'
49
+ summary: ! 'ALPHA: Lightweight test runner for command line tools.'
48
50
  test_files: []