kookaburra 1.3.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.markdown +52 -59
- data/lib/kookaburra.rb +11 -17
- data/lib/kookaburra/api_client.rb +214 -0
- data/lib/kookaburra/api_driver.rb +47 -196
- data/lib/kookaburra/configuration.rb +4 -4
- data/lib/kookaburra/mental_model.rb +16 -4
- data/lib/kookaburra/test_helpers.rb +15 -37
- data/lib/kookaburra/version.rb +1 -1
- data/spec/integration/test_a_rack_application_spec.rb +34 -356
- data/spec/kookaburra/{api_driver_spec.rb → api_client_spec.rb} +14 -14
- data/spec/kookaburra/configuration_spec.rb +6 -6
- data/spec/kookaburra/mental_model_spec.rb +13 -1
- data/spec/kookaburra/test_helpers_spec.rb +5 -44
- data/spec/kookaburra_spec.rb +7 -7
- data/spec/support/json_api_app_and_kookaburra_drivers.rb +372 -0
- metadata +41 -42
- data/lib/kookaburra/given_driver.rb +0 -65
- data/lib/kookaburra/mental_model_matcher.rb +0 -138
- data/spec/kookaburra/mental_model_matcher_spec.rb +0 -237
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kookaburra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Wilger
|
@@ -10,188 +10,188 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2014-
|
13
|
+
date: 2014-08-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- -
|
26
|
+
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '0'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: bundler
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- - ~>
|
33
|
+
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
35
|
version: '1.3'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
|
-
- - ~>
|
40
|
+
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '1.3'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: rake
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- -
|
47
|
+
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '0'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- -
|
54
|
+
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: rspec
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
|
-
- -
|
61
|
+
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: '0'
|
64
64
|
type: :development
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
|
-
- -
|
68
|
+
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
70
|
version: '0'
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: capybara
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ">="
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
78
|
type: :development
|
79
79
|
prerelease: false
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
81
81
|
requirements:
|
82
|
-
- -
|
82
|
+
- - ">="
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: '0'
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: capybara-webkit
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
|
-
- -
|
89
|
+
- - ">="
|
90
90
|
- !ruby/object:Gem::Version
|
91
91
|
version: '0'
|
92
92
|
type: :development
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
|
-
- -
|
96
|
+
- - ">="
|
97
97
|
- !ruby/object:Gem::Version
|
98
98
|
version: '0'
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
100
|
name: reek
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
102
102
|
requirements:
|
103
|
-
- -
|
103
|
+
- - ">="
|
104
104
|
- !ruby/object:Gem::Version
|
105
105
|
version: '0'
|
106
106
|
type: :development
|
107
107
|
prerelease: false
|
108
108
|
version_requirements: !ruby/object:Gem::Requirement
|
109
109
|
requirements:
|
110
|
-
- -
|
110
|
+
- - ">="
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: '0'
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: yard
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
116
116
|
requirements:
|
117
|
-
- -
|
117
|
+
- - ">="
|
118
118
|
- !ruby/object:Gem::Version
|
119
119
|
version: '0'
|
120
120
|
type: :development
|
121
121
|
prerelease: false
|
122
122
|
version_requirements: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
|
-
- -
|
124
|
+
- - ">="
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: '0'
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: kramdown
|
129
129
|
requirement: !ruby/object:Gem::Requirement
|
130
130
|
requirements:
|
131
|
-
- -
|
131
|
+
- - ">="
|
132
132
|
- !ruby/object:Gem::Version
|
133
133
|
version: '0'
|
134
134
|
type: :development
|
135
135
|
prerelease: false
|
136
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
137
|
requirements:
|
138
|
-
- -
|
138
|
+
- - ">="
|
139
139
|
- !ruby/object:Gem::Version
|
140
140
|
version: '0'
|
141
141
|
- !ruby/object:Gem::Dependency
|
142
142
|
name: sinatra
|
143
143
|
requirement: !ruby/object:Gem::Requirement
|
144
144
|
requirements:
|
145
|
-
- -
|
145
|
+
- - ">="
|
146
146
|
- !ruby/object:Gem::Version
|
147
147
|
version: '0'
|
148
148
|
type: :development
|
149
149
|
prerelease: false
|
150
150
|
version_requirements: !ruby/object:Gem::Requirement
|
151
151
|
requirements:
|
152
|
-
- -
|
152
|
+
- - ">="
|
153
153
|
- !ruby/object:Gem::Version
|
154
154
|
version: '0'
|
155
155
|
- !ruby/object:Gem::Dependency
|
156
156
|
name: uuid
|
157
157
|
requirement: !ruby/object:Gem::Requirement
|
158
158
|
requirements:
|
159
|
-
- -
|
159
|
+
- - ">="
|
160
160
|
- !ruby/object:Gem::Version
|
161
161
|
version: '0'
|
162
162
|
type: :development
|
163
163
|
prerelease: false
|
164
164
|
version_requirements: !ruby/object:Gem::Requirement
|
165
165
|
requirements:
|
166
|
-
- -
|
166
|
+
- - ">="
|
167
167
|
- !ruby/object:Gem::Version
|
168
168
|
version: '0'
|
169
169
|
- !ruby/object:Gem::Dependency
|
170
170
|
name: find_a_port
|
171
171
|
requirement: !ruby/object:Gem::Requirement
|
172
172
|
requirements:
|
173
|
-
- -
|
173
|
+
- - ">="
|
174
174
|
- !ruby/object:Gem::Version
|
175
175
|
version: '0'
|
176
176
|
type: :development
|
177
177
|
prerelease: false
|
178
178
|
version_requirements: !ruby/object:Gem::Requirement
|
179
179
|
requirements:
|
180
|
-
- -
|
180
|
+
- - ">="
|
181
181
|
- !ruby/object:Gem::Version
|
182
182
|
version: '0'
|
183
183
|
- !ruby/object:Gem::Dependency
|
184
184
|
name: json
|
185
185
|
requirement: !ruby/object:Gem::Requirement
|
186
186
|
requirements:
|
187
|
-
- -
|
187
|
+
- - ">="
|
188
188
|
- !ruby/object:Gem::Version
|
189
189
|
version: '0'
|
190
190
|
type: :development
|
191
191
|
prerelease: false
|
192
192
|
version_requirements: !ruby/object:Gem::Requirement
|
193
193
|
requirements:
|
194
|
-
- -
|
194
|
+
- - ">="
|
195
195
|
- !ruby/object:Gem::Version
|
196
196
|
version: '0'
|
197
197
|
description: Cucumber + Capybara = Kookaburra? It made sense at the time.
|
@@ -201,11 +201,11 @@ executables: []
|
|
201
201
|
extensions: []
|
202
202
|
extra_rdoc_files: []
|
203
203
|
files:
|
204
|
-
- .document
|
205
|
-
- .gitignore
|
206
|
-
- .rspec
|
207
|
-
- .travis.yml
|
208
|
-
- .yardopts
|
204
|
+
- ".document"
|
205
|
+
- ".gitignore"
|
206
|
+
- ".rspec"
|
207
|
+
- ".travis.yml"
|
208
|
+
- ".yardopts"
|
209
209
|
- Gemfile
|
210
210
|
- Gemfile.lock
|
211
211
|
- LICENSE.txt
|
@@ -215,14 +215,13 @@ files:
|
|
215
215
|
- lib/core_ext/object/to_param.rb
|
216
216
|
- lib/core_ext/object/to_query.rb
|
217
217
|
- lib/kookaburra.rb
|
218
|
+
- lib/kookaburra/api_client.rb
|
218
219
|
- lib/kookaburra/api_driver.rb
|
219
220
|
- lib/kookaburra/assertion.rb
|
220
221
|
- lib/kookaburra/configuration.rb
|
221
222
|
- lib/kookaburra/dependency_accessor.rb
|
222
223
|
- lib/kookaburra/exceptions.rb
|
223
|
-
- lib/kookaburra/given_driver.rb
|
224
224
|
- lib/kookaburra/mental_model.rb
|
225
|
-
- lib/kookaburra/mental_model_matcher.rb
|
226
225
|
- lib/kookaburra/rack_app_server.rb
|
227
226
|
- lib/kookaburra/test_helpers.rb
|
228
227
|
- lib/kookaburra/ui_driver.rb
|
@@ -232,9 +231,8 @@ files:
|
|
232
231
|
- lib/kookaburra/ui_driver/ui_component/address_bar.rb
|
233
232
|
- lib/kookaburra/version.rb
|
234
233
|
- spec/integration/test_a_rack_application_spec.rb
|
235
|
-
- spec/kookaburra/
|
234
|
+
- spec/kookaburra/api_client_spec.rb
|
236
235
|
- spec/kookaburra/configuration_spec.rb
|
237
|
-
- spec/kookaburra/mental_model_matcher_spec.rb
|
238
236
|
- spec/kookaburra/mental_model_spec.rb
|
239
237
|
- spec/kookaburra/test_helpers_spec.rb
|
240
238
|
- spec/kookaburra/ui_driver/scoped_browser_spec.rb
|
@@ -242,6 +240,7 @@ files:
|
|
242
240
|
- spec/kookaburra/ui_driver/ui_component_spec.rb
|
243
241
|
- spec/kookaburra/ui_driver_spec.rb
|
244
242
|
- spec/kookaburra_spec.rb
|
243
|
+
- spec/support/json_api_app_and_kookaburra_drivers.rb
|
245
244
|
- spec/support/shared_examples/it_can_have_ui_components.rb
|
246
245
|
- spec/support/shared_examples/it_can_make_assertions.rb
|
247
246
|
- spec/support/shared_examples/it_has_a_dependency_accessor.rb
|
@@ -255,25 +254,24 @@ require_paths:
|
|
255
254
|
- lib
|
256
255
|
required_ruby_version: !ruby/object:Gem::Requirement
|
257
256
|
requirements:
|
258
|
-
- -
|
257
|
+
- - ">="
|
259
258
|
- !ruby/object:Gem::Version
|
260
259
|
version: '0'
|
261
260
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
262
261
|
requirements:
|
263
|
-
- -
|
262
|
+
- - ">="
|
264
263
|
- !ruby/object:Gem::Version
|
265
264
|
version: '0'
|
266
265
|
requirements: []
|
267
266
|
rubyforge_project:
|
268
|
-
rubygems_version: 2.
|
267
|
+
rubygems_version: 2.2.2
|
269
268
|
signing_key:
|
270
269
|
specification_version: 4
|
271
270
|
summary: Window Driver pattern for acceptance tests
|
272
271
|
test_files:
|
273
272
|
- spec/integration/test_a_rack_application_spec.rb
|
274
|
-
- spec/kookaburra/
|
273
|
+
- spec/kookaburra/api_client_spec.rb
|
275
274
|
- spec/kookaburra/configuration_spec.rb
|
276
|
-
- spec/kookaburra/mental_model_matcher_spec.rb
|
277
275
|
- spec/kookaburra/mental_model_spec.rb
|
278
276
|
- spec/kookaburra/test_helpers_spec.rb
|
279
277
|
- spec/kookaburra/ui_driver/scoped_browser_spec.rb
|
@@ -281,6 +279,7 @@ test_files:
|
|
281
279
|
- spec/kookaburra/ui_driver/ui_component_spec.rb
|
282
280
|
- spec/kookaburra/ui_driver_spec.rb
|
283
281
|
- spec/kookaburra_spec.rb
|
282
|
+
- spec/support/json_api_app_and_kookaburra_drivers.rb
|
284
283
|
- spec/support/shared_examples/it_can_have_ui_components.rb
|
285
284
|
- spec/support/shared_examples/it_can_make_assertions.rb
|
286
285
|
- spec/support/shared_examples/it_has_a_dependency_accessor.rb
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
|
3
|
-
class Kookaburra
|
4
|
-
# Your GivenDriver subclass is used to define your testing DSL for setting up
|
5
|
-
# test preconditions. Unlike {Kookaburra::APIDriver}, which is meant to be a
|
6
|
-
# simple mapping to your application's API, a method in the GivenDriver may be
|
7
|
-
# comprised of several distinct API calls as well as access to Kookaburra's
|
8
|
-
# test data store via {#mental_model}.
|
9
|
-
#
|
10
|
-
# @abstract Subclass and implement your Given DSL.
|
11
|
-
#
|
12
|
-
# @example GivenDriver subclass
|
13
|
-
# module MyApp
|
14
|
-
# module Kookaburra
|
15
|
-
# class GivenDriver < ::Kookaburra::GivenDriver
|
16
|
-
# def api
|
17
|
-
# @api ||= APIDriver.new(configuration)
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# def a_widget(name, attributes = {})
|
21
|
-
# # Set up the data that will be passed to the API by merging any
|
22
|
-
# # passed attributes into the default data.
|
23
|
-
# data = {:name => 'Foo', :description => 'Bar baz'}.merge(attributes)
|
24
|
-
#
|
25
|
-
# # Call the API method and get the resulting response as Ruby data.
|
26
|
-
# result = api.create_widget(data)
|
27
|
-
#
|
28
|
-
# # Store the resulting widget data in the MentalModel object, so that
|
29
|
-
# # it can be referenced in other operations.
|
30
|
-
# mental_model.widgets[name] = result
|
31
|
-
# end
|
32
|
-
# end
|
33
|
-
# end
|
34
|
-
# end
|
35
|
-
class GivenDriver
|
36
|
-
extend Forwardable
|
37
|
-
|
38
|
-
# It is unlikely that you would call #initialize yourself; your GivenDriver
|
39
|
-
# object is instantiated for you by {Kookaburra#given}.
|
40
|
-
#
|
41
|
-
# @param [Kookaburra::Configuration] configuration
|
42
|
-
def initialize(configuration)
|
43
|
-
@configuration = configuration
|
44
|
-
end
|
45
|
-
|
46
|
-
protected
|
47
|
-
|
48
|
-
attr_reader :configuration
|
49
|
-
|
50
|
-
# Access to the shared {Kookaburra::MentalModel} instance
|
51
|
-
#
|
52
|
-
# @attribute [rw] mental_model
|
53
|
-
def_delegator :configuration, :mental_model
|
54
|
-
|
55
|
-
# Used to access your APIDriver in your own GivenDriver implementation
|
56
|
-
#
|
57
|
-
# @abstract
|
58
|
-
# @return [Kookaburra::APIDriver]
|
59
|
-
# @raise [Kookaburra::ConfigurationError] raised if you do not provide an
|
60
|
-
# implementation.
|
61
|
-
def api
|
62
|
-
raise ConfigurationError, "You must implement #api in your subclass."
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,138 +0,0 @@
|
|
1
|
-
require 'kookaburra/mental_model'
|
2
|
-
|
3
|
-
class Kookaburra
|
4
|
-
class MentalModel
|
5
|
-
# This is a custom matcher that matches the RSpec matcher API.
|
6
|
-
#
|
7
|
-
# @see Kookaburra::TestHelpers#match_mental_model_of
|
8
|
-
# @see Kookaburra::TestHelpers#assert_mental_model_of
|
9
|
-
class Matcher
|
10
|
-
def initialize(mental_model, collection_key)
|
11
|
-
@collection_key = collection_key
|
12
|
-
|
13
|
-
mental_model.send(collection_key).tap do |collection|
|
14
|
-
@expected = collection
|
15
|
-
@unexpected = collection.deleted
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Specifies that result should be limited to the given keys from the
|
20
|
-
# mental model.
|
21
|
-
#
|
22
|
-
# Useful if you are looking at a filtered result. That is, your mental
|
23
|
-
# model contains elements { A, B, C }, but you only expect to see element
|
24
|
-
# A.
|
25
|
-
#
|
26
|
-
# @param [Array] collection_keys The keys used in your mental model to
|
27
|
-
# reference the data
|
28
|
-
# @return [self]
|
29
|
-
def only(*collection_keys)
|
30
|
-
keepers = @expected.slice(*collection_keys)
|
31
|
-
tossers = @expected.except(*collection_keys)
|
32
|
-
|
33
|
-
@expected = keepers
|
34
|
-
@unexpected.merge! tossers
|
35
|
-
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
# Reads better than {#only} with no args
|
40
|
-
#
|
41
|
-
# @return [self]
|
42
|
-
def expecting_nothing
|
43
|
-
only
|
44
|
-
end
|
45
|
-
|
46
|
-
# The result contains everything that was expected to be found and nothing
|
47
|
-
# that was unexpected.
|
48
|
-
#
|
49
|
-
# (Part of the RSpec protocol for custom matchers.)
|
50
|
-
#
|
51
|
-
# @param [Array] actual This is the data observed that you are attempting
|
52
|
-
# to match against the mental model.
|
53
|
-
# @return Boolean
|
54
|
-
def matches?(actual)
|
55
|
-
@actual = actual
|
56
|
-
expected_items_found? && !unexpected_items_found?
|
57
|
-
end
|
58
|
-
|
59
|
-
# Message to be printed when observed reality does not conform to
|
60
|
-
# mental model.
|
61
|
-
#
|
62
|
-
# (Part of the RSpec protocol for custom matchers.)
|
63
|
-
#
|
64
|
-
# @return String
|
65
|
-
def failure_message_for_should
|
66
|
-
message = "expected #{@collection_key} to match the user's mental model, but:\n"
|
67
|
-
unless expected_items_found?
|
68
|
-
message += "expected to be present: #{pp_array(expected_items)}\n"
|
69
|
-
message += "the missing elements were: #{pp_array(expected_items_that_were_not_found)}\n"
|
70
|
-
end
|
71
|
-
if unexpected_items_found?
|
72
|
-
message += "expected to not be present: #{pp_array(unexpected_items)}\n"
|
73
|
-
message += "the unexpected extra elements: #{pp_array(unexpected_items_that_were_found)}\n"
|
74
|
-
end
|
75
|
-
message
|
76
|
-
end
|
77
|
-
|
78
|
-
# Message to be printed when observed reality does conform to mental
|
79
|
-
# model, but you did not expect it to. (To be honest, we can't think of
|
80
|
-
# why you would want this, but it is included for the sake of RSpec
|
81
|
-
# compatibility.)
|
82
|
-
#
|
83
|
-
# (Part of the RSpec protocol for custom matchers.)
|
84
|
-
#
|
85
|
-
# @return String
|
86
|
-
def failure_message_for_should_not
|
87
|
-
"expected #{@collection_key} not to match the user's mental model"
|
88
|
-
end
|
89
|
-
|
90
|
-
# (Part of the RSpec protocol for custom matchers.)
|
91
|
-
#
|
92
|
-
# @return String
|
93
|
-
def description
|
94
|
-
"match the user's mental model of #{@collection_key}"
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def expected_items; @expected.values; end
|
100
|
-
def unexpected_items; @unexpected.values; end
|
101
|
-
|
102
|
-
def expected_items_that_were_not_found
|
103
|
-
difference_between_arrays(expected_items, @actual)
|
104
|
-
end
|
105
|
-
|
106
|
-
def unexpected_items_that_were_found
|
107
|
-
unexpected_items_not_found = difference_between_arrays(unexpected_items, @actual)
|
108
|
-
difference_between_arrays(unexpected_items, unexpected_items_not_found)
|
109
|
-
end
|
110
|
-
|
111
|
-
def expected_items_found?
|
112
|
-
expected_items_that_were_not_found.empty?
|
113
|
-
end
|
114
|
-
|
115
|
-
def unexpected_items_found?
|
116
|
-
!unexpected_items_that_were_found.empty?
|
117
|
-
end
|
118
|
-
|
119
|
-
# (Swiped from RSpec's array matcher)
|
120
|
-
# Returns the difference of arrays, accounting for duplicates.
|
121
|
-
# e.g., difference_between_arrays([1, 2, 3, 3], [1, 2, 3]) # => [3]
|
122
|
-
def difference_between_arrays(array_1, array_2)
|
123
|
-
difference = array_1.dup
|
124
|
-
array_2.each do |element|
|
125
|
-
if index = difference.index(element)
|
126
|
-
difference.delete_at(index)
|
127
|
-
end
|
128
|
-
end
|
129
|
-
difference
|
130
|
-
end
|
131
|
-
|
132
|
-
def pp_array(array)
|
133
|
-
array = array.sort if array.all? { |e| e.respond_to?(:<=>) }
|
134
|
-
array.inspect
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|