bovem 1.1.1 → 1.2.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.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bovem (1.1.0)
4
+ bovem (1.2.0)
5
5
  lazier (~> 1.0)
6
6
  open4 (~> 1.3.0)
7
7
 
data/lib/bovem/console.rb CHANGED
@@ -130,6 +130,12 @@ module Bovem
130
130
  message
131
131
  end
132
132
 
133
+ # Returns the minimum length of a banner, not including brackets and leading spaces.
134
+ # @return [Fixnum] The minimum length of a banner.
135
+ def self.min_banner_length
136
+ 1
137
+ end
138
+
133
139
  # Executes a command and returns its output.
134
140
  #
135
141
  # @param command [String] The command to execute.
@@ -306,6 +312,21 @@ module Bovem
306
312
  rv
307
313
  end
308
314
 
315
+ # Writes a message, aligning to a call with an empty banner.
316
+ #
317
+ # @param message [String] The message to format.
318
+ # @param suffix [Object] If not `nil` or `false`, a suffix to add to the message. `true` means to add `\n`.
319
+ # @param indent [Object] If not `nil` or `false`, the width to use for indentation. `true` means to use the current indentation, a negative value of `-x` will indent of `x` absolute spaces.
320
+ # @param wrap [Object] If not `nil` or `false`, the maximum length of a line for wrapped text. `true` means the current line width.
321
+ # @param plain [Boolean] If ignore color markers into the message.
322
+ # @param print [Boolean] If `false`, the result will be returned instead of be printed.
323
+ # @return [String] The printed message.
324
+ #
325
+ # @see #format
326
+ def write_banner_aligned(message, suffix = "\n", indent = true, wrap = false, plain = false, print = true)
327
+ self.write((" " * (::Bovem::Console.min_banner_length + 3)) + message.ensure_string, suffix, indent, wrap, plain, print)
328
+ end
329
+
309
330
  # Writes a status to the output. Valid values are `:ok`, `:pass`, `:fail`, `:warn`.
310
331
  #
311
332
  # @param status [Symbol] The status to write.
@@ -348,6 +369,7 @@ module Bovem
348
369
  # @return [String] The banner.
349
370
  # @see #format
350
371
  def get_banner(label, base_color, full_colored = false, bracket_color = "blue", brackets = ["[", "]"])
372
+ label = label.rjust(Bovem::Console.min_banner_length, " ")
351
373
  brackets = brackets.ensure_array
352
374
  bracket_color = base_color if full_colored
353
375
  "{mark=%s}%s{mark=%s}%s{/mark}%s{/mark}" % [bracket_color.parameterize, brackets[0], base_color.parameterize, label, brackets[1]]
@@ -366,7 +388,7 @@ module Bovem
366
388
  #
367
389
  # @see #format
368
390
  def info(message, suffix = "\n", indent = true, wrap = false, plain = false, indented_banner = false, full_colored = false, print = true)
369
- banner = self.get_banner(" INFO", "bright cyan", full_colored)
391
+ banner = self.get_banner("I", "bright cyan", full_colored)
370
392
  message = self.indent(message, indented_banner ? 0 : indent)
371
393
  self.write(banner + " " + message, suffix, indented_banner ? indent : 0, wrap, plain, print)
372
394
  end
@@ -384,7 +406,7 @@ module Bovem
384
406
  #
385
407
  # @see #format
386
408
  def begin(message, suffix = "\n", indent = true, wrap = false, plain = false, indented_banner = false, full_colored = false, print = true)
387
- banner = " " + self.get_banner("*", "bright green")
409
+ banner = self.get_banner("*", "bright green")
388
410
  message = self.indent(message, indented_banner ? 0 : indent)
389
411
  self.write(banner + " " + message, suffix, indented_banner ? indent : 0, wrap, plain, print)
390
412
  end
@@ -402,7 +424,7 @@ module Bovem
402
424
  #
403
425
  # @see #format
404
426
  def warn(message, suffix = "\n", indent = true, wrap = false, plain = false, indented_banner = false, full_colored = false, print = true)
405
- banner = self.get_banner(" WARN", "bright yellow", full_colored)
427
+ banner = self.get_banner("W", "bright yellow", full_colored)
406
428
  message = self.indent(message, indented_banner ? 0 : indent)
407
429
  self.write(banner + " " + message, suffix, indented_banner ? indent : 0, wrap, plain, print)
408
430
  end
@@ -420,7 +442,7 @@ module Bovem
420
442
  #
421
443
  # @see #format
422
444
  def error(message, suffix = "\n", indent = true, wrap = false, plain = false, indented_banner = false, full_colored = false, print = true)
423
- banner = self.get_banner("ERROR", "bright red", full_colored)
445
+ banner = self.get_banner("E", "bright red", full_colored)
424
446
  message = self.indent(message, indented_banner ? 0 : indent)
425
447
  self.write(banner + " " + message, suffix, indented_banner ? indent : 0, wrap, plain, print)
426
448
  end
@@ -456,7 +478,7 @@ module Bovem
456
478
  #
457
479
  # @see #format
458
480
  def debug(message, suffix = "\n", indent = true, wrap = false, plain = false, indented_banner = false, full_colored = false, print = true)
459
- banner = self.get_banner("DEBUG", "bright magenta", full_colored)
481
+ banner = self.get_banner("D", "bright magenta", full_colored)
460
482
  message = self.indent(message, indented_banner ? 0 : indent)
461
483
  self.write(banner + " " + message, suffix, indented_banner ? indent : 0, wrap, plain, print)
462
484
  end
@@ -543,7 +565,7 @@ module Bovem
543
565
  self.status(:fail, plain)
544
566
  exit(rv.length > 1 ? rv[1].to_integer : -1)
545
567
  else
546
- self.status(status, plain)
568
+ self.status(status, plain) if message.present?
547
569
  end
548
570
  end
549
571
 
data/lib/bovem/shell.rb CHANGED
@@ -342,9 +342,13 @@ module Bovem
342
342
 
343
343
  # Find a list of files in directories matching given regexps or patterns.
344
344
  #
345
+ # You can also pass a block to perform matching. The block will receive a single argument and the path will be considered matched if the blocks not evaluates to `nil` or `false`.
346
+ #
347
+ # Inside the block, you can call `Find.prune` to stop searching in the current directory.
348
+ #
345
349
  # @param directories [String] A list of directories where to search files.
346
- # @param patterns [Array] A list of regexps or patterns to match files. If empty, every file is returned.
347
- # @param by_extension [Boolean] If to only search in extensions.
350
+ # @param patterns [Array] A list of regexps or patterns to match files. If empty, every file is returned. Ignored if a block is provided.
351
+ # @param by_extension [Boolean] If to only search in extensions. Ignored if a block is provided.
348
352
  # @param case_sensitive [Boolean] If the search is case sensitive. Only meaningful for string patterns.
349
353
  def find(directories, patterns = [], by_extension = false, case_sensitive = false)
350
354
  rv = []
@@ -361,8 +365,12 @@ module Bovem
361
365
  if self.check(directory, [:directory, :readable, :executable]) then
362
366
  Find.find(directory) do |entry|
363
367
  found = patterns.blank? ? true : catch(:found) do
364
- patterns.each do |pattern|
365
- throw(:found, true) if pattern.match(entry) && (!by_extension || !File.directory?(entry))
368
+ if block_given? then
369
+ throw(:found, true) if yield(entry)
370
+ else
371
+ patterns.each do |pattern|
372
+ throw(:found, true) if pattern.match(entry) && (!by_extension || !File.directory?(entry))
373
+ end
366
374
  end
367
375
 
368
376
  false
data/lib/bovem/version.rb CHANGED
@@ -14,10 +14,10 @@ module Bovem
14
14
  MAJOR = 1
15
15
 
16
16
  # The minor version.
17
- MINOR = 1
17
+ MINOR = 2
18
18
 
19
19
  # The patch version.
20
- PATCH = 1
20
+ PATCH = 0
21
21
 
22
22
  # The current version number of Bovem.
23
23
  STRING = [MAJOR, MINOR, PATCH].compact.join(".")
@@ -51,6 +51,12 @@ describe Bovem::Console do
51
51
  end
52
52
  end
53
53
 
54
+ describe ".min_banner_length" do
55
+ it "should return a number" do
56
+ expect(::Bovem::Console.min_banner_length).to be_a(Fixnum)
57
+ end
58
+ end
59
+
54
60
  describe "#initialize" do
55
61
  it "should correctly set defaults" do
56
62
  expect(console.indentation).to eq(0)
@@ -186,6 +192,14 @@ describe Bovem::Console do
186
192
  end
187
193
  end
188
194
 
195
+ describe "#write_banner_aligned" do
196
+ it "should call #min_banner_length and #format" do
197
+ ::Bovem::Console.should_receive(:min_banner_length).and_return(1)
198
+ console.should_receive(:format).with(" A", "B", "C", "D", "E")
199
+ console.write_banner_aligned("A", "B", "C", "D", "E")
200
+ end
201
+ end
202
+
189
203
  describe "#get_banner" do
190
204
  it "should correctly format arguments" do
191
205
  expect(console.get_banner("LABEL", "red")).to eq("{mark=blue}[{mark=red}LABEL{/mark}]{/mark}")
@@ -199,9 +213,9 @@ describe Bovem::Console do
199
213
 
200
214
  describe "#info" do
201
215
  it "should forward everything to #get_banner" do
202
- console.should_receive(:get_banner).with(" INFO", "bright cyan", false).at_least(1).and_return("")
216
+ console.should_receive(:get_banner).with("I", "bright cyan", false).at_least(1).and_return("")
203
217
  console.info("OK", "\n", true, false, false, false, false, false)
204
- console.should_receive(:get_banner).with(" INFO", "bright cyan", true).at_least(1).and_return("")
218
+ console.should_receive(:get_banner).with("I", "bright cyan", true).at_least(1).and_return("")
205
219
  console.info("OK", "\n", true, false, false, false, true, false)
206
220
  end
207
221
 
@@ -225,9 +239,9 @@ describe Bovem::Console do
225
239
 
226
240
  describe "#warn" do
227
241
  it "should forward everything to #get_banner" do
228
- console.should_receive(:get_banner).with(" WARN", "bright yellow", false).at_least(1).and_return("")
242
+ console.should_receive(:get_banner).with("W", "bright yellow", false).at_least(1).and_return("")
229
243
  console.warn("OK", "\n", true, false, false, false, false, false)
230
- console.should_receive(:get_banner).with(" WARN", "bright yellow", true).at_least(1).and_return("")
244
+ console.should_receive(:get_banner).with("W", "bright yellow", true).at_least(1).and_return("")
231
245
  console.warn("OK", "\n", true, false, false, false, true, false)
232
246
  end
233
247
 
@@ -239,9 +253,9 @@ describe Bovem::Console do
239
253
 
240
254
  describe "#error" do
241
255
  it "should forward everything to #get_banner" do
242
- console.should_receive(:get_banner).with("ERROR", "bright red", false).at_least(1).and_return("")
256
+ console.should_receive(:get_banner).with("E", "bright red", false).at_least(1).and_return("")
243
257
  console.error("OK", "\n", true, false, false, false, false, false)
244
- console.should_receive(:get_banner).with("ERROR", "bright red", true).at_least(1).and_return("")
258
+ console.should_receive(:get_banner).with("E", "bright red", true).at_least(1).and_return("")
245
259
  console.error("OK", "\n", true, false, false, false, true, false)
246
260
  end
247
261
 
@@ -269,9 +283,9 @@ describe Bovem::Console do
269
283
 
270
284
  describe "#debug" do
271
285
  it "should forward everything to #get_banner" do
272
- console.should_receive(:get_banner).with("DEBUG", "bright magenta", false).at_least(1).and_return("")
286
+ console.should_receive(:get_banner).with("D", "bright magenta", false).at_least(1).and_return("")
273
287
  console.debug("OK", "\n", true, false, false, false, false, false)
274
- console.should_receive(:get_banner).with("DEBUG", "bright magenta", true).at_least(1).and_return("")
288
+ console.should_receive(:get_banner).with("D", "bright magenta", true).at_least(1).and_return("")
275
289
  console.debug("OK", "\n", true, false, false, false, true, false)
276
290
  end
277
291
 
@@ -410,10 +424,11 @@ describe Bovem::Console do
410
424
  end
411
425
 
412
426
  it "should write the correct status" do
427
+ console.stub(:begin)
413
428
  console.should_receive(:status).with(:ok, false)
414
- console.task { :ok }
429
+ console.task("OK") { :ok }
415
430
  console.should_receive(:status).with(:fail, false)
416
- expect { console.task { :fatal }}.to raise_error(SystemExit)
431
+ expect { console.task("") { :fatal }}.to raise_error(SystemExit)
417
432
  end
418
433
 
419
434
  it "should abort correctly" do
@@ -474,5 +474,20 @@ describe Bovem::Shell do
474
474
  expect(shell.find(root + "/lib/bovem", /bovem/, true)).to eq([])
475
475
  expect(shell.find(root + "/lib/bovem", "RB", true, true)).to eq([])
476
476
  end
477
+
478
+ it "should filter files basing using a block" do
479
+ files = []
480
+
481
+ Find.find(root + "/lib/bovem/") do |file|
482
+ files << file if !File.directory?(file)
483
+ end
484
+
485
+ expect(shell.find(root + "/lib/bovem", /rb/, true) { |file|
486
+ !File.directory?(file)
487
+ }).to eq(files)
488
+ expect(shell.find(root + "/lib/bovem", /bovem/, true) { |file|
489
+ false
490
+ }).to eq([])
491
+ end
477
492
  end
478
493
  end
metadata CHANGED
@@ -1,167 +1,173 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: bovem
3
- version: !ruby/object:Gem::Version
4
- version: 1.1.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 31
5
5
  prerelease:
6
+ segments:
7
+ - 1
8
+ - 2
9
+ - 0
10
+ version: 1.2.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Shogun
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-09-10 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: lazier
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: '1.0'
22
- type: :runtime
17
+
18
+ date: 2012-09-23 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ hash: 15
27
+ segments:
28
+ - 1
29
+ - 0
30
+ version: "1.0"
23
31
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: '1.0'
30
- - !ruby/object:Gem::Dependency
31
- name: open4
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 1.3.0
38
32
  type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
33
+ name: lazier
34
+ requirement: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ version_requirements: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ hash: 27
42
+ segments:
43
+ - 1
44
+ - 3
45
+ - 0
45
46
  version: 1.3.0
46
- - !ruby/object:Gem::Dependency
47
- name: rspec
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ~>
52
- - !ruby/object:Gem::Version
53
- version: 2.11.0
54
- type: :development
55
47
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ~>
60
- - !ruby/object:Gem::Version
48
+ type: :runtime
49
+ name: open4
50
+ requirement: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ hash: 35
58
+ segments:
59
+ - 2
60
+ - 11
61
+ - 0
61
62
  version: 2.11.0
62
- - !ruby/object:Gem::Dependency
63
- name: rake
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ~>
68
- - !ruby/object:Gem::Version
69
- version: 0.9.0
70
- type: :development
71
63
  prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ~>
76
- - !ruby/object:Gem::Version
77
- version: 0.9.0
78
- - !ruby/object:Gem::Dependency
79
- name: simplecov
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ~>
84
- - !ruby/object:Gem::Version
85
- version: 0.6.0
86
64
  type: :development
65
+ name: rspec
66
+ requirement: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ version_requirements: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ hash: 59
74
+ segments:
75
+ - 0
76
+ - 9
77
+ - 0
78
+ version: 0.9.0
87
79
  prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: 0.6.0
94
- - !ruby/object:Gem::Dependency
95
- name: pry
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ! '>='
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
80
  type: :development
81
+ name: rake
82
+ requirement: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ version_requirements: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ hash: 7
90
+ segments:
91
+ - 0
92
+ - 6
93
+ - 0
94
+ version: 0.6.0
103
95
  prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
- requirements:
107
- - - ! '>='
108
- - !ruby/object:Gem::Version
109
- version: '0'
110
- - !ruby/object:Gem::Dependency
111
- name: yard
112
- requirement: !ruby/object:Gem::Requirement
113
- none: false
114
- requirements:
115
- - - ~>
116
- - !ruby/object:Gem::Version
117
- version: 0.8.0
118
96
  type: :development
97
+ name: simplecov
98
+ requirement: *id005
99
+ - !ruby/object:Gem::Dependency
100
+ version_requirements: &id006 !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 3
106
+ segments:
107
+ - 0
108
+ version: "0"
119
109
  prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
- requirements:
123
- - - ~>
124
- - !ruby/object:Gem::Version
125
- version: 0.8.0
126
- - !ruby/object:Gem::Dependency
127
- name: redcarpet
128
- requirement: !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ~>
132
- - !ruby/object:Gem::Version
133
- version: 2.1.0
134
110
  type: :development
111
+ name: pry
112
+ requirement: *id006
113
+ - !ruby/object:Gem::Dependency
114
+ version_requirements: &id007 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ~>
118
+ - !ruby/object:Gem::Version
119
+ hash: 63
120
+ segments:
121
+ - 0
122
+ - 8
123
+ - 0
124
+ version: 0.8.0
135
125
  prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ~>
140
- - !ruby/object:Gem::Version
141
- version: 2.1.0
142
- - !ruby/object:Gem::Dependency
143
- name: github-markup
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ~>
148
- - !ruby/object:Gem::Version
149
- version: 0.7.0
150
126
  type: :development
127
+ name: yard
128
+ requirement: *id007
129
+ - !ruby/object:Gem::Dependency
130
+ version_requirements: &id008 !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ~>
134
+ - !ruby/object:Gem::Version
135
+ hash: 11
136
+ segments:
137
+ - 2
138
+ - 1
139
+ - 0
140
+ version: 2.1.0
151
141
  prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
- requirements:
155
- - - ~>
156
- - !ruby/object:Gem::Version
142
+ type: :development
143
+ name: redcarpet
144
+ requirement: *id008
145
+ - !ruby/object:Gem::Dependency
146
+ version_requirements: &id009 !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ~>
150
+ - !ruby/object:Gem::Version
151
+ hash: 3
152
+ segments:
153
+ - 0
154
+ - 7
155
+ - 0
157
156
  version: 0.7.0
157
+ prerelease: false
158
+ type: :development
159
+ name: github-markup
160
+ requirement: *id009
158
161
  description: A collection of utilities for developers.
159
- email:
162
+ email:
160
163
  - shogun_panda@me.com
161
164
  executables: []
165
+
162
166
  extensions: []
167
+
163
168
  extra_rdoc_files: []
164
- files:
169
+
170
+ files:
165
171
  - .gitignore
166
172
  - .travis.yml
167
173
  - .yardopts
@@ -185,29 +191,38 @@ files:
185
191
  - spec/spec_helper.rb
186
192
  homepage: http://github.com/ShogunPanda/bovem
187
193
  licenses: []
194
+
188
195
  post_install_message:
189
196
  rdoc_options: []
190
- require_paths:
197
+
198
+ require_paths:
191
199
  - lib
192
- required_ruby_version: !ruby/object:Gem::Requirement
200
+ required_ruby_version: !ruby/object:Gem::Requirement
193
201
  none: false
194
- requirements:
195
- - - ! '>='
196
- - !ruby/object:Gem::Version
197
- version: '0'
198
- required_rubygems_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ hash: 3
206
+ segments:
207
+ - 0
208
+ version: "0"
209
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
210
  none: false
200
- requirements:
201
- - - ! '>='
202
- - !ruby/object:Gem::Version
203
- version: '0'
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ hash: 3
215
+ segments:
216
+ - 0
217
+ version: "0"
204
218
  requirements: []
219
+
205
220
  rubyforge_project: bovem
206
221
  rubygems_version: 1.8.24
207
222
  signing_key:
208
223
  specification_version: 3
209
224
  summary: A collection of utilities for developers.
210
- test_files:
225
+ test_files:
211
226
  - spec/bovem/configuration_spec.rb
212
227
  - spec/bovem/console_spec.rb
213
228
  - spec/bovem/logger_spec.rb