specimen 0.0.1.alpha.b → 0.0.2.alpha

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +60 -19
  3. data/VERSION +1 -1
  4. data/bin/specimen +2 -2
  5. data/lib/specimen/cli.rb +6 -20
  6. data/lib/specimen/command/base.rb +35 -0
  7. data/lib/specimen/command/base_group.rb +35 -0
  8. data/lib/specimen/command/exec_command_builder.rb +47 -0
  9. data/lib/specimen/command/runner/cukes_runner.rb +26 -0
  10. data/lib/specimen/command/runner/exec_runner.rb +37 -0
  11. data/lib/specimen/command/runner/path_runner.rb +24 -0
  12. data/lib/specimen/command/runner/specs_runner.rb +25 -0
  13. data/lib/specimen/command/test_runner.rb +58 -0
  14. data/lib/specimen/command.rb +209 -0
  15. data/lib/specimen/commands/cukes/cukes_command.rb +9 -0
  16. data/lib/specimen/commands/exec/exec_command.rb +9 -0
  17. data/lib/specimen/commands/gem_help/USAGE +11 -0
  18. data/lib/specimen/commands/gem_help/gem_help_command.rb +23 -0
  19. data/lib/specimen/commands/init/USAGE +38 -0
  20. data/lib/specimen/commands/init/init_command.rb +49 -0
  21. data/lib/specimen/commands/specs/specs_command.rb +9 -0
  22. data/lib/specimen/extensions/ruby/hash.rb +1 -0
  23. data/lib/specimen/generator/configs/specimen_project_config.rb +122 -0
  24. data/lib/specimen/generator/cucumber/cucumber_project_generator.rb +28 -0
  25. data/lib/specimen/generator/cucumber/templates/config/cucumber.yml.tt +1 -0
  26. data/lib/specimen/generator/cucumber/templates/features/examples/add_numbers.feature.tt +9 -0
  27. data/lib/specimen/generator/cucumber/templates/features/support/env.rb.tt +0 -0
  28. data/lib/specimen/generator/file_by_template.rb +6 -4
  29. data/lib/specimen/generator/generator_base.rb +9 -0
  30. data/lib/specimen/generator/project/project_root_generator.rb +33 -0
  31. data/lib/specimen/generator/project/specimen_project_generator.rb +25 -0
  32. data/lib/specimen/generator/project/templates/root/.gitignore.tt +4 -0
  33. data/lib/specimen/generator/project/templates/root/config/specimen.yml.tt +38 -0
  34. data/lib/specimen/generator/project_generator_base.rb +34 -0
  35. data/lib/specimen/generator/rspec/rspec_project_generator.rb +28 -0
  36. data/lib/specimen/generator/rspec/templates/config/.rspec.tt +5 -0
  37. data/lib/specimen/generator/rspec/templates/spec/examples/example_spec.rb.tt +13 -0
  38. data/lib/specimen/generator/rspec/templates/spec/spec_helper.rb.tt +15 -0
  39. data/lib/specimen/generator.rb +8 -1
  40. data/lib/specimen/runtime/yml_parser.rb +49 -0
  41. data/lib/specimen/runtime.rb +84 -0
  42. data/lib/specimen/version.rb +4 -6
  43. data/lib/specimen.rb +11 -3
  44. metadata +99 -12
  45. data/lib/specimen/cli/default_command.rb +0 -37
  46. data/lib/specimen/generator/specimen_project.rb +0 -73
  47. data/lib/specimen/generator/specimen_project_config.rb +0 -54
  48. data/lib/specimen/generator/templates/specimen/specimen.yml.tt +0 -1
  49. /data/lib/specimen/generator/{templates/gemrc.tt → project/templates/root/.gemrc.tt} +0 -0
  50. /data/lib/specimen/generator/{templates/rbenv-gemsets.tt → project/templates/root/.rbenv-gemsets.tt} +0 -0
  51. /data/lib/specimen/generator/{templates/rubocop.yml.tt → project/templates/root/.rubocop.yml.tt} +0 -0
  52. /data/lib/specimen/generator/{templates → project/templates/root}/Gemfile.tt +0 -0
  53. /data/lib/specimen/generator/{templates → project/templates/root}/README.md.tt +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '091d4e836ac67953118af5d330c4254d7e29716b7cb3e2756369b45a0ba74a88'
4
- data.tar.gz: 69249e8db11054399bbc70c2fdee9163b9cbac769ae79ed55182c61f4083448a
3
+ metadata.gz: e3fce910bcf39219d89c6e71fc7b55f49190059d3b667075efbf3cc52c856023
4
+ data.tar.gz: 988fd2a04568f0e29bac692cc108e1086b9a3d200db7f74315ff4d56835a4bdf
5
5
  SHA512:
6
- metadata.gz: 83f173e5ecfe205b8581e18851aed9de5e0e19f52c995790f53af3316d7e16238d8ff02104339c360caf0db07916347c157664c955522bc89b6ad2a6c28dbcbe
7
- data.tar.gz: 0ab049182afb589bfe054d0325114cd0d3536c4ec9990df0e222bfd5ef8713e93b2e901dbf2ae534794e9fda09d5bd4a42a87e778d8142346ea6f1bd50d817fc
6
+ metadata.gz: 3445ddf6f2c1ff018d60153f9f6693d240ef61424f3783a6cc937ae6dfbd5f21e71354b24ea4aedca32ae0e7f301017adf59db1eb3cd564b938769c84000e64f
7
+ data.tar.gz: 7e4ff97d90c40fe7bfc2ee43da5826cc355b49531fc65cbf84d8771742ce8b17e1b6b2a34911decc1656196070e3642e87f92f41e9e61297512be77f3da17444
data/README.md CHANGED
@@ -8,36 +8,77 @@ will help me with:
8
8
  - provide a Rails like templating approach in terms of _convention over configuration_ to provide a maintainable base for
9
9
  API or UI tests using RSpec and/or Cucumber.
10
10
 
11
+ ## specimen commands
11
12
 
12
- **Beware**
13
+ ```shell
14
+ ❯ specimen
15
+ Usage:
16
+ specimen COMMAND [options]
13
17
 
14
- At the point of writing the README and setting the repo to public, the gem does not do much yet so the current functionality
15
- is minimal, not optimized and not tested :). Hopefully that will change in the future.
18
+ You must specify a command:
16
19
 
17
- ```shell
18
- # install Specimen gem
19
- $> gem install specimen
20
+ init Initialize a new specimen project
21
+ cukes Run Cucumber tests (WIP)
22
+ specs Run RSpec tests (WIP)
23
+ exec Run tests via a config file (WIP)
20
24
 
21
- # creates a new project relative to the current working directory. Will ask for a project name.
22
- $> specimen init
25
+ All commands can be run with -h (or --help) for more information.
26
+ ```
23
27
 
24
- # creates a new project 'foobar' relative to the current working directory.
25
- # Inside /foobar you will find the default dir structures for Cucumber and RSpec tests and a few more files
26
- $> specimen init -n foobar
28
+ ### specimen init
27
29
 
28
- # look at the command help
29
- $> specimen help init
30
+ ```shell
31
+ specimen init -h
30
32
  Usage:
31
- specimen init
33
+ specimen init --name=NAME [options] # Create a new specimen project which will generate following dirs and files
34
+
35
+ * default directories /config, /lib, /tmp
36
+ * default directories (/features/..) and files for cucumber unless --skip-cucumber
37
+ * default directories (/spec/..) and files for RSpec unless --skip-rspec
38
+ * root path files:
39
+ * .gemrc
40
+ * .gitignore
41
+ * .rspec (unless --skip-rspec)
42
+ * .rubocop.yml
43
+ * cucumber.yml (unless --skip-cucumber)
44
+ * Gemfile (based on the used options)
45
+ * README.md
46
+ * specimen.yml (default configuration file for the specimen gem
32
47
 
33
48
  Options:
34
- --name, -n, [--project-name=PROJECT_NAME]
35
- [--api-only], [--no-api-only], [--skip-api-only] # Default: false
36
- [--cucumber], [--no-cucumber], [--skip-cucumber] # Default: true
49
+ -n, [--name=NAME] # required: true
50
+ The name of your project and installation path relative to your current PWD
51
+
52
+ [--ui-driver=UI_DRIVER] # Default: 'watir'
53
+ Valid options are:
54
+ * watir
55
+ * selenium
56
+ * selenium-webdriver
57
+
58
+ [--skip-ui] # Default: false
59
+ Don´t add selenium or watir gem to your Gemfile
60
+
61
+ [--skip-cucumber] # Default: false
62
+ No cucumber gems will be added to your Gemfile.
63
+ Creation of cucumber directories and files will be skipped.
64
+
65
+ [--skip-rspec] # Default: false
66
+ RSpec will still be in your Gemfile (as it´s matchers are used for cucumber)
67
+ but no RSpec directories and files will be generated
37
68
  ```
38
69
 
70
+ ### specimen cukes
71
+
72
+ TBD
73
+
74
+ ### specimen specs
75
+
76
+ TBD
77
+
78
+ ### specimen exec
79
+
80
+ TBD
39
81
 
40
82
  ### Known issues
41
83
 
42
- - tests are missing
43
- - generated Gemfile contains Watir and Selenium webdriver, it should be only one of them.
84
+ - tests are missing
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1.alpha.b
1
+ 0.0.2.alpha
data/bin/specimen CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- lib_path = File.expand_path('..', __dir__) + '/lib'
4
+ lib_path = "#{File.expand_path('..', __dir__)}/lib"
4
5
  $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
5
6
 
6
7
  require 'specimen/cli'
7
- Specimen::CLI.start!(ARGV.dup)
data/lib/specimen/cli.rb CHANGED
@@ -1,25 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'specimen'
4
- require 'specimen/cli/default_command'
5
4
 
6
- module Specimen
7
- module CLI
8
- class << self
9
- def start!(args = ARGV)
10
- command = args.shift
5
+ config = {
6
+ verbose: ENV.key?('VERBOSE'),
7
+ strict: ENV.key?('STRICT'),
8
+ log_level: ENV.key?('LOG_LEVEL') ? ENV.fetch('LOG_LEVEL').to_sym : :info
9
+ }
11
10
 
12
- case command
13
- when '--version', '-v'
14
- show_version
15
- else
16
- DefaultCommand.start(ARGV.dup)
17
- end
18
- end
19
-
20
- def show_version
21
- puts(Specimen::VERSION::STRING)
22
- end
23
- end
24
- end
25
- end
11
+ Specimen::Command.execute!(ARGV.dup, config)
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class Base < Thor
6
+ include Thor::Actions
7
+
8
+ class << self
9
+ def exit_on_failure?
10
+ false
11
+ end
12
+ end
13
+
14
+ no_commands do
15
+ def usage_path
16
+ find_in_source_paths('USAGE')
17
+ rescue Thor::Error
18
+ ''
19
+ end
20
+
21
+ def usage_content
22
+ return '' if usage_path.empty?
23
+
24
+ File.read(usage_path)
25
+ end
26
+
27
+ def class_usage
28
+ return nil if usage_content.empty?
29
+
30
+ ERB.new(usage_content, trim_mode: '-').result(binding)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class BaseGroup < Thor::Group
6
+ include Thor::Actions
7
+
8
+ class << self
9
+ def exit_on_failure?
10
+ false
11
+ end
12
+ end
13
+
14
+ no_commands do
15
+ def usage_path
16
+ find_in_source_paths('USAGE')
17
+ rescue Thor::Error
18
+ ''
19
+ end
20
+
21
+ def usage_content
22
+ return '' if usage_path.empty?
23
+
24
+ File.read(usage_path)
25
+ end
26
+
27
+ def class_usage
28
+ return nil if usage_content.empty?
29
+
30
+ ERB.new(usage_content, trim_mode: '-').result(binding)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class ExecCommandBuilder
6
+ attr_reader :config
7
+
8
+ def initialize(config:, framework: nil, tests_path: '')
9
+ @framework = framework
10
+ @config = config
11
+ @tests_path = tests_path
12
+ end
13
+
14
+ def build_cmd
15
+ raise 'Undefined framework' if base_cmd.nil?
16
+
17
+ "#{env_string} #{base_cmd} #{options_string} #{@tests_path}".strip
18
+ end
19
+
20
+ def base_cmd
21
+ config['framework'] || @framework
22
+ end
23
+
24
+ def env_vars
25
+ config['env'] || []
26
+ end
27
+
28
+ def command_options
29
+ config['options'] || []
30
+ end
31
+
32
+ def env_string
33
+ return '' unless env_vars.any?
34
+
35
+ env_vars.join(' ')
36
+ end
37
+
38
+ def options_string
39
+ return '' unless command_options.any?
40
+
41
+ command_options.map(&:to_s).join(' ')
42
+ end
43
+ end
44
+
45
+
46
+ end
47
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class CukesRunner < PathRunner
6
+ no_commands do
7
+ def perform
8
+ super
9
+
10
+ check_config_not_nil!
11
+ inside runtime.work_dir do
12
+ run(exec_cmd)
13
+ end
14
+ end
15
+
16
+ def framework
17
+ profile_config['framework'] || 'cucumber'
18
+ end
19
+
20
+ def profile_name
21
+ profile? ? profile : 'cucumber'
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class ExecRunner < TestRunner
6
+ class_option :profile, aliases: %w[-p], type: :string
7
+
8
+ no_commands do
9
+ def perform
10
+ super
11
+
12
+ run_profile_check!
13
+ check_config_not_nil!
14
+ inside runtime.work_dir do
15
+ run(exec_cmd)
16
+ end
17
+ end
18
+
19
+ def tests_path
20
+ ''
21
+ end
22
+
23
+ def run_profile_check!
24
+ raise "Missing command option '--profile|-p'" unless profile?
25
+ end
26
+
27
+ def framework
28
+ profile_config['framework'] || nil
29
+ end
30
+
31
+ def profile_name
32
+ profile? ? profile : nil
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class PathRunner < TestRunner
6
+ argument :path, type: :string, default: ''
7
+
8
+ no_commands do
9
+ def arg_is_command_option?
10
+ return false if path.empty?
11
+
12
+ path.start_with?('--', '-')
13
+ end
14
+
15
+ def tests_path
16
+ return @tests_path if @tests_path
17
+ return '' if arg_is_command_option?
18
+
19
+ @tests_path = path
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class SpecsRunner < PathRunner
6
+ no_commands do
7
+ def perform
8
+ super
9
+ check_config_not_nil!
10
+ inside runtime.work_dir do
11
+ run(exec_cmd)
12
+ end
13
+ end
14
+
15
+ def framework
16
+ profile_config['framework'] || 'rspec'
17
+ end
18
+
19
+ def profile_name
20
+ profile? ? profile : 'rspec'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class TestRunner < BaseGroup
6
+ class ProfileDataNilError < RuntimeError
7
+ def initialize(profile_name, yml_name)
8
+ @msg = "No data found in '#{yml_name}' for profile: '#{profile_name}'"
9
+ super(@msg)
10
+ end
11
+ end
12
+
13
+ class_option :config_file, aliases: %w[-C --config], type: :string, default: 'specimen.yml'
14
+
15
+ no_commands do
16
+ def perform
17
+ runtime
18
+ end
19
+
20
+ def runtime
21
+ return @runtime if @runtime
22
+
23
+ runtime = Runtime.start!(self)
24
+ Specimen.runtime = runtime
25
+ @runtime = runtime
26
+ end
27
+
28
+ def framework
29
+ nil
30
+ end
31
+
32
+ def profile
33
+ options[:profile]
34
+ end
35
+
36
+ def profile?
37
+ !profile.nil?
38
+ end
39
+
40
+ def profile_config
41
+ runtime.profile_yml_data(profile_name)
42
+ end
43
+
44
+ def profile_name
45
+ profile? ? profile : nil
46
+ end
47
+
48
+ def exec_cmd
49
+ ExecCommandBuilder.new(config: profile_config, framework:, tests_path:).build_cmd
50
+ end
51
+
52
+ def check_config_not_nil!
53
+ raise ProfileDataNilError.new(profile_name, runtime.yml_name) if profile? && profile_config.nil?
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,209 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'colorize'
4
+ require 'thor'
5
+
6
+ require 'pry'
7
+
8
+ require 'specimen/command/base'
9
+ require 'specimen/command/base_group'
10
+ require 'specimen/command/test_runner'
11
+ require 'specimen/command/exec_command_builder'
12
+ require 'specimen/command/runner/path_runner'
13
+ require 'specimen/command/runner/cukes_runner'
14
+ require 'specimen/command/runner/exec_runner'
15
+ require 'specimen/command/runner/specs_runner'
16
+
17
+ require 'specimen/commands/cukes/cukes_command'
18
+ require 'specimen/commands/exec/exec_command'
19
+ require 'specimen/commands/gem_help/gem_help_command'
20
+ require 'specimen/commands/init/init_command'
21
+ require 'specimen/commands/specs/specs_command'
22
+
23
+ module Specimen
24
+ module Command
25
+ class InvalidCommandError < RuntimeError; end
26
+
27
+ extend ActiveSupport::Autoload
28
+
29
+ autoload :Base
30
+ autoload :BaseGroup
31
+
32
+ COMMAND_MAPPINGS = %w[cukes exec init specs generate test].to_set
33
+ HELP_MAPPINGS = %w[-h -? --help].to_set
34
+ VERSION_MAPPINGS = %w[-v --version].to_set
35
+
36
+ class << self
37
+ attr_reader :args, :config, :exec_config
38
+
39
+ def default_config
40
+ @default_config ||= {
41
+ verbose: false,
42
+ strict: false,
43
+ log_level: :info
44
+ }
45
+ end
46
+
47
+ def execute!(args = [], config = {})
48
+ @args = args.dup
49
+ @config = config
50
+ @exec_config = default_config.merge!(config)
51
+
52
+ trap_interrupt
53
+
54
+ raise InvalidCommandError, "'#{command_arg}' is not a valid specimen command!" unless valid_command?
55
+
56
+ show_gem_help_and_exit! if gem_help?
57
+ show_gem_version_and_exit! if show_version?
58
+ show_command_help_and_exit! if command_help?
59
+
60
+ command_perform!
61
+
62
+ exit_ok
63
+ rescue StandardError => e
64
+ shell.say(e.message.red.bold)
65
+
66
+ if exec_config[:verbose]
67
+ shell.say(e.class.to_s.red.bold)
68
+ shell.say(e.backtrace&.join("\n").red)
69
+ end
70
+
71
+ exit_specimen_failed
72
+ end
73
+
74
+ def show_gem_help_and_exit!
75
+ GemHelpCommand.new([]).perform
76
+
77
+ exit_ok
78
+ end
79
+
80
+ def show_command_help_and_exit!
81
+ display_command_help
82
+
83
+ exit_ok
84
+ end
85
+
86
+ def show_gem_version_and_exit!
87
+ shell.say("specimen version: #{Specimen.gem_version.to_s.bold}")
88
+
89
+ exit_ok
90
+ end
91
+
92
+ def display_command_help
93
+ shallow_command.class_usage.nil? ? shallow_command.class.help(shell) : shell.say(shallow_command.class_usage)
94
+ end
95
+
96
+ def command_perform!
97
+ command.new(command_arguments, parsed_command_options).perform
98
+ end
99
+
100
+ def shallow_command
101
+ @shallow_command ||= command.new([])
102
+ end
103
+
104
+ def command_arg
105
+ @command_arg ||= args.first
106
+ end
107
+
108
+ def command_arg?
109
+ !command_arg.nil?
110
+ end
111
+
112
+ def command_arguments
113
+ @command_arguments ||= args.reject { |arg| arg == command_arg }
114
+ end
115
+
116
+ def command
117
+ @command ||= {
118
+ cukes: CukesCommand,
119
+ exec: ExecCommand,
120
+ gem_help: GemHelpCommand,
121
+ init: InitCommand,
122
+ specs: SpecsCommand
123
+ }[command_arg.to_sym]
124
+ end
125
+
126
+ def command_class_options
127
+ command.class_options
128
+ end
129
+
130
+ def command_local_options
131
+ @command_local_options ||= {}
132
+ end
133
+
134
+ # need to look into that
135
+ def command_options_relation
136
+ {exclusive_option_names: [], at_least_one_option_names: []}
137
+ end
138
+
139
+ def disable_required_check?
140
+ return true if command_help?
141
+
142
+ command.disable_required_check? command
143
+ end
144
+
145
+ def stop_on_unknown_option?
146
+ exec_config[:strict] || false
147
+ end
148
+
149
+ def parsed_command_options
150
+ Thor::Options.new(
151
+ command_class_options,
152
+ command_local_options,
153
+ stop_on_unknown_option?,
154
+ disable_required_check?,
155
+ command_options_relation
156
+ ).parse(command_arguments)
157
+ end
158
+
159
+ def command?
160
+ COMMAND_MAPPINGS.include?(command_arg)
161
+ end
162
+
163
+ def command_help?
164
+ HELP_MAPPINGS.include?(command_arguments.first)
165
+ end
166
+
167
+ def gem_help?
168
+ return true if command_arg.nil?
169
+
170
+ HELP_MAPPINGS.include?(command_arg)
171
+ end
172
+
173
+ def valid_command?
174
+ command? || gem_help? || show_version?
175
+ end
176
+
177
+ def show_version?
178
+ return false if command_arg.nil?
179
+
180
+ VERSION_MAPPINGS.include?(command_arg)
181
+ end
182
+
183
+ private
184
+
185
+ def shell
186
+ @shell ||= Thor::Base.shell.new
187
+ end
188
+
189
+ def exit_ok
190
+ Kernel.exit(0)
191
+ end
192
+
193
+ def exit_specimen_failed
194
+ Kernel.exit(1)
195
+ end
196
+
197
+ def exit_unable_to_finish
198
+ Kernel.exit(2)
199
+ end
200
+
201
+ def trap_interrupt
202
+ Signal.trap('INT') do
203
+ shell.say("\nExiting... Interrupt again to exit immediately.".red.bold)
204
+ exit_unable_to_finish
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class CukesCommand < CukesRunner
6
+ namespace :cukes
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Specimen
4
+ module Command
5
+ class ExecCommand < ExecRunner
6
+ namespace :exec
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ Usage:
2
+ specimen COMMAND [options]
3
+
4
+ You must specify a command:
5
+
6
+ init Initialize a new specimen project
7
+ cukes Run Cucumber tests (WIP)
8
+ specs Run RSpec tests (WIP)
9
+ exec Run tests via a config file (WIP)
10
+
11
+ All commands can be run with -h (or --help) for more information.