rubeno 0.0.5 → 0.0.7

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: b8dedd5e87189068d03353586100b545cb3431a82964a3706c6c7682fff5d340
4
- data.tar.gz: 736b7c4dac0518bbfdbe9f19bbbecaf5dcfad19be11ee2a2a680cf7f2c02f19e
3
+ metadata.gz: 8a51af887649a33c2f76c351bcb25d722eb4992ea180c0fdcda59bc722846409
4
+ data.tar.gz: 362ffd9a2da778891d56ed84c533eb0514780be37ff63b1509e781ada8559358
5
5
  SHA512:
6
- metadata.gz: 8bd1796520d9f8ceb13778f48d97de8e9ce1d69b74a4ef19fb505a36bd1345b2cf4413e627abd38a65fc64699a2eea3d36c473227248eb79bb46628b086e5f1a
7
- data.tar.gz: fb8657b555b4f02931c9e760a4789b929040f026f077ead673cb9842bfee88747bda1a2336665d4c7119031a0a109a8c83a0010553b61aa15d83f7ff1f0e07b1
6
+ metadata.gz: db7dcc13aa15c2c58c526ecff22c0a11f1a2cf00e4b246ebee1315996036653b65f92da156e224967649645aceeb59da4b18b4f8cc428c43ee93062ea884f6de
7
+ data.tar.gz: a94bf9b5273436388bc478714757245c7afd74a83ddba4d08554d3b0ac9a0dd34f553a4115cdb6aa2a4fb70285d77ebcc1fab20e5286e7f63c1b5f901541012b
data/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Rubeno
2
+
3
+ The Ruby implementation of Testeranto.
4
+
5
+ ## Deployment to rubygems
6
+ 1) update the version in rubeno.gemspec
7
+ 2) `gem build rubeno.gemspec`
8
+
9
+ ## Overview
10
+
11
+ Rubeno is a Ruby implementation of the Testeranto BDD testing framework. It follows the same patterns as the other language implementations (TypeScript, Python, Go) to provide a consistent testing experience across multiple programming languages.
12
+
13
+ ## Structure
14
+
15
+ The implementation consists of:
16
+
17
+ 1. **Base Classes**: `BaseSuite`, `BaseGiven`, `BaseWhen`, `BaseThen` - Core BDD components
18
+ 2. **Main Class**: `Rubeno` - Orchestrates test execution
19
+ 3. **Test Adapter**: `SimpleTestAdapter` - Default adapter implementation
20
+ 4. **Process Manager**: `PM_Ruby` - Handles communication
21
+ 5. **Types**: Type definitions for the framework
22
+
23
+ ## Usage
24
+
25
+ ### Basic Example
26
+
27
+ ```ruby
28
+ require 'rubeno'
29
+
30
+ # Define test implementation
31
+ test_implementation = Rubeno::ITestImplementation.new(
32
+ suites: { 'Default' => ->(name, givens) { ... } },
33
+ givens: { 'basic' => ->(initial_values) { ... } },
34
+ whens: { 'press' => ->(button) { ->(store) { ... } } },
35
+ thens: { 'displayIs' => ->(expected) { ->(store) { ... } } }
36
+ )
37
+
38
+ # Define test specification
39
+ test_specification = ->(suites, givens, whens, thens) do
40
+ [
41
+ suites.Default('Test Suite', {
42
+ 'test1' => givens.basic([], [whens.press('1')], [thens.displayIs('1')], nil)
43
+ })
44
+ ]
45
+ end
46
+
47
+ # Create test instance
48
+ test_instance = Rubeno.Rubeno(
49
+ nil,
50
+ test_specification,
51
+ test_implementation,
52
+ Rubeno::SimpleTestAdapter.new,
53
+ Rubeno::ITTestResourceRequest.new(ports: 1)
54
+ )
55
+
56
+ # Set as default and run
57
+ Rubeno.set_default_instance(test_instance)
58
+ Rubeno.main
59
+ ```
60
+
61
+ ### Running Tests
62
+
63
+ To run tests with Rubeno:
64
+
65
+ ```bash
66
+ ruby example/Calculator-test.rb '{"name":"test","fs":".","ports":[]}'
67
+ ```
68
+
69
+ ## Integration with Testeranto
70
+
71
+ Rubeno follows the same patterns as other Testeranto implementations:
72
+
73
+ 1. **Test Resource Configuration**: Passed as a JSON string argument
74
+ 2. **Results Output**: Writes to `testeranto/reports/allTests/example/ruby.Calculator.test.ts.json`
75
+ 3. **WebSocket Communication**: Supports communication via WebSocket (when configured)
76
+ 4. **Artifact Generation**: Supports test artifacts and reporting
77
+
78
+ ## Docker Support
79
+
80
+ Rubeno includes a Dockerfile for running tests in containers:
81
+
82
+ ```dockerfile
83
+ FROM ruby:3.2-alpine
84
+ WORKDIR /workspace
85
+ # ... (see testeranto/runtimes/ruby/ruby.Dockerfile)
86
+ ```
87
+
88
+ ## Extending
89
+
90
+ To create custom adapters, implement the `ITestAdapter` module:
91
+
92
+ ```ruby
93
+ class CustomAdapter
94
+ include Rubeno::ITestAdapter
95
+
96
+ def before_all(input_val, tr, pm)
97
+ # Custom setup
98
+ input_val
99
+ end
100
+
101
+ # ... implement other methods
102
+ end
103
+ ```
104
+
105
+ ## Dependencies
106
+
107
+ - Ruby 2.7+ (for pattern matching and other modern features)
108
+ - JSON (standard library)
109
+
110
+ ## Future Enhancements
111
+
112
+ 1. **WebSocket Support**: Full WebSocket communication for real-time test reporting
113
+ 2. **Advanced Adapters**: More sophisticated adapter implementations
114
+ 3. **Plugin System**: Extensible plugin architecture
115
+ 4. **Performance Optimizations**: Improved test execution performance
116
+
117
+ ## See Also
118
+
119
+ - [Tiposkripto](../tiposkripto/) - TypeScript/JavaScript implementation
120
+ - [Pitono](../pitono/) - Python implementation
121
+ - [Golingvu](../golingvu/) - Go implementation
122
+
data/bin/rubeno CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  require 'rubeno'
4
4
 
5
- puts "hello rubeno"
5
+ Rubeno.main
data/lib/base_given.rb ADDED
@@ -0,0 +1,130 @@
1
+ module Rubeno
2
+ class BaseGiven
3
+ attr_accessor :features, :whens, :thens, :error, :fail, :store, :recommended_fs_path,
4
+ :given_cb, :initial_values, :key, :failed, :artifacts, :status, :fails
5
+
6
+ def initialize(features, whens, thens, given_cb, initial_values)
7
+ @features = features
8
+ @whens = whens
9
+ @thens = thens
10
+ @given_cb = given_cb
11
+ @initial_values = initial_values
12
+ @artifacts = []
13
+ @fails = 0
14
+ end
15
+
16
+ def add_artifact(path)
17
+ normalized_path = path.gsub('\\', '/')
18
+ @artifacts << normalized_path
19
+ end
20
+
21
+ def before_all(store)
22
+ store
23
+ end
24
+
25
+ def to_obj
26
+ {
27
+ key: @key,
28
+ whens: (@whens || []).map { |w| w.respond_to?(:to_obj) ? w.to_obj : {} },
29
+ thens: (@thens || []).map { |t| t.respond_to?(:to_obj) ? t.to_obj : {} },
30
+ error: @error ? [@error, @error.backtrace] : nil,
31
+ failed: @failed,
32
+ features: @features || [],
33
+ artifacts: @artifacts,
34
+ status: @status
35
+ }
36
+ end
37
+
38
+ def given_that(subject, test_resource_configuration, artifactory, given_cb, initial_values, pm)
39
+ raise NotImplementedError, "given_that must be implemented by subclasses"
40
+ end
41
+
42
+ def after_each(store, key, artifactory, pm)
43
+ store
44
+ end
45
+
46
+ def give(subject, key, test_resource_configuration, tester, artifactory, t_log, pm, suite_ndx)
47
+ @key = key
48
+ @fails = 0
49
+ @failed = false
50
+ @error = nil
51
+
52
+ given_artifactory = ->(f_path, value) do
53
+ artifactory.call("given-#{key}/#{f_path}", value)
54
+ end
55
+
56
+ begin
57
+ # Call the given callback to get initial subject
58
+ initial_subject = @given_cb.call(@initial_values)
59
+ @store = given_that(
60
+ initial_subject,
61
+ test_resource_configuration,
62
+ given_artifactory,
63
+ @given_cb,
64
+ @initial_values,
65
+ pm
66
+ )
67
+ @status = true
68
+ rescue => e
69
+ @status = false
70
+ @failed = true
71
+ @fails += 1
72
+ @error = e
73
+ return @store
74
+ end
75
+
76
+ begin
77
+ # Process whens
78
+ @whens.each_with_index do |when_step, when_ndx|
79
+ begin
80
+ @store = when_step.test(
81
+ @store,
82
+ test_resource_configuration,
83
+ t_log,
84
+ pm,
85
+ "suite-#{suite_ndx}/given-#{key}/when/#{when_ndx}"
86
+ )
87
+ rescue => e
88
+ @failed = true
89
+ @fails += 1
90
+ @error = e
91
+ end
92
+ end
93
+
94
+ # Process thens
95
+ @thens.each_with_index do |then_step, then_ndx|
96
+ begin
97
+ result = then_step.test(
98
+ @store,
99
+ test_resource_configuration,
100
+ t_log,
101
+ pm,
102
+ "suite-#{suite_ndx}/given-#{key}/then-#{then_ndx}"
103
+ )
104
+ unless tester.call(result)
105
+ @failed = true
106
+ @fails += 1
107
+ end
108
+ rescue => e
109
+ @failed = true
110
+ @fails += 1
111
+ @error = e
112
+ end
113
+ end
114
+ rescue => e
115
+ @error = e
116
+ @failed = true
117
+ @fails += 1
118
+ ensure
119
+ begin
120
+ after_each(@store, @key, given_artifactory, pm)
121
+ rescue => e
122
+ @failed = true
123
+ @fails += 1
124
+ end
125
+ end
126
+
127
+ @store
128
+ end
129
+ end
130
+ end
data/lib/base_suite.rb ADDED
@@ -0,0 +1,94 @@
1
+ module Rubeno
2
+ class BaseSuite
3
+ attr_accessor :name, :givens, :store, :test_resource_configuration, :index, :failed, :fails, :artifacts
4
+
5
+ def initialize(name, givens = {})
6
+ @name = name
7
+ @givens = givens
8
+ @artifacts = []
9
+ @failed = false
10
+ @fails = 0
11
+ end
12
+
13
+ def add_artifact(path)
14
+ normalized_path = path.gsub('\\', '/')
15
+ @artifacts << normalized_path
16
+ end
17
+
18
+ def features
19
+ features = []
20
+ seen = {}
21
+ @givens.each_value do |given|
22
+ given.features.each do |feature|
23
+ unless seen[feature]
24
+ features << feature
25
+ seen[feature] = true
26
+ end
27
+ end
28
+ end
29
+ features
30
+ end
31
+
32
+ def to_obj
33
+ {
34
+ name: @name,
35
+ givens: @givens.values.map(&:to_obj),
36
+ fails: @fails,
37
+ failed: @failed,
38
+ features: features,
39
+ artifacts: @artifacts
40
+ }
41
+ end
42
+
43
+ def setup(s, artifactory, tr, pm)
44
+ s
45
+ end
46
+
47
+ def assert_that(t)
48
+ !!t
49
+ end
50
+
51
+ def after_all(store, artifactory, pm)
52
+ store
53
+ end
54
+
55
+ def run(input_val, test_resource_configuration, artifactory, t_log, pm)
56
+ @test_resource_configuration = test_resource_configuration
57
+
58
+ subject = setup(input_val, artifactory, test_resource_configuration, pm)
59
+
60
+ @fails = 0
61
+ @failed = false
62
+
63
+ @givens.each do |g_key, g|
64
+ begin
65
+ @store = g.give(
66
+ subject,
67
+ g_key,
68
+ test_resource_configuration,
69
+ method(:assert_that),
70
+ artifactory,
71
+ t_log,
72
+ pm,
73
+ @index
74
+ )
75
+ @fails += g.fails if g.fails && g.fails > 0
76
+ rescue => e
77
+ @failed = true
78
+ @fails += 1
79
+ puts "Error in given #{g_key}: #{e.message}"
80
+ end
81
+ end
82
+
83
+ @failed = true if @fails > 0
84
+
85
+ begin
86
+ after_all(@store, artifactory, pm)
87
+ rescue => e
88
+ puts "Error in after_all: #{e.message}"
89
+ end
90
+
91
+ self
92
+ end
93
+ end
94
+ end
data/lib/base_then.rb ADDED
@@ -0,0 +1,43 @@
1
+ module Rubeno
2
+ class BaseThen
3
+ attr_accessor :name, :then_cb, :error, :artifacts, :status
4
+
5
+ def initialize(name, then_cb)
6
+ @name = name
7
+ @then_cb = then_cb
8
+ @error = false
9
+ @artifacts = []
10
+ end
11
+
12
+ def add_artifact(path)
13
+ normalized_path = path.gsub('\\', '/')
14
+ @artifacts << normalized_path
15
+ end
16
+
17
+ def but_then(store, then_cb, test_resource_configuration, pm)
18
+ raise NotImplementedError, "but_then must be implemented by subclasses"
19
+ end
20
+
21
+ def to_obj
22
+ {
23
+ name: @name,
24
+ error: @error,
25
+ artifacts: @artifacts,
26
+ status: @status
27
+ }
28
+ end
29
+
30
+ def test(store, test_resource_configuration, t_log, pm, filepath)
31
+ begin
32
+ # Call the then_cb with the store to get a boolean result
33
+ result = @then_cb.call(store)
34
+ @status = true
35
+ result
36
+ rescue => e
37
+ @status = false
38
+ @error = true
39
+ raise e
40
+ end
41
+ end
42
+ end
43
+ end
data/lib/base_when.rb ADDED
@@ -0,0 +1,46 @@
1
+ module Rubeno
2
+ class BaseWhen
3
+ attr_accessor :name, :when_cb, :error, :artifacts, :status
4
+
5
+ def initialize(name, when_cb)
6
+ @name = name
7
+ @when_cb = when_cb
8
+ @artifacts = []
9
+ end
10
+
11
+ def add_artifact(path)
12
+ normalized_path = path.gsub('\\', '/')
13
+ @artifacts << normalized_path
14
+ end
15
+
16
+ def and_when(store, when_cb, test_resource_configuration, pm)
17
+ raise NotImplementedError, "and_when must be implemented by subclasses"
18
+ end
19
+
20
+ def to_obj
21
+ error_str = nil
22
+ if @error
23
+ error_str = "#{@error.class}: #{@error.message}"
24
+ end
25
+ {
26
+ name: @name,
27
+ status: @status,
28
+ error: error_str,
29
+ artifacts: @artifacts
30
+ }
31
+ end
32
+
33
+ def test(store, test_resource_configuration, t_log, pm, filepath)
34
+ begin
35
+ # Call the when_cb with the store
36
+ result = @when_cb.call(store)
37
+ @status = true
38
+ result
39
+ rescue => e
40
+ @status = false
41
+ @error = e
42
+ raise e
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/pm/ruby.rb ADDED
@@ -0,0 +1,156 @@
1
+ module Rubeno
2
+ class PM_Ruby
3
+ def initialize(t, websocket_port)
4
+ @test_resource_configuration = t
5
+ @websocket_port = websocket_port
6
+ @connected = false
7
+ end
8
+
9
+ def start
10
+ raise "DEPRECATED"
11
+ end
12
+
13
+ def send(command, *args)
14
+ # For now, return default values to allow tests to run
15
+ case command
16
+ when "pages"
17
+ []
18
+ when "newPage"
19
+ "mock-page"
20
+ when "page"
21
+ "mock-page"
22
+ when "existsSync"
23
+ false
24
+ when "writeFileSync"
25
+ true
26
+ when "createWriteStream"
27
+ "mock-stream"
28
+ when "write"
29
+ true
30
+ when "end"
31
+ true
32
+ when "customclose"
33
+ nil
34
+ else
35
+ nil
36
+ end
37
+ end
38
+
39
+ def pages
40
+ send("pages")
41
+ end
42
+
43
+ def wait_for_selector(p, s)
44
+ send("waitForSelector", p, s)
45
+ end
46
+
47
+ def close_page(p)
48
+ send("closePage", p)
49
+ end
50
+
51
+ def goto(page, url)
52
+ send("goto", page, url)
53
+ end
54
+
55
+ def new_page
56
+ send("newPage")
57
+ end
58
+
59
+ def call(selector, page)
60
+ send("$", selector, page)
61
+ end
62
+
63
+ def is_disabled(selector)
64
+ send("isDisabled", selector)
65
+ end
66
+
67
+ def get_attribute(selector, attribute, p)
68
+ send("getAttribute", selector, attribute, p)
69
+ end
70
+
71
+ def get_inner_html(selector, p)
72
+ send("getInnerHtml", selector, p)
73
+ end
74
+
75
+ def focus_on(selector)
76
+ send("focusOn", selector)
77
+ end
78
+
79
+ def type_into(selector)
80
+ send("typeInto", selector)
81
+ end
82
+
83
+ def page
84
+ send("page")
85
+ end
86
+
87
+ def click(selector)
88
+ send("click", selector)
89
+ end
90
+
91
+ def screencast(opts, page)
92
+ adjusted_opts = opts.dup
93
+ if adjusted_opts['path']
94
+ adjusted_opts['path'] = "#{@test_resource_configuration.fs}/#{opts['path']}"
95
+ end
96
+ send("screencast", adjusted_opts, page, @test_resource_configuration.name)
97
+ end
98
+
99
+ def screencast_stop(p)
100
+ send("screencastStop", p)
101
+ end
102
+
103
+ def custom_screenshot(x)
104
+ opts = x[0]
105
+ page = x[1] if x.length > 1
106
+
107
+ adjusted_opts = opts.dup
108
+ if adjusted_opts['path']
109
+ adjusted_opts['path'] = "#{@test_resource_configuration.fs}/#{opts['path']}"
110
+ end
111
+
112
+ if page
113
+ send("customScreenShot", adjusted_opts, @test_resource_configuration.name, page)
114
+ else
115
+ send("customScreenShot", adjusted_opts, @test_resource_configuration.name)
116
+ end
117
+ end
118
+
119
+ def exists_sync(dest_folder)
120
+ path = "#{@test_resource_configuration.fs}/#{dest_folder}"
121
+ send("existsSync", path)
122
+ end
123
+
124
+ def mkdir_sync
125
+ path = "#{@test_resource_configuration.fs}/"
126
+ send("mkdirSync", path)
127
+ end
128
+
129
+ def write(uid, contents)
130
+ send("write", uid, contents)
131
+ end
132
+
133
+ def write_file_sync(filepath, contents)
134
+ full_path = "#{@test_resource_configuration.fs}/#{filepath}"
135
+ begin
136
+ result = send("writeFileSync", full_path, contents, @test_resource_configuration.name)
137
+ result
138
+ rescue => e
139
+ raise e
140
+ end
141
+ end
142
+
143
+ def create_write_stream(filepath)
144
+ full_path = "#{@test_resource_configuration.fs}/#{filepath}"
145
+ send("createWriteStream", full_path, @test_resource_configuration.name)
146
+ end
147
+
148
+ def end(uid)
149
+ send("end", uid)
150
+ end
151
+
152
+ def custom_close
153
+ send("customclose", @test_resource_configuration.fs, @test_resource_configuration.name)
154
+ end
155
+ end
156
+ end
data/lib/rubeno.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  require 'json'
2
- require_relative 'base_suite'
3
- require_relative 'base_given'
4
- require_relative 'base_when'
5
- require_relative 'base_then'
6
- require_relative 'simple_adapter'
7
- require_relative 'pm/ruby'
8
- require_relative 'types'
2
+ require 'rubeno/base_suite'
3
+ require 'rubeno/base_given'
4
+ require 'rubeno/base_when'
5
+ require 'rubeno/base_then'
6
+ require 'rubeno/simple_adapter'
7
+ require 'rubeno/pm/ruby'
8
+ require 'rubeno/types'
9
9
 
10
10
  module Rubeno
11
11
  class Rubeno
@@ -0,0 +1,43 @@
1
+ require_relative 'types'
2
+
3
+ module Rubeno
4
+ class SimpleTestAdapter
5
+ include ITestAdapter
6
+
7
+ def before_all(input_val, tr, pm)
8
+ input_val
9
+ end
10
+
11
+ def after_all(store, pm)
12
+ store
13
+ end
14
+
15
+ def before_each(subject, initializer, test_resource, initial_values, pm)
16
+ subject
17
+ end
18
+
19
+ def after_each(store, key, pm)
20
+ store
21
+ end
22
+
23
+ def and_when(store, when_cb, test_resource, pm)
24
+ if when_cb.respond_to?(:call)
25
+ when_cb.call(store)
26
+ else
27
+ store
28
+ end
29
+ end
30
+
31
+ def but_then(store, then_cb, test_resource, pm)
32
+ if then_cb.respond_to?(:call)
33
+ then_cb.call(store)
34
+ else
35
+ store
36
+ end
37
+ end
38
+
39
+ def assert_this(t)
40
+ !!t
41
+ end
42
+ end
43
+ end
data/lib/types.rb ADDED
@@ -0,0 +1,85 @@
1
+ module Rubeno
2
+ # Type definitions for Rubeno
3
+
4
+ # Test resource configuration
5
+ class ITTestResourceConfiguration
6
+ attr_accessor :name, :fs, :ports, :browser_ws_endpoint, :timeout, :retries, :environment
7
+
8
+ def initialize(name:, fs:, ports:, browser_ws_endpoint: nil, timeout: nil, retries: nil, environment: {})
9
+ @name = name
10
+ @fs = fs
11
+ @ports = ports
12
+ @browser_ws_endpoint = browser_ws_endpoint
13
+ @timeout = timeout
14
+ @retries = retries
15
+ @environment = environment
16
+ end
17
+ end
18
+
19
+ # Test adapter interface
20
+ module ITestAdapter
21
+ def before_all(input_val, tr, pm)
22
+ input_val
23
+ end
24
+
25
+ def after_all(store, pm)
26
+ store
27
+ end
28
+
29
+ def before_each(subject, initializer, test_resource, initial_values, pm)
30
+ subject
31
+ end
32
+
33
+ def after_each(store, key, pm)
34
+ store
35
+ end
36
+
37
+ def and_when(store, when_cb, test_resource, pm)
38
+ store
39
+ end
40
+
41
+ def but_then(store, then_cb, test_resource, pm)
42
+ store
43
+ end
44
+
45
+ def assert_this(t)
46
+ !!t
47
+ end
48
+ end
49
+
50
+ # Test specification function type
51
+ ITestSpecification = Proc
52
+
53
+ # Test implementation structure
54
+ class ITestImplementation
55
+ attr_accessor :suites, :givens, :whens, :thens
56
+
57
+ def initialize(suites:, givens:, whens:, thens:)
58
+ @suites = suites
59
+ @givens = givens
60
+ @whens = whens
61
+ @thens = thens
62
+ end
63
+ end
64
+
65
+ # Test resource request
66
+ class ITTestResourceRequest
67
+ attr_accessor :ports
68
+
69
+ def initialize(ports: 0)
70
+ @ports = ports
71
+ end
72
+ end
73
+
74
+ # Final results
75
+ class IFinalResults
76
+ attr_accessor :failed, :fails, :artifacts, :features
77
+
78
+ def initialize(failed:, fails:, artifacts:, features:)
79
+ @failed = failed
80
+ @fails = fails
81
+ @artifacts = artifacts
82
+ @features = features
83
+ end
84
+ end
85
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubeno
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Wong
@@ -17,9 +17,17 @@ executables:
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - README.md
20
21
  - Rakefile
21
22
  - bin/rubeno
23
+ - lib/base_given.rb
24
+ - lib/base_suite.rb
25
+ - lib/base_then.rb
26
+ - lib/base_when.rb
27
+ - lib/pm/ruby.rb
22
28
  - lib/rubeno.rb
29
+ - lib/simple_adapter.rb
30
+ - lib/types.rb
23
31
  homepage: http://rubygems.org/gems/rubeno
24
32
  licenses: []
25
33
  metadata: {}