baf 0.14.1 → 0.15.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9311e4cba4d27aee336f9983d97efd78d8296b5672ec1dccc3337056b66ba620
4
- data.tar.gz: a9ba3e9ab48e78e71173faaa63eece4addadcc9573e28ea6d3b19adbe6fc41c9
3
+ metadata.gz: c3dd2c36e21fb8a41d21f0d3ea90c5126274b9f68f19f4b2cb0f09c33aa38605
4
+ data.tar.gz: 9cf8f0b59d4b8cbb70f174912f2569f204fd27a82236a8e992c6729b366cc574
5
5
  SHA512:
6
- metadata.gz: 7aeeb1da2a0f359a5a537580ab13384b3cba5501a6c00722c0f025760eb4c31c951ddf0616410138520bd2457972386dd1bf9bd976259aa271d6365187a0d6e7
7
- data.tar.gz: 74267eaf156de24338b988e46960565cb1eefc6dc5b241ccb1dba4db022ed6bd313f5932d944833ab010f858b314daeb3145318e01a8a6b52925e730f753f1af
6
+ metadata.gz: bcc9f8fb5658bb47c75067a09912585878ee73ab227c09628eb4d2742e3f360a8c2f55b3effa1e2acc1329f130046f8ec76caefa66d6c468fbdce46596ba6370
7
+ data.tar.gz: 8aa8f06dee9cb55a12e560177c80a44f724c4fab30b5a5e9de9764f7fdd4eb12d0e9e76ebdedbad4fdd5fbb7cb58ea101fb3402d68d56fd191a0297b0dd198bb
data/lib/baf/option.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  module Baf
2
2
  class Option
3
- LONG_PREFIX = '--'.freeze
4
- LONG_NORMALIZE_SEARCH = ?_.freeze
5
- LONG_NORMALIZE_REPLACE = ?-.freeze
6
- LONG_WITH_ARG_GLUE = ' '.freeze
7
- PARSER_MESSAGE = :on
8
- PARSER_MESSAGE_TAIL = :on_tail
3
+ LONG_PREFIX = '--'.freeze
4
+ LONG_NORMALIZE_SEARCH = ?_.freeze
5
+ LONG_NORMALIZE_REPLACE = ?-.freeze
6
+ LONG_WITH_ARG_GLUE = ' '.freeze
7
+ PARSER_MESSAGE = :on
8
+ PARSER_MESSAGE_TAIL = :on_tail
9
9
 
10
10
  attr_accessor :short, :long, :arg, :desc, :block, :tail
11
11
 
@@ -3,8 +3,8 @@ require 'baf/option'
3
3
 
4
4
  module Baf
5
5
  class OptionsRegistrant
6
- SUMMARY_HEADER = "\noptions:".freeze
7
- HELP_PARSER_ARGS = %w[
6
+ SUMMARY_HEADER = "\noptions:".freeze
7
+ HELP_PARSER_ARGS = %w[
8
8
  -h
9
9
  --help
10
10
  print\ this\ message
@@ -1,50 +1,35 @@
1
- def program_run check: false, opts: nil, args: nil, wait: true
2
- cmd = [*@_baf_program ||= %w[ruby baf]]
3
- cmd << opts if opts
4
- cmd << args.split(' ') if args
5
- if wait
6
- run_simple cmd.join(' '), fail_on_error: false
7
- else
8
- run cmd.join ' '
9
- end
10
- program_run_check if check
11
- end
12
-
13
- def program_run_check status: 0
14
- expect(last_command_started).to have_exit_status status
15
- rescue RSpec::Expectations::ExpectationNotMetError => e
16
- if ENV.key? 'BAF_TEST_DEBUG'
17
- fail RSpec::Expectations::ExpectationNotMetError, <<-eoh
18
- #{e.message} Output was:
19
- ```\n#{last_command_started.output.lines.map { |l| " #{l}" }.join} ```
20
- eoh
21
- else
22
- raise
23
- end
1
+ def run state, cmd: nil, wait: true, args: []
2
+ cmd ||= state[:program]
3
+ Baf::Testing.run cmd + args,
4
+ wait: wait,
5
+ env_allow: state.fetch(:env_allow) { [] },
6
+ timeout: state[:exec_timeout]
24
7
  end
25
8
 
26
9
 
27
10
  When /^I( successfully)? (run|\w+) the program$/ do |check, run|
28
- program_run check: !!check, wait: run == 'run'
29
- end
30
-
31
- When /^I( successfully)? (run|\w+) the program with arguments? (.+)$/ do |check, run, args|
32
- program_run check: !!check, args: args, wait: run == 'run'
11
+ $_baf[:process] = run $_baf, wait: run == 'run'
12
+ Baf::Testing.expect_ex $_baf[:process], 0 if check
33
13
  end
34
14
 
35
- When /^I( successfully)? (run|\w+) the program with command (.+)$/ do |check, run, cmd|
36
- program_run check: !!check, args: cmd, wait: run == 'run'
15
+ When(
16
+ /^I( successfully)? (run|\w+) the program with (?:argument|command|option)s? (.+)$/
17
+ ) do |check, run, args|
18
+ $_baf[:process] = run $_baf, wait: run == 'run', args: args.split(' ')
19
+ Baf::Testing.expect_ex $_baf[:process], 0 if check
37
20
  end
38
21
 
39
- When /^I( successfully)? (run|\w+) the program with options? (-.+)$/ do |check, run, opts|
40
- program_run check: !!check, opts: opts, wait: run == 'run'
22
+ When /^I( successfully)? (run|\w+) `([^`]+)`$/ do |check, run, command|
23
+ $_baf[:process] = run $_baf, cmd: command.split(' '), wait: run == 'run'
24
+ Baf::Testing.expect_ex $_baf[:process], 0 if check
41
25
  end
42
26
 
43
27
 
44
- Then /^the exit status must be (\d+)$/ do |exit_status|
45
- program_run_check status: exit_status.to_i
28
+ Then /^the program must terminate successfully$/ do
29
+ Baf::Testing.wait $_baf[:process]
30
+ Baf::Testing.expect_ex $_baf[:process], 0
46
31
  end
47
32
 
48
- Then /^the program must terminate successfully$/ do
49
- program_run_check status: 0
33
+ Then /^the exit status must be (\d+)$/ do |exit_status|
34
+ Baf::Testing.expect_ex $_baf[:process], Integer(exit_status)
50
35
  end
@@ -0,0 +1,3 @@
1
+ Given /^a file named ([^ ]+) with:$/ do |path, content|
2
+ Baf::Testing.write_file path, content + $/
3
+ end
@@ -1,3 +1,3 @@
1
1
  When /^I input "([^"]+)"$/ do |content|
2
- last_command_started.write unescape_text content
2
+ $_baf[:process].input Baf::Testing.unescape_step_arg content
3
3
  end
@@ -1,44 +1,35 @@
1
- def build_regexp pattern, options
2
- Regexp.new(pattern, options.each_char.inject(0) do |m, e|
3
- m | case e
4
- when ?i then Regexp::IGNORECASE
5
- when ?m then Regexp::MULTILINE
6
- when ?x then Regexp::EXTENDED
7
- end
8
- end)
9
- end
10
-
11
- def expect_output content, stream: :output
12
- stream = :stderr if stream == :error
13
- expect(last_command_started.send stream).to eq unescape_text content
14
- end
15
-
16
-
17
1
  Then /^the output must be empty$/ do
18
- expect(last_command_started.output).to be_empty
2
+ expect($_baf[:process].output).to be_empty
19
3
  end
20
4
 
21
5
  Then /^the output must contain:$/ do |content|
22
- expect(last_command_started.output).to include unescape_text content
6
+ expect($_baf[:process].output).to include content
23
7
  end
24
8
 
25
9
  Then /^the output must contain "([^"]+)"$/ do |content|
26
- expect(last_command_started.output).to include unescape_text content
10
+ expect($_baf[:process].output).to include content
27
11
  end
28
12
 
29
13
  Then /^the output must not contain "([^"]+)"$/ do |content|
30
- expect(last_command_started.output).not_to include unescape_text content
14
+ expect($_baf[:process].output).not_to include content
31
15
  end
32
16
 
33
17
  Then /^the output must contain exactly:$/ do |content|
34
- expect_output content + $/
18
+ expect($_baf[:process].output).to eq content + $/
35
19
  end
36
20
 
37
21
  Then /^the( error)? output must contain exactly "([^"]+)"$/ do |stream, content|
38
22
  stream = stream ? :error : :output
39
- expect_output content, stream: stream
23
+ expect($_baf[:process].output stream)
24
+ .to eq Baf::Testing::unescape_step_arg content
25
+ end
26
+
27
+ Then /^the output must match:/ do |pattern|
28
+ expect($_baf[:process].output)
29
+ .to match Baf::Testing.build_regexp(pattern, 'mx')
40
30
  end
41
31
 
42
32
  Then /^the output must match \/([^\/]+)\/([a-z]*)$/ do |pattern, options|
43
- expect(last_command_started.output).to match build_regexp(pattern, options)
33
+ expect($_baf[:process].output)
34
+ .to match Baf::Testing.build_regexp(pattern, options)
44
35
  end
@@ -1,57 +1,16 @@
1
- require 'timeout'
2
-
3
- module Baf
4
- module Testing
5
- class WaitError < ::StandardError
6
- attr_reader :timeout
7
-
8
- def initialize message, timeout
9
- super message
10
- @timeout = timeout
11
- end
12
- end
13
- end
14
- end
15
-
16
- def wait_output! pattern, times: 1, results: nil
17
- output = -> { last_command_started.output }
18
- wait_until do
19
- case pattern
20
- when Regexp then (results = output.call.scan(pattern)).size >= times
21
- when String then output.call.include? pattern
22
- end
23
- end
24
- results
25
- rescue Baf::Testing::WaitError => e
26
- fail <<-eoh
27
- expected `#{pattern}' not seen after #{e.timeout} seconds in:
28
- ```\n#{output.call.lines.map { |l| " #{l}" }.join} ```
29
- eoh
30
- end
31
-
32
- def wait_until message: 'condition not met after %d seconds'
33
- timeout = ENV.key?('BAF_TEST_TIMEOUT') ?
34
- ENV['BAF_TEST_TIMEOUT'].to_i :
35
- 2
36
- Timeout.timeout timeout do
37
- loop do
38
- break if yield
39
- sleep 0.05
40
- end
41
- end
42
- rescue Timeout::Error
43
- fail Baf::Testing::WaitError.new(message % timeout, timeout)
1
+ def wait_output pattern, output: -> { $_baf[:process].output }, times: 1
2
+ Baf::Testing.wait_output pattern, stream: output, times: times
44
3
  end
45
4
 
46
5
 
47
6
  Then /^the output will match \/([^\/]+)\/([a-z]*)$/ do |pattern, options|
48
- wait_output! build_regexp pattern, options
7
+ wait_output Baf::Testing.build_regexp pattern, options
49
8
  end
50
9
 
51
10
  Then /^the output will contain:$/ do |content|
52
- wait_output! content + $/
11
+ wait_output content + $/
53
12
  end
54
13
 
55
14
  Then /^the output will contain "([^"]+)"$/ do |content|
56
- wait_output! content
15
+ wait_output content
57
16
  end
@@ -1,5 +1,11 @@
1
- require 'aruba/api'
2
- require 'aruba/cucumber/hooks'
3
-
1
+ require 'baf/testing'
4
2
  require 'baf/testing/cucumber/steps/execution'
3
+ require 'baf/testing/cucumber/steps/filesystem'
5
4
  require 'baf/testing/cucumber/steps/output'
5
+
6
+ $_baf = {}
7
+
8
+ Around do |_, block|
9
+ Baf::Testing.exercise_scenario &block
10
+ $_baf.delete :process
11
+ end
@@ -0,0 +1,107 @@
1
+ require 'baf'
2
+
3
+ require 'tempfile'
4
+
5
+ module Baf
6
+ module Testing
7
+ class Process
8
+ ExecutionFailure = Class.new Error
9
+
10
+ TIMEOUT = 4
11
+ TMP_FILE_PREFIX = 'baf_test_'.freeze
12
+ WAIT_POLL_DELAY = 0.01
13
+
14
+ attr_reader :pid, :exit_status, :timeout
15
+
16
+ def initialize command, env_allow: [], timeout: TIMEOUT
17
+ @command = command
18
+ @env_allow = env_allow
19
+ @timeout = timeout
20
+ @stdout = Tempfile.new TMP_FILE_PREFIX
21
+ @stderr = Tempfile.new TMP_FILE_PREFIX
22
+ end
23
+
24
+ def start
25
+ reader, writer = IO.pipe
26
+
27
+ @pid = spawn env,
28
+ *@command,
29
+ unsetenv_others: true,
30
+ in: reader,
31
+ out: @stdout,
32
+ err: @stderr
33
+ reader.close
34
+ @stdin = writer
35
+ rescue Errno::ENOENT => e
36
+ fail ExecutionFailure, e.message
37
+ end
38
+
39
+ def wait timeout: @timeout
40
+ deadline = Time.now + timeout
41
+ wait_poll
42
+ until stopped? || Time.now >= deadline
43
+ sleep WAIT_POLL_DELAY
44
+ wait_poll
45
+ end
46
+ yield unless stopped? if block_given?
47
+ end
48
+
49
+ def stop wait_timeout: 1
50
+ ::Process.kill :TERM, @pid
51
+ wait timeout: wait_timeout
52
+ return if stopped?
53
+ ::Process.kill :KILL, @pid
54
+ ::Process.wait2 @pid
55
+ rescue Errno::ECHILD, Errno::ESRCH
56
+ end
57
+
58
+ def running?
59
+ started? && !stopped?
60
+ end
61
+
62
+ def input str
63
+ @stdin.write str
64
+ end
65
+
66
+ def output stream = nil
67
+ case stream
68
+ when :output then [@stdout]
69
+ when :error then [@stderr]
70
+ else [@stdout, @stderr]
71
+ end.inject '' do |memo, stream|
72
+ memo + IO.read(stream.path)
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def env
79
+ ENV.inject({}) do |acc, (k, v)|
80
+ if env_allow? k then acc.merge k => v else acc end
81
+ end.merge 'HOME' => File.realpath(?.)
82
+ end
83
+
84
+ def env_allow? var
85
+ @env_allow.any? do |e|
86
+ case e
87
+ when String then var == e
88
+ when Regexp then var =~ e
89
+ end
90
+ end
91
+ end
92
+
93
+ def started?
94
+ !!@pid
95
+ end
96
+
97
+ def stopped?
98
+ !!@exit_status
99
+ end
100
+
101
+ def wait_poll
102
+ pid, status = ::Process.wait2 @pid, ::Process::WNOHANG
103
+ @exit_status = status.exitstatus if pid
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,138 @@
1
+ require 'fileutils'
2
+
3
+ require 'baf'
4
+ require 'baf/testing/process'
5
+
6
+ module Baf
7
+ module Testing
8
+ ExecutionTimeout = Class.new Error
9
+ ExitStatusMismatch = Class.new Error
10
+
11
+ class WaitError < Error
12
+ attr_reader :timeout
13
+
14
+ def initialize message, timeout
15
+ super message
16
+ @timeout = timeout
17
+ end
18
+ end
19
+
20
+ ENV_WHITELIST = [
21
+ /\ACHRUBY_/,
22
+ /\AGEM_/,
23
+ 'PATH',
24
+ /\ARB_/,
25
+ 'RUBYOPT'
26
+ ].freeze
27
+
28
+ EXEC_TIMEOUT_ERROR_FMT = 'process did not exit after %.03f seconds'.freeze
29
+
30
+ EXIT_STATUS_MISMATCH_FMT = <<~eoh.freeze
31
+ expected %<expected>d exit status got %<actual>d; output was:
32
+ %{separator}
33
+ %{output}
34
+ %{separator}
35
+ eoh
36
+
37
+ OUTPUT_SEPARATOR = (?- * 70).freeze
38
+
39
+ WAIT_MESSAGE_FMT = 'condition not met after %.03f seconds'.freeze
40
+ WAIT_OUTPUT_MESSAGE_FMT = <<~eoh.freeze
41
+ expected `%{pattern}' not seen after %<timeout>.03f seconds in:
42
+ %{separator}
43
+ %{output}
44
+ %{separator}
45
+ eoh
46
+ WAIT_TIMEOUT = ENV.key?('BAF_TEST_TIMEOUT') ?
47
+ ENV['BAF_TEST_TIMEOUT'].to_i :
48
+ 2
49
+
50
+ WORKING_DIR = 'tmp/uat'.freeze
51
+
52
+ class << self
53
+ def build_regexp pattern, options = ''
54
+ Regexp.new(pattern, options.each_char.inject(0) do |m, e|
55
+ m | case e
56
+ when ?i then Regexp::IGNORECASE
57
+ when ?m then Regexp::MULTILINE
58
+ when ?x then Regexp::EXTENDED
59
+ end
60
+ end)
61
+ end
62
+
63
+ def exercise_scenario dir: WORKING_DIR
64
+ FileUtils.remove_entry_secure dir, true
65
+ FileUtils.mkdir_p dir
66
+ Dir.chdir dir do
67
+ yield
68
+ end
69
+ end
70
+
71
+ def expect_ex process, exit_status
72
+ return if process.exit_status == exit_status
73
+
74
+ fail ExitStatusMismatch, EXIT_STATUS_MISMATCH_FMT % {
75
+ expected: exit_status,
76
+ actual: process.exit_status,
77
+ separator: OUTPUT_SEPARATOR,
78
+ output: process.output.chomp
79
+ }
80
+ end
81
+
82
+ def run command, wait: true, env_allow: [], timeout: nil
83
+ Process.new(
84
+ command,
85
+ env_allow: ENV_WHITELIST + env_allow,
86
+ timeout: timeout || Process::TIMEOUT
87
+ ).tap do |process|
88
+ process.start
89
+ wait process if wait
90
+ end
91
+ end
92
+
93
+ def wait process
94
+ process.wait do
95
+ process.stop
96
+ fail ExecutionTimeout, EXEC_TIMEOUT_ERROR_FMT % process.timeout
97
+ end
98
+ end
99
+
100
+ def unescape_step_arg str
101
+ str.gsub '\n', "\n"
102
+ end
103
+
104
+ def wait_until message: WAIT_MESSAGE_FMT, timeout: WAIT_TIMEOUT
105
+ return if yield
106
+ deadline = Time.now + timeout
107
+ until Time.now >= deadline
108
+ return if yield
109
+ sleep 0.05
110
+ end
111
+ fail WaitError.new message % timeout, timeout
112
+ end
113
+
114
+ def wait_output pattern, stream:, times: 1, timeout: WAIT_TIMEOUT
115
+ results = nil
116
+ wait_until timeout: timeout do
117
+ case pattern
118
+ when Regexp then (results = stream.call.scan(pattern)).size >= times
119
+ when String then stream.call.include? pattern
120
+ end
121
+ end
122
+ results
123
+ rescue Baf::Testing::WaitError => e
124
+ fail Baf::Testing::WaitError.new(WAIT_OUTPUT_MESSAGE_FMT % {
125
+ pattern: pattern,
126
+ timeout: timeout,
127
+ separator: OUTPUT_SEPARATOR,
128
+ output: stream.call.chomp
129
+ }, timeout)
130
+ end
131
+
132
+ def write_file path, content
133
+ FileUtils.mkdir_p File.dirname path
134
+ IO.write path, content
135
+ end
136
+ end
137
+ end
138
+ end
metadata CHANGED
@@ -1,44 +1,117 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.1
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thibault Jouan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-04 00:00:00.000000000 Z
11
+ date: 2022-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: baf-testing
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: cucumber
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '3.2'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
41
- description: Basic Application Framework
40
+ version: '3.2'
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.11'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.11'
55
+ description: |
56
+ baf helps writing an user acceptance test suite with a dedicated library
57
+ and cucumber steps. It can run and wait for programs in a modified
58
+ environment, verify the exit status, the output streams and other side
59
+ effects. It also supports interactive programs and writing to their
60
+ standard input.
61
+
62
+ Then, it provides a DSL to write the CLI:
63
+
64
+ require 'baf/cli'
65
+
66
+ module MyProgram
67
+ class CLI < Baf::CLI
68
+ def setup
69
+ flag_version '0.1.2'.freeze
70
+
71
+ option :c, :config, 'config', 'specify config file' do |path|
72
+ @config_path = path
73
+ end
74
+ end
75
+
76
+ def run
77
+ usage! unless arguments.any?
78
+
79
+ puts 'arguments: %s' % arguments
80
+ puts 'config: %s' % @config_path if @config_path
81
+ end
82
+ end
83
+ end
84
+
85
+ MyProgram::CLI.run ARGV
86
+
87
+ Which behaves this way:
88
+
89
+ % ./my_program
90
+ Usage: my_program [options]
91
+
92
+ options:
93
+ -c, --config config specify config file
94
+
95
+ -h, --help print this message
96
+ -V, --version print version
97
+ zsh: exit 64 ./my_program
98
+
99
+ % ./my_program --wrong-arg
100
+ Usage: my_program [options]
101
+
102
+ options:
103
+ -c, --config config specify config file
104
+
105
+ -h, --help print this message
106
+ -V, --version print version
107
+ zsh: exit 64 ./my_program --wrong-arg
108
+
109
+ % ./my_program foo
110
+ arguments ["foo"]
111
+
112
+ % ./my_program -c some_file foo
113
+ arguments ["foo"]
114
+ config path some_file
42
115
  email: tj@a13.fr
43
116
  executables: []
44
117
  extensions: []
@@ -50,12 +123,14 @@ files:
50
123
  - lib/baf/flag.rb
51
124
  - lib/baf/option.rb
52
125
  - lib/baf/options_registrant.rb
126
+ - lib/baf/testing.rb
53
127
  - lib/baf/testing/cucumber.rb
54
128
  - lib/baf/testing/cucumber/steps/execution.rb
129
+ - lib/baf/testing/cucumber/steps/filesystem.rb
55
130
  - lib/baf/testing/cucumber/steps/input.rb
56
131
  - lib/baf/testing/cucumber/steps/output.rb
57
132
  - lib/baf/testing/cucumber/steps/output_wait.rb
58
- - lib/baf/version.rb
133
+ - lib/baf/testing/process.rb
59
134
  homepage: https://rubygems.org/gems/baf
60
135
  licenses:
61
136
  - BSD-3-Clause
@@ -75,8 +150,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
75
150
  - !ruby/object:Gem::Version
76
151
  version: '0'
77
152
  requirements: []
78
- rubygems_version: 3.1.4
153
+ rubygems_version: 3.3.14
79
154
  signing_key:
80
155
  specification_version: 4
81
- summary: Basic Application Framework
156
+ summary: Toolkit for testing and writing CLI programs
82
157
  test_files: []
data/lib/baf/version.rb DELETED
@@ -1,3 +0,0 @@
1
- module Baf
2
- VERSION = '0.14.1'.freeze
3
- end