cvg 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NGYyMzdiYzVmMjM0MDI5Y2MzMGNjN2QwNjdkNWM0ZDdlOGZhZDM1OA==
4
+ ZTczMWJiNzMyZGI2NTBjM2E4YmRjNjE4ZGRhODQ1ZTliYmQ4NTE2NA==
5
5
  data.tar.gz: !binary |-
6
- N2IyN2E4ZDM5MDZiYzQwOTBiMmViNWJiMmM2YWIyZDMxMWNkNDQ4Mw==
6
+ NzJmZmMwMTFhOWNjZDZlM2MxNTcyNzU5NjgyYTA5NzA2YTQwZGZlNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NGEyMjk2ODM0MmNjNjQ1NjllM2RiZWFhN2FlZDdlZTA5N2RmNzNlMjIyNWI1
10
- ZWJhYjIxYzk5NGVjNWVmZGQ3NjlmNTc1Y2NlYmRlY2QxY2NmYWU5MzMzZTRm
11
- Y2Q3MjJmYWZiYzVjZWU5MTgyMWMyNmE4MGYzMDY5Zjk0Yjg4ZTE=
9
+ MmZiZDk0MmYxYzVkMmIxYTY4YmQ2Njk3MjJiODM4YjIxMjZlMTExNjlhNzBi
10
+ ZjVjMTIyY2M5OTQwMzQ5MjlhMWUwNDQ3MzhjNWJhNTZhNzg4NmRlOGQ1ZDRi
11
+ ODg5NDg3ZjdlMDc0NTAxY2JlNzgyNDlhOWNiNTRjMWZmZjRkM2Q=
12
12
  data.tar.gz: !binary |-
13
- MTliZjBlY2ZlM2JlZThhM2Y5YWFmYzk0NWEyNTc0MmNiOGYxMmYzYjk4OWIy
14
- ODZmMmM4OGNhMTQxZWIzMzdlYzEyODJkMTFmMTU3MGFmYmE3Yzc1N2JlMTFk
15
- ZTRjYWUxZjI5MzQ0ZmZmMWIxMjk2NjVkOGNiNTI0MDdmMWNlNDg=
13
+ ODlmNWM4NjA0ZDMwYTJlMWZkMzZmZmQ4NGEyOTk4NTM3YTYxYjYyY2JhNDk3
14
+ YzQ2MTYxMGI5ZWYwMGM0OTgyZGU0OTlmMzdjNDFmZmRiNmEyMTYwMDhiYjA3
15
+ ZWQ5YTFkNWY3ZDdmM2VlYWRiMmFmZGQzMGJlM2MzZWJkMGUyYzA=
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ 0.1.1 / 2013-11-11
2
+
3
+ * Enhancements
4
+
5
+ * --count outputs just "Count: %d" of passing rows
6
+
1
7
  0.1.0 / 2013-11-08
2
8
 
3
9
  * Breaking changes
data/bin/cvg CHANGED
@@ -155,7 +155,26 @@ class Cvg
155
155
  end
156
156
  end
157
157
 
158
- class DetectMissing
158
+ class Flag
159
+ attr_reader :parent
160
+ def initialize(parent)
161
+ @parent = parent
162
+ end
163
+ def mode
164
+ nil
165
+ end
166
+ def per_row_pre_test?
167
+ nil
168
+ end
169
+ def per_row_passed_test?
170
+ nil
171
+ end
172
+ def final?
173
+ nil
174
+ end
175
+ end
176
+
177
+ class DetectMissing < Flag
159
178
  MISSING = %w{ N/A n/a NULL null - #DIV/0 #REF! #NAME? NIL nil NA na #VALUE! #NULL! NaN #N/A #NUM! ? }
160
179
  def apply!(row)
161
180
  row.each do |k, v|
@@ -164,11 +183,38 @@ class Cvg
164
183
  end
165
184
  end
166
185
  end
186
+ def per_row_pre_test?
187
+ true
188
+ end
189
+ end
190
+
191
+ class Count < Flag
192
+ attr_reader :num
193
+ def initialize(*)
194
+ super
195
+ @num = 0
196
+ end
197
+ def apply!(row)
198
+ @num += 1
199
+ end
200
+ def finalize
201
+ parent.output_f.puts "Count: #{num}"
202
+ end
203
+ def mode
204
+ :dont_write_rows
205
+ end
206
+ def per_row_passed_test?
207
+ true
208
+ end
209
+ def final?
210
+ true
211
+ end
167
212
  end
168
213
 
169
214
  TESTS = [Present, Missing, Match, GreaterOrLesser, Dedup]
170
215
  FLAGS = {
171
216
  'detect-missing' => DetectMissing,
217
+ 'count' => Count,
172
218
  }
173
219
 
174
220
  attr_reader :options
@@ -179,24 +225,35 @@ class Cvg
179
225
  end
180
226
 
181
227
  def perform
182
- write_headers
228
+ if write_rows?
229
+ write_headers
230
+ end
183
231
 
184
232
  each_input_row do |row|
185
233
  if tests.all? { |t| t.pass?(row) }
186
- write_row row
234
+ per_row_passed_test_flags.each { |flag| flag.apply! row }
235
+ if write_rows?
236
+ write_row row
237
+ end
187
238
  end
188
239
  end
189
240
 
241
+ final_flags.each { |flag| flag.finalize }
242
+
190
243
  close_output
191
244
  end
192
245
 
246
+ def output_f
247
+ @output_f ||= $stdout
248
+ end
249
+
193
250
  private
194
251
 
195
252
  def each_input_row
196
253
  input_paths.each do |path|
197
254
  CSV.foreach(path, headers: :first_row) do |row|
198
255
  row = row.to_hash
199
- flags.each { |flag| flag.apply! row }
256
+ per_row_pre_test_flags.each { |flag| flag.apply! row }
200
257
  yield row
201
258
  end
202
259
  end
@@ -216,10 +273,31 @@ class Cvg
216
273
  end
217
274
  end
218
275
 
276
+ def write_rows?
277
+ return @write_rows_query if defined?(@write_rows_query)
278
+ @write_rows_query = !modes.include?(:dont_write_rows)
279
+ end
280
+
281
+ def modes
282
+ @modes ||= flags.map(&:mode).flatten.compact
283
+ end
284
+
285
+ def per_row_pre_test_flags
286
+ @per_row_pre_test_flags ||= flags.select { |flag| flag.per_row_pre_test? }
287
+ end
288
+
289
+ def per_row_passed_test_flags
290
+ @per_row_passed_test_flags ||= flags.select { |flag| flag.per_row_passed_test? }
291
+ end
292
+
293
+ def final_flags
294
+ @final_flags ||= flags.select { |flag| flag.final? }
295
+ end
296
+
219
297
  def flags
220
298
  @_flags ||= begin
221
299
  @flags.map do |flag|
222
- FLAGS.fetch(flag).new
300
+ FLAGS.fetch(flag).new(self)
223
301
  end
224
302
  end
225
303
  end
@@ -232,10 +310,6 @@ class Cvg
232
310
  output_f.puts fields.to_csv
233
311
  end
234
312
 
235
- def output_f
236
- @output_f ||= $stdout
237
- end
238
-
239
313
  def close_output
240
314
  output_f.close
241
315
  end
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "rspec"
27
27
  spec.add_development_dependency "rspec-expectations"
28
28
  spec.add_development_dependency "posix-spawn"
29
+ spec.add_development_dependency "pry"
29
30
  end
@@ -1,3 +1,16 @@
1
+ def cvgme(args, input_csv_paths)
2
+ bin_path = File.expand_path '../../../bin/cvg', __FILE__
3
+ cmd = "#{bin_path} #{args.join(' ')} #{input_csv_paths.join(' ')}"
4
+ child = POSIX::Spawn::Child.new cmd
5
+ if child.err.present?
6
+ $stderr.puts
7
+ $stderr.puts cmd
8
+ $stderr.puts child.err
9
+ $stderr.puts
10
+ end
11
+ child.out.strip
12
+ end
13
+
1
14
  Before do
2
15
  @input_csv_paths = []
3
16
  @args = []
@@ -14,16 +27,13 @@ When(/^you pass arguments (.+)$/) do |args|
14
27
  end
15
28
 
16
29
  Then(/^you get output$/) do |expected_output_csv|
17
- bin_path = File.expand_path '../../../bin/cvg', __FILE__
18
- cmd = "#{bin_path} #{@args.join(' ')} #{@input_csv_paths.join(' ')}"
19
- child = POSIX::Spawn::Child.new cmd
20
- if child.err.present?
21
- $stderr.puts
22
- $stderr.puts cmd
23
- $stderr.puts child.err
24
- $stderr.puts
25
- end
26
- expect(child.out.strip).to eq(expected_output_csv.strip)
30
+ got_csv = cvgme(@args, @input_csv_paths)
31
+ expect(got_csv).to eq(expected_output_csv.strip)
32
+
33
+ expected_count = CSV.parse(expected_output_csv.strip, headers: :first_row).length
34
+ got_count = cvgme((@args + ['--count']), @input_csv_paths)
35
+ expect(got_count).to match(/Count: #{expected_count}/)
36
+
27
37
  @input_csv_paths.each do |path|
28
38
  if File.dirname(File.expand_path(path)).start_with?(Dir.tmpdir)
29
39
  File.unlink path
@@ -1,5 +1,6 @@
1
1
  # require 'bundler/setup'
2
2
  require 'tmpdir'
3
+ require 'csv'
3
4
  require 'rspec/expectations'
4
5
  require 'posix/spawn'
5
6
  require 'active_support/core_ext'
data/lib/cvg.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "cvg/version"
2
2
 
3
- module Cvg
3
+ class Cvg
4
4
  # Your code goes here...
5
5
  end
@@ -1,3 +1,3 @@
1
- module Cvg
2
- VERSION = "0.1.0"
1
+ class Cvg
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cvg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seamus Abshere
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-08 00:00:00.000000000 Z
11
+ date: 2013-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ! '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Like jq or grep for csv. Combine one or more CSVs while filtering on
112
126
  fields with regular expressions, whitelists, presence, missing, etc.
113
127
  email: