command-unit 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []