rspec-cli 0.2.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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OWUxYmRlNWRjOTM1YjY0MDljNWI4ZWY2NWZmOWY0NDcwZTMwMzJhZg==
5
+ data.tar.gz: !binary |-
6
+ N2RhZTg3MjNiMGQ3ZWIxMGRmNjMwYzRkYmIxMjI3MTM5MmZhZmQ3OA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YTQyMzAyMmU0YTU0MjEzNjIxMDJkY2Q2Yjg1YTVlMzY5MDQwNjcyNWY5YWYz
10
+ MDljNGUxMjE4NmI0NDA4MTFkNWQxZGM1NDhmMzdhZTk2ZGU1ODg4MTUzZDYx
11
+ MzdjZjE4MWQ2YmRjNjc2Y2QxZTUxMjcwMmI2NTlkYTEwNTU3YTg=
12
+ data.tar.gz: !binary |-
13
+ MDRlMGRjN2M1N2JmNjgyYmVlMTlmYTU5ZDVhZDZjYTM5YTU2ZTI2OTg3YjIz
14
+ NTc0ZWIzYjVlZWNkZjQ3NTQ1MWM2NGEyYWYzNmEwZWM4MDZiNjE5YWFlMDEz
15
+ NTUxNjQ1MWFmMzY4MjUzMWVmZDA2MDZhMGM1YWNmOGMwNDRjZDQ=
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .#*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rspec-cli.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+ guard 'rspec', cmd: 'rspec'do
2
+
3
+ watch(%r{^spec/.+_spec\.rb$})
4
+ watch(%r{^lib/rspec/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
5
+
6
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Sia. S.
2
+
3
+ MIT License
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,50 @@
1
+ # RSpec::Cli
2
+
3
+ This is an extension to rspec to fascilitate cli testing.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'rspec-cli'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install rspec-cli
20
+
21
+ ## Usage
22
+
23
+ In your rspec config
24
+
25
+ ```ruby
26
+ RSpec.configure do |config|
27
+ config.include RSpec::Cli, type: :feature
28
+
29
+ config.alias_example_group_to :feature, :type => :feature
30
+ config.alias_example_to :scenario
31
+ end
32
+ ```
33
+ or similar.
34
+
35
+ Now your feature specs will have helper methods
36
+ ```new_cli_process(%w[echo hi there :D])``` and ```spawn_cli_process(%w[echo hi there :D])```
37
+
38
+ The first one returns a CliProcess instance that hasn't spawned your command yet.
39
+
40
+ The second one returns a CliProcess instance that has spawned your command.
41
+
42
+ The CliProcess instance has some useful methads like ```#read``` to read from it's stdout, ```#write(string)``` to write to it's stdin and ```#status``` to get the process's status.
43
+
44
+ ## Contributing
45
+
46
+ 1. Fork it ( https://github.com/[my-github-username]/rspec-cli/fork )
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,109 @@
1
+ require 'pty'
2
+ require 'rspec/cli/i_o_decorator'
3
+
4
+ module RSpec
5
+
6
+ module Cli
7
+
8
+ ##
9
+ # This class spawns your process and provides some
10
+ # helpers to interact with the process
11
+ class CliProcess
12
+
13
+ TERMINAL_COLOURS = /\e\[(\d+)(;\d+)*m/
14
+
15
+ attr_reader :pid
16
+
17
+ def initialize(*args)
18
+ raise ArgumentError, "wrong number of arguments" if args.empty?
19
+ args.unshift(*args.shift) if Array === args.first
20
+ @command = args
21
+ end
22
+
23
+ def flush
24
+ assert_spawned
25
+ @master.flush
26
+ end
27
+
28
+ def read_all(*args)
29
+ assert_spawned
30
+ @master.flush
31
+ @master.ready_all *args
32
+ end
33
+
34
+ def gets
35
+ assert_spawned
36
+ @master.gets
37
+ end
38
+
39
+ def puts(*args)
40
+ assert_spawned
41
+ @master.puts args
42
+ @master.flush
43
+ end
44
+
45
+ def stdout
46
+ @master
47
+ end
48
+
49
+ def stdin
50
+ @slave
51
+ end
52
+
53
+ def write(arg)
54
+ # This method can block if the argument is huge
55
+ assert_spawned
56
+ @master.write "#{arg}\n"
57
+ @master.flush
58
+ end
59
+
60
+ def run!
61
+ # Create master and slave pseudo terminal devices
62
+ master_tty, slave_tty = PTY.open
63
+ @master = IODecorator.new master_tty
64
+ @slave = slave_tty
65
+
66
+ @pid = PTY.spawn(*@command, in: @slave, out: @slave, err: @slave)[2]
67
+
68
+ @slave.close
69
+
70
+ self
71
+
72
+ end
73
+
74
+ def status
75
+
76
+ assert_spawned
77
+ PTY.check(@pid)
78
+
79
+ end
80
+
81
+ def alive?
82
+
83
+ begin
84
+ return status.nil?
85
+ rescue
86
+ return false
87
+ end
88
+
89
+ end
90
+
91
+ def kill!(signal = "TERM")
92
+
93
+ assert_spawned
94
+ @master.close
95
+ Process.kill(signal, @pid)
96
+
97
+ end
98
+
99
+ private
100
+
101
+ def assert_spawned
102
+ raise "process hasn't spawned yet" if @pid.nil?
103
+ end
104
+
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,32 @@
1
+ require 'pty'
2
+ require 'delegate'
3
+
4
+ module RSpec
5
+
6
+ module Cli
7
+
8
+ class IODecorator < SimpleDelegator
9
+
10
+ def has_data?(timeout = 0)
11
+ IO.select([self], nil, nil, timeout) ? true : false
12
+ end
13
+
14
+ def ready_all nonblocking = false
15
+ if nonblocking && !has_data?
16
+ return nil
17
+ end
18
+
19
+ # Block until data has arrived.
20
+ data = readpartial 0xFFFF
21
+ # If there is more data in the buffer, retrieve it nonblocking.
22
+ while has_data?
23
+ data << readpartial(0xFFFF)
24
+ end
25
+ data
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,5 @@
1
+ module RSpec
2
+ module Cli
3
+ VERSION = "0.2.1"
4
+ end
5
+ end
data/lib/rspec/cli.rb ADDED
@@ -0,0 +1,18 @@
1
+ require "rspec/cli/version"
2
+ require "rspec/cli/cli_process"
3
+
4
+ module RSpec
5
+
6
+ module Cli
7
+
8
+ def spawn_cli_process(*args)
9
+ new_cli_process(*args).run!
10
+ end
11
+
12
+ def new_cli_process(*args)
13
+ CliProcess.new(*args)
14
+ end
15
+
16
+ end
17
+
18
+ end
data/rspec-cli.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rspec/cli/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rspec-cli"
8
+ spec.version = RSpec::Cli::VERSION
9
+ spec.authors = ["Sia. S."]
10
+ spec.email = ["sia.s.saj@gmail.com"]
11
+ spec.summary = "rspec-cli-#{RSpec::Cli::VERSION}"
12
+ spec.description = "A set of tools to test programs on the command line"
13
+ spec.homepage = "https://github.com/quazimodo/rspec-cli"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.1"
24
+
25
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+ require 'rspec/cli/cli_process'
3
+
4
+ describe RSpec::Cli::CliProcess do
5
+
6
+ let(:looper) do
7
+ RSpec::Cli::CliProcess.new(%w[spec/support/bin/dummy --looper])
8
+ end
9
+
10
+ let(:echo) do
11
+ RSpec::Cli::CliProcess.new %w[spec/support/bin/dummy --echo "interesting repeat"]
12
+ end
13
+
14
+
15
+
16
+ it "initializes with a binary and a set of arguments" do
17
+ expect{RSpec::Cli::CliProcess.new %w[echo who are you] }.not_to raise_error
18
+ end
19
+
20
+ it "initializes without actually spawning any process" do
21
+ expect(PTY).not_to receive(:spawn)
22
+ expect(echo.pid).to eq nil
23
+ end
24
+
25
+ describe "#run!" do
26
+
27
+ it "spawns process and sets the pid" do
28
+ echo.run!
29
+ expect(echo.pid).not_to eq nil
30
+ end
31
+
32
+ it "assigns the new process's stdout to a tty by default" do
33
+ allow_any_instance_of(File).to receive(:close)
34
+ echo.run!
35
+ expect(echo.stdout).to be_a_tty
36
+ end
37
+
38
+ it "assigns the new process's stdin to a tty by default" do
39
+ allow_any_instance_of(File).to receive(:close)
40
+ echo.run!
41
+ expect(echo.stdin).to be_a_tty
42
+ end
43
+
44
+ end
45
+
46
+ describe "#status" do
47
+
48
+ it "raises an error if the process hasn't spawned yet" do
49
+ expect{echo.status}.to raise_error "process hasn't spawned yet"
50
+ end
51
+
52
+ it "returns nil if the process is still alive" do
53
+ looper.run!
54
+ expect(looper.status).to eq nil
55
+ end
56
+
57
+ it "returns a Process::Status object if the process has spawned and terminated" do
58
+ looper.run!
59
+ looper.kill!
60
+ sleep 0.1
61
+ expect(looper.status).to be_a_kind_of Process::Status
62
+ end
63
+
64
+ end
65
+
66
+ describe "#write" do
67
+
68
+ it "writes to the spawned processes stdin" do
69
+ looper.run!
70
+ looper.write "hi there"
71
+ expect(looper.gets).to include "hi there"
72
+ end
73
+
74
+ it "puts to the spawned process stdin" do
75
+ looper.run!
76
+ looper.puts "hi there"
77
+ expect(looper.gets).to include "hi there"
78
+ end
79
+
80
+ it "raises an error if the process hasn't been spawned" do
81
+ expect{looper.write "hi"}.to raise_error
82
+ end
83
+
84
+ end
85
+
86
+ describe "#kill" do
87
+
88
+ it "closes all remaining streams" do
89
+ looper.run!
90
+ pty = looper.instance_variable_get(:@master)
91
+ expect(pty).to receive(:close)
92
+ looper.kill!
93
+ end
94
+
95
+ it "raises an error if the process hasn't spawned" do
96
+ expect{looper.read}.to raise_error
97
+ end
98
+
99
+ it "terminates the process using SIGTERM" do
100
+ looper.run!
101
+ pid = looper.pid
102
+ expect(Process).to receive(:kill).with("TERM", pid).and_call_original
103
+ looper.kill!
104
+ expect(Process.wait looper.pid).to eq looper.pid
105
+ end
106
+
107
+ it "terminates the process using given signal" do
108
+ looper.run!
109
+ pid = looper.pid
110
+ expect(Process).to receive(:kill).with("KILL", pid).and_call_original
111
+ looper.kill!("KILL")
112
+ expect(Process.wait looper.pid).to eq looper.pid
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ require 'rspec/cli/i_o_decorator'
3
+
4
+ describe RSpec::Cli::IODecorator do
5
+
6
+
7
+
8
+ let(:pipe_arry) { IO.pipe }
9
+
10
+ let(:pipe_out) { pipe_arry[0] }
11
+ let(:pipe_in) { pipe_arry[1] }
12
+
13
+ let(:io_out) { RSpec::Cli::IODecorator.new pipe_out }
14
+ let(:io_in) { RSpec::Cli::IODecorator.new pipe_in }
15
+
16
+
17
+ describe "#has_data?" do
18
+
19
+ it "returns true if io has data to read" do
20
+ io_in.puts "test_data"
21
+ expect(io_out.has_data?).to be true
22
+ end
23
+
24
+ it "returns false if io has no data to reads" do
25
+ expect(io_out.has_data?).to be false
26
+ end
27
+
28
+ end
29
+
30
+ describe "#read_all" do
31
+
32
+ context "with nonblocking reads" do
33
+
34
+ it 'returns nil if no data' do
35
+ expect(io_out.read_all(nonblocking: true)).to be nil
36
+ end
37
+
38
+ it "returns all the data if there is data" do
39
+ io_in.puts "hi, this"
40
+ io_in.puts "is test data"
41
+ expect(io_out.read_all(nonblocking: true)).to include "hi, this\nis test data"
42
+ end
43
+
44
+ it "doesn't fall into a race condition with another process interacting with it" do
45
+ master_tty, slave_tty = PTY.open
46
+
47
+ master = RSpec::Cli::IODecorator.new master_tty
48
+
49
+ command = "spec/support/bin/dummy --looper --sleeper 0.1"
50
+ @pid = PTY.spawn(command, in: slave_tty, out: slave_tty, err: slave_tty)[2]
51
+
52
+ master.write "hi there"
53
+ expect(master.read_all).to include "hi there"
54
+ end
55
+ end
56
+
57
+
58
+ context "with blocking reads" do
59
+
60
+ it 'blocks till data arrives' do
61
+ test = lambda do
62
+ Timeout::timeout(1) { io_out.read_all }
63
+ end
64
+
65
+ expect(test).to raise_error Timeout::Error
66
+ end
67
+
68
+ it 'reads all the data when available' do
69
+
70
+ data = nil
71
+ huge_string = "BC" * 0xFFFF
72
+ huge_string << "ends in awesome"
73
+
74
+ # declare the block that we will call in our test
75
+ test = lambda do
76
+ Timeout::timeout(1) { data = io_out.read_all }
77
+ end
78
+
79
+ # the huge_string might be too big for the buffer and block
80
+ # while the system waits for the buffer to be read from,
81
+ # so we do the write in a new thread.
82
+ Thread.new do
83
+ io_in.syswrite huge_string
84
+ end
85
+
86
+ expect(test).to change{data}.to huge_string
87
+
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+
94
+ end
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'rspec/cli'
3
+
4
+ describe RSpec::Cli do
5
+
6
+ let(:subject) { Object.new.extend RSpec::Cli }
7
+
8
+ describe "::new_cli_process" do
9
+
10
+ it "returns a CliProcess object that has not actually spawned the process yet" do
11
+ p = subject.new_cli_process %w[factor]
12
+ expect(p.pid).to eq nil
13
+ end
14
+
15
+ end
16
+
17
+ describe "::spawn_cli_process" do
18
+
19
+ it "returns a CliProcess object with a spawned process" do
20
+ p = subject.spawn_cli_process %w[factor]
21
+ expect(p.pid).not_to eq nil
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,19 @@
1
+ Dir.glob(::File.expand_path('../support/*.rb', __FILE__)).each { |f| require_relative f }
2
+
3
+ RSpec.configure do |config|
4
+
5
+ config.filter_run :focus
6
+ config.run_all_when_everything_filtered = true
7
+ config.order = :random
8
+
9
+ config.expect_with :rspec do |expectations|
10
+ expectations.syntax = :expect
11
+ end
12
+
13
+ config.mock_with :rspec do |mocks|
14
+ mocks.syntax = :expect
15
+ # Prevents you from mocking or stubbing a method that does not exist on
16
+ # a real object. This is generally recommended.
17
+ mocks.verify_partial_doubles = true
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+
4
+
5
+ options = {}
6
+ OptionParser.new do |opts|
7
+ opts.banner = "Dummy executable to help test rspec-cli"
8
+
9
+ opts.on("-l", "--looper", "start in read/print loop mode") do
10
+ options[:looper] = true
11
+ end
12
+
13
+ opts.on("-e str", "--echo str", "echo str arg") do |echo|
14
+ options[:echo] = echo
15
+ end
16
+
17
+ opts.on("-s seconds", "--sleeper seconds", "echo str arg") do |seconds|
18
+ options[:sleeper] = seconds
19
+ end
20
+ end.parse!
21
+
22
+ puts "Dummy has loaded"
23
+
24
+ if options[:looper]
25
+
26
+ loop do
27
+ i = gets
28
+ sleep(options[:sleeper].to_f) unless options[:sleeper].nil?
29
+ puts i
30
+ end
31
+
32
+ elsif options[:echo]
33
+
34
+ puts options[:echo]
35
+
36
+ end
37
+
38
+
39
+ exit 0
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rspec-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Sia. S.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ description: A set of tools to test programs on the command line
56
+ email:
57
+ - sia.s.saj@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - Gemfile
65
+ - Guardfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - lib/rspec/cli.rb
70
+ - lib/rspec/cli/cli_process.rb
71
+ - lib/rspec/cli/i_o_decorator.rb
72
+ - lib/rspec/cli/version.rb
73
+ - rspec-cli.gemspec
74
+ - spec/cli/cli_process_spec.rb
75
+ - spec/cli/i_o_decorator_spec.rb
76
+ - spec/cli_spec.rb
77
+ - spec/spec_helper.rb
78
+ - spec/support/bin/dummy
79
+ homepage: https://github.com/quazimodo/rspec-cli
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.3.0
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: rspec-cli-0.2.1
103
+ test_files:
104
+ - spec/cli/cli_process_spec.rb
105
+ - spec/cli/i_o_decorator_spec.rb
106
+ - spec/cli_spec.rb
107
+ - spec/spec_helper.rb
108
+ - spec/support/bin/dummy
109
+ has_rdoc: