libis-tools 0.9.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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.travis.yml +37 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +289 -0
- data/Rakefile +6 -0
- data/lib/libis-tools.rb +1 -0
- data/lib/libis/tools.rb +16 -0
- data/lib/libis/tools/assert.rb +41 -0
- data/lib/libis/tools/checksum.rb +84 -0
- data/lib/libis/tools/command.rb +40 -0
- data/lib/libis/tools/config.rb +160 -0
- data/lib/libis/tools/dc_record.rb +47 -0
- data/lib/libis/tools/extend/empty.rb +7 -0
- data/lib/libis/tools/extend/hash.rb +107 -0
- data/lib/libis/tools/extend/ostruct.rb +3 -0
- data/lib/libis/tools/extend/string.rb +85 -0
- data/lib/libis/tools/extend/struct.rb +29 -0
- data/lib/libis/tools/logger.rb +71 -0
- data/lib/libis/tools/mets_file.rb +575 -0
- data/lib/libis/tools/parameter.rb +172 -0
- data/lib/libis/tools/sharepoint_mapping.rb +118 -0
- data/lib/libis/tools/sharepoint_record.rb +260 -0
- data/lib/libis/tools/version.rb +5 -0
- data/lib/libis/tools/xml_document.rb +574 -0
- data/libis-tools.gemspec +39 -0
- data/spec/assert_spec.rb +65 -0
- data/spec/checksum_spec.rb +132 -0
- data/spec/command_spec.rb +68 -0
- data/spec/config_spec.rb +86 -0
- data/spec/data/test.data +9 -0
- data/spec/data/test.xml +8 -0
- data/spec/data/test.yml +1 -0
- data/spec/logger_spec.rb +107 -0
- data/spec/parameter_container_spec.rb +83 -0
- data/spec/parameter_spec.rb +139 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/test.xsd +20 -0
- data/spec/xmldocument_spec.rb +413 -0
- data/test/test_helper.rb +7 -0
- data/test/webservices/test_ca_item_info.rb +59 -0
- data/test/webservices/test_ca_search.rb +35 -0
- metadata +244 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f9120e1cf4cfed1f9bdfe8529383d4bda5e89e2e
|
4
|
+
data.tar.gz: ab3b461ff790ab4990b63fbc3e63166b8a38471b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bbdcff4a1240c7c72d0aadea944b045b76c37a71f652515207b4f27c93addce312000efb2f601464f8a55bc5f354c799681111539ab89a19bfbdaee28bc1bc01
|
7
|
+
data.tar.gz: b7619f13ddc7423341ae4a81692e2eec5b52037acf830c828d5db783fd4888ba088b7c95d6e557f6f87583f34e2c1ac0f8cc0162bb334c7990371e5b8fec4681
|
data/.coveralls.yml
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 1.9.3
|
5
|
+
- 2.1.0
|
6
|
+
- 2.2.0
|
7
|
+
- ruby-head
|
8
|
+
- jruby-19mode
|
9
|
+
jdk:
|
10
|
+
- openjdk7
|
11
|
+
- oraclejdk7
|
12
|
+
- oraclejdk8
|
13
|
+
matrix:
|
14
|
+
exclude:
|
15
|
+
- rvm: 1.9.3
|
16
|
+
jdk: oraclejdk7
|
17
|
+
- rvm: 1.9.3
|
18
|
+
jdk: oraclejdk8
|
19
|
+
- rvm: 2.1.0
|
20
|
+
jdk: oraclejdk7
|
21
|
+
- rvm: 2.1.0
|
22
|
+
jdk: oraclejdk8
|
23
|
+
- rvm: 2.2.0
|
24
|
+
jdk: oraclejdk7
|
25
|
+
- rvm: 2.2.0
|
26
|
+
jdk: oraclejdk8
|
27
|
+
- rvm: ruby-head
|
28
|
+
jdk: oraclejdk7
|
29
|
+
- rvm: ruby-head
|
30
|
+
jdk: oraclejdk8
|
31
|
+
branches:
|
32
|
+
only:
|
33
|
+
- master
|
34
|
+
addons:
|
35
|
+
code_climate:
|
36
|
+
repo_token: f6978964f55e6543befb82373651365f8195677816af6ff40ad70c82f7f22f09
|
37
|
+
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 LIBIS
|
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,289 @@
|
|
1
|
+
[](https://travis-ci.org/Kris-LIBIS/LIBIS_Tools)
|
2
|
+
[](https://coveralls.io/r/Kris-LIBIS/LIBIS_Tools)
|
3
|
+
[](https://gemnasium.com/Kris-LIBIS/LIBIS_Tools)
|
4
|
+
<!--[](https://codeclimate.com/github/Kris-LIBIS/LIBIS_Tools)
|
5
|
+
[](https://codeclimate.com/github/Kris-LIBIS/LIBIS_Tools)
|
6
|
+
-->
|
7
|
+
|
8
|
+
# Libis::Tools
|
9
|
+
|
10
|
+
This gem contains some generic helper methods, classes and modules that should be easily reusable in other projects.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem 'libis-tools'
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install libis-tools
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
In order to make available all the code the gem supplies a single file can be included:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
require 'libis-tools'
|
34
|
+
```
|
35
|
+
|
36
|
+
or:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'libis/tools'
|
40
|
+
```
|
41
|
+
|
42
|
+
Alternatively, if you only want to use a single class or module, partial files are available. See the examples in the
|
43
|
+
sections below for their names.
|
44
|
+
|
45
|
+
## Content
|
46
|
+
|
47
|
+
### assert
|
48
|
+
|
49
|
+
The Object#assert method enables the assert functionality found in other languages.
|
50
|
+
The method takes an argument that will be interpreted as a boolean expression and an optional message.
|
51
|
+
If the boolean expression evaluates to false an AssertionFailure exception will be raised.
|
52
|
+
|
53
|
+
Alternatively, if a block is passed to the method, the given block will be evaluated and the result will decide if the
|
54
|
+
exception will be raised. In that case the first argument passed to the assert method is used as message and the second
|
55
|
+
argument is ignored.
|
56
|
+
|
57
|
+
The method will not evaluate the first parameter or block unless the general parameter $DEBUG evaluates to true. That
|
58
|
+
means that special care should be taken that the expression does not generate any side effects that the program may rely
|
59
|
+
on.
|
60
|
+
|
61
|
+
Examples:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
require 'libis/tools/assert'
|
65
|
+
assert(value > 0, 'value should be positive number')
|
66
|
+
```
|
67
|
+
and using a code block:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
require 'libis/tools/assert'
|
71
|
+
assert 'database is not idle' do
|
72
|
+
db = get_database
|
73
|
+
db.status == :IDLE
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
### Checksum
|
78
|
+
|
79
|
+
The ::Libis::Tools::Checksum class offers a standardized interface for calculating checksums of file contents in
|
80
|
+
different formats. The actual list of supported checksum formats is in ::Libis::Tools::Checksum.CHECKSUM_TYPES. It
|
81
|
+
contains MD5, SHA-1 and SHA-2 (in 256-bit, 384-bit and 512-bit variants).
|
82
|
+
|
83
|
+
There are two ways this can be used: using a class instance or using class methods. When a class instance is used, the
|
84
|
+
desired checksum type has to be supplied when the instance is created. Each call to a checksum method will calculate the
|
85
|
+
checksum and reset the digest to prevent future calls to be affected by the current result. When a class method is used
|
86
|
+
besides the file name, the checksum type has to be supplied.
|
87
|
+
|
88
|
+
The available methods on both instance and class level are:
|
89
|
+
|
90
|
+
* digest: return the checksum as (binary) string.
|
91
|
+
* hexdigest: return the checksum as hexadecimal encoded string.
|
92
|
+
* base64digest: return the checksum as base64 encoded string.
|
93
|
+
|
94
|
+
Examples:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
require 'libis/tools/checksum'
|
98
|
+
checksum = ::Libis::Tools::Checksum.new(:MD5)
|
99
|
+
puts "Checksum: #{checksum.hexdigest(file_name)} (MD5, hex)"
|
100
|
+
```
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
require 'libis/tools/checksum'
|
104
|
+
puts "Checksum: #{::Libis::Tools::Checksum.base64digest(file_name, :SHA384)} (SHA-2, 384 bit, base64)"
|
105
|
+
```
|
106
|
+
|
107
|
+
### Command
|
108
|
+
|
109
|
+
This module allows to run an external command safely and returns it's output, error messages and status. The run method
|
110
|
+
takes any number of arguments that will be used as command-line arguments. The method returns a Hash with:
|
111
|
+
|
112
|
+
* :out => an array with lines that were printed on the external program's standard out.
|
113
|
+
* :err => an array with lines that were printed on the external program's standard error.
|
114
|
+
* :status => exit code returned by the external program.
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
require 'libis/tools/command'
|
118
|
+
result = ::Libis::Tools::Command.run('ls', '-l', File.absolute_path(__FILE__))
|
119
|
+
p result # => {out: [...], err: [...], status: 0}
|
120
|
+
```
|
121
|
+
|
122
|
+
or:
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
require 'libis/tools/command'
|
126
|
+
include ::Libis::Tools::Command
|
127
|
+
result = run('ls', '-l', File.absolute_path(__FILE__))
|
128
|
+
p result # => {out: [...], err: [...], status: 0}
|
129
|
+
```
|
130
|
+
|
131
|
+
Note that the Command class uses Open3#popen3 internally. All arguments supplied to Command#run are passed to the popen3
|
132
|
+
call. Unfortunately JRuby has some known issues with popen3. Please use and test carefully in JRuby environments.
|
133
|
+
|
134
|
+
### Config
|
135
|
+
|
136
|
+
The Config class is a convenience method for easy configuration maintenance and loading. It supports code defaults,
|
137
|
+
loading configurations from multiple YAML files containing ERB statements. The Config class follows the Singleton
|
138
|
+
pattern and behaves like a Hash/OpenStruct/HashWithIndifferentAccess. It also initializes a default Logger instance.
|
139
|
+
|
140
|
+
For each configuration parameter, the value can be accessed via the class or the Singleton instance through a method
|
141
|
+
call or via the Hash operator using the parameter name either as a string or a symbol.
|
142
|
+
|
143
|
+
Examples:
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
require 'libis/tools/config'
|
147
|
+
cfg = ::Libis::Tools::Config
|
148
|
+
cfg['my_value'] = 10
|
149
|
+
p cfg.instance.my_value # => 10
|
150
|
+
cfg.instance.my_text = 'abc'
|
151
|
+
p cfg[:my_text] # => 'abc'
|
152
|
+
p cfg.logger.warn('message') # => W, [2015-03-16T12:51:01.180548 #28935] WARN -- : message
|
153
|
+
```
|
154
|
+
|
155
|
+
### Logger
|
156
|
+
|
157
|
+
The Logger module adds logging functionality to any class. Just include the ::Libis::Tools::Logger module and the
|
158
|
+
methods debug, info, warn, error and fatal will be available to the class instance. Each method takes a message argument
|
159
|
+
and optional extra parameters. The methods all call the message method with the logging level as first argument and the
|
160
|
+
supplied arguments appended.
|
161
|
+
|
162
|
+
The default message method implementation uses the logger of ::Libis::Tools::Config. If extra parameters are supplied,
|
163
|
+
the message will be used as a format specification with the extra parameters applied to it. If an 'appname' parameter is
|
164
|
+
defined in the Config object, it will be used as program name by the logger, otherwise the class name is taken.
|
165
|
+
|
166
|
+
If the class defines a #options method that returns a Hash containing a :quiet key, the value for that key will be
|
167
|
+
evaluated and if true debug, info and warning messages will not be printed.
|
168
|
+
|
169
|
+
Example:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
require 'libis/tools/logger'
|
173
|
+
class TestLogger
|
174
|
+
include ::Libis::Tools::Logger
|
175
|
+
attr_accessor :options, name
|
176
|
+
def initialize
|
177
|
+
@options = {}
|
178
|
+
@name = nil
|
179
|
+
end
|
180
|
+
end
|
181
|
+
tl = TestLogger.new
|
182
|
+
tl.debug 'message'
|
183
|
+
tl.options[:quiet] = true
|
184
|
+
tl.warn 'message'
|
185
|
+
::Libis::Tools::Config.appname = 'TestApplication'
|
186
|
+
tl.error 'huge error: [%d] %s', 1000, 'Exit'
|
187
|
+
tl.name = 'TestClass'
|
188
|
+
tl.options[:quiet] = false
|
189
|
+
tl.info 'Running application: %s', ::Libis::Tools::Config.appname
|
190
|
+
```
|
191
|
+
produces:
|
192
|
+
<pre>
|
193
|
+
D, [...] DEBUG -- TestLogger: message
|
194
|
+
E, [...] ERROR -- TestApplication: huge error: [1000] Exit
|
195
|
+
I, [...] INFO -- TestClass: Running application TestApplication
|
196
|
+
</pre>
|
197
|
+
|
198
|
+
### XmlDocument
|
199
|
+
|
200
|
+
Class that embodies most used features of Nokogiri, Nori and Gyoku in one convenience class. The Nokogiri document is
|
201
|
+
stored in the class variable 'document' and can be accessed and manipulated directly - if required. The class supports
|
202
|
+
the Nokogiri Build syntax for creating XML documents in a compact DSL. It also allows you to check the document against
|
203
|
+
an XML Schema and provides shorthand notations for accessing nodes and attributes.
|
204
|
+
|
205
|
+
Example:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
xml_doc = ::Libis::Tools::XmlDocument.parse(<<-END.align_left)
|
209
|
+
<patron>
|
210
|
+
<name>Harry Potter</name>
|
211
|
+
<barcode library="Hogwarts Library">1234567890</barcode>
|
212
|
+
<access_level>student</access_level>
|
213
|
+
<email>harry.potter@hogwarts.edu</email>
|
214
|
+
<email>hpotter@JKRowling.com</email>
|
215
|
+
</patron>
|
216
|
+
END
|
217
|
+
puts '---parse---', xml_doc.to_xml
|
218
|
+
xml_doc.save('/tmp/test.xml')
|
219
|
+
xml_doc = ::Libis::Tools::XmlDocument.open('/tmp/test.xml')
|
220
|
+
puts '---save/open---', xml_doc.to_xml
|
221
|
+
xml_doc = ::Libis::Tools::XmlDocument.build do
|
222
|
+
patron {
|
223
|
+
name 'Harry Potter'
|
224
|
+
barcode( '1234567890', library: 'Hogwarts Library')
|
225
|
+
access_level 'student'
|
226
|
+
email 'harry.potter@hogwarts.edu'
|
227
|
+
email 'hpotter@JKRowling.com'
|
228
|
+
}
|
229
|
+
end
|
230
|
+
puts '---build---', xml_doc.to_xml
|
231
|
+
xml_doc = ::Libis::Tools::XmlDocument.new
|
232
|
+
xml_doc.add_node :patron
|
233
|
+
xml_doc.name = 'Harry Potter'
|
234
|
+
xml_doc.barcode = '1234567890'
|
235
|
+
xml_doc.barcode :library, 'Hogwarts Library'
|
236
|
+
xml_doc.access_level = 'student'
|
237
|
+
xml_doc.email = 'harry.potter@hogwarts.edu'
|
238
|
+
xml_doc.add_node :email, 'hpotter@JKRowling.com'
|
239
|
+
# Note: xml_doc.email('hpotter@JKRowling.com') whould not have created a new node.
|
240
|
+
# It would override the first email element
|
241
|
+
puts '---method---', xml_doc.to_xml
|
242
|
+
```
|
243
|
+
|
244
|
+
produces:
|
245
|
+
|
246
|
+
---parse---
|
247
|
+
<?xml version="1.0" encoding="utf-8"?>
|
248
|
+
<patron>
|
249
|
+
<name>Harry Potter</name>
|
250
|
+
<barcode library="Hogwarts Library">1234567890</barcode>
|
251
|
+
<access_level>student</access_level>
|
252
|
+
<email>harry.potter@hogwarts.edu</email>
|
253
|
+
<email>hpotter@JKRowling.com</email>
|
254
|
+
</patron>
|
255
|
+
---save/open---
|
256
|
+
<?xml version="1.0" encoding="utf-8"?>
|
257
|
+
<patron>
|
258
|
+
<name>Harry Potter</name>
|
259
|
+
<barcode library="Hogwarts Library">1234567890</barcode>
|
260
|
+
<access_level>student</access_level>
|
261
|
+
<email>harry.potter@hogwarts.edu</email>
|
262
|
+
<email>hpotter@JKRowling.com</email>
|
263
|
+
</patron>
|
264
|
+
---build---
|
265
|
+
<?xml version="1.0" encoding="utf-8"?>
|
266
|
+
<patron>
|
267
|
+
<name>Harry Potter</name>
|
268
|
+
<barcode library="Hogwarts Library">1234567890</barcode>
|
269
|
+
<access_level>student</access_level>
|
270
|
+
<email>harry.potter@hogwarts.edu</email>
|
271
|
+
<email>hpotter@JKRowling.com</email>
|
272
|
+
</patron>
|
273
|
+
---method---
|
274
|
+
<?xml version="1.0" encoding="utf-8"?>
|
275
|
+
<patron>
|
276
|
+
<name>Harry Potter</name>
|
277
|
+
<barcode library="Hogwarts Library">1234567890</barcode>
|
278
|
+
<access_level>student</access_level>
|
279
|
+
<email>harry.potter@hogwarts.edu</email>
|
280
|
+
<email>hpotter@JKRowling.com</email>
|
281
|
+
</patron>
|
282
|
+
|
283
|
+
## Contributing
|
284
|
+
|
285
|
+
1. Fork it ( https://github.com/Kris-LIBIS/LIBIS_Tools/fork )
|
286
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
287
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
288
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
289
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/libis-tools.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative 'libis/tools'
|
data/lib/libis/tools.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Libis
|
2
|
+
module Tools
|
3
|
+
|
4
|
+
autoload :Checksum, 'libis/tools/checksum'
|
5
|
+
autoload :Command, 'libis/tools/command'
|
6
|
+
autoload :Config, 'libis/tools/config'
|
7
|
+
autoload :DCRecord, 'libis/tools/dc_record'
|
8
|
+
autoload :Logger, 'libis/tools/logger'
|
9
|
+
autoload :MetsFile, 'libis/tools/mets_file'
|
10
|
+
autoload :Parameter, 'libis/tools/parameter'
|
11
|
+
autoload :XmlDocument, 'libis/tools/xml_document'
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require_relative 'tools/extend/struct'
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class AssertionFailure < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class Object
|
7
|
+
|
8
|
+
# Assert functionality as found in other languages (e.g. 'C').
|
9
|
+
#
|
10
|
+
# The assert is enabled/disabled by setting the $DEBUG global variable. If $DEBUG evaluates to true, the assertion is
|
11
|
+
# active.
|
12
|
+
#
|
13
|
+
# If activated, the first argument will be evaluated and when it evaluates to true, an AssertionFailure exception will
|
14
|
+
# be raised with the message given as the second argument.
|
15
|
+
#
|
16
|
+
# Alternatively, a code block may be passed to the assert. In that case the test expression is not evaluated, but used
|
17
|
+
# as the message for the expression. The assert will yield the code block and it's result will be evaluated to decide
|
18
|
+
# if the exception will be thrown.
|
19
|
+
#
|
20
|
+
# Examples:
|
21
|
+
#
|
22
|
+
# $DEBUG = nil
|
23
|
+
# assert false, 'assert 1' # nothing happens
|
24
|
+
# $DEBUG = true
|
25
|
+
# assert false, 'assert 2' # AssertionFailure 'assert 2' is raised
|
26
|
+
# assert 'assert 3', 'assert 4' do
|
27
|
+
# false
|
28
|
+
# end # AssertionFailure 'assert 3' is raised
|
29
|
+
#
|
30
|
+
# @param [Object] test_expression the expression that will be evaluated; the message if a code block is present
|
31
|
+
# @param [String] message exception message is no code block is present
|
32
|
+
def assert(test_expression, message = 'assertion failure')
|
33
|
+
if $DEBUG
|
34
|
+
if block_given?
|
35
|
+
message = test_expression
|
36
|
+
test_expression = yield
|
37
|
+
end
|
38
|
+
raise AssertionFailure.new(message) unless test_expression
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|