csv_pirate 3.4.4 → 4.0.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.
data/CHANGELOG CHANGED
@@ -1,3 +1,13 @@
1
+ Version 4.0.1 2010-01-15
2
+ - Improving import / export
3
+ - Updating Readme to reflect 4.0.0 API
4
+
5
+ Version 4.0.0 2010-01-14 (never released)
6
+ - CSV Imports from old CsvPirate Dumps
7
+ - Lots of refactoring
8
+ - Lots of bug reduction
9
+ - added Rspec tests!
10
+
1
11
  Version 3.4.4 2009-11-10
2
12
  - Fixed installation instructions to refer to gemcutter, and removed github as gemhost
3
13
 
data/README.rdoc CHANGED
@@ -2,9 +2,11 @@
2
2
 
3
3
  Easily create CSVs of any data that can be derived from your models.
4
4
 
5
- CsvPirate is the easy way to create a CSV of essentially anything in Rails, in full pirate regalia.
5
+ CsvPirate is the easy way to create a CSV of essentially anything in Ruby, in full pirate regalia.
6
6
  It works better if you are wearing a tricorne!
7
7
 
8
+ Everything in the source that depended on Rails extensions of Ruby classes has been refactored to work in pure Ruby!
9
+
8
10
  My goal is to have it do EVERYTHING it possibly can for me, since almost every project I do needs CSV exports.
9
11
 
10
12
  CsvPirate only works for commissions of swag OR grub!
@@ -33,9 +35,9 @@ Initialize method (a.k.a new()) takes a hash of parameters:
33
35
  # :bury_treasure should we store the csv data as it is collected in an array in Ruby form for later use (true), or just write the CSV (false)?
34
36
  # :blackjack Specify how you want your CSV header
35
37
  # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
36
- # {:humanize =>'-'} first joins as above, then humanizes the string
38
+ # {:humanize =>'-'} first joins as above, then humanizes the string (this is the default)
37
39
  # {:array => ['col1',col2','col3'] Uses the column names provided. If the array's length is less than the booty array's length it reverts to :humanize =>'_'
38
- # check the source to see if there anything else hiding in there!
40
+ # check the source to see if there anything else hiding in there! There are a few new options in the 4.0.0 release, which are as yet undocumented.
39
41
 
40
42
  The create method has the same parameters, and actually creates the CSV.
41
43
 
@@ -110,6 +112,8 @@ What's the simplest thing that will work?
110
112
 
111
113
  == Usage without ActiveRecord
112
114
 
115
+ [ See Spec Tests for more Examples! ]
116
+
113
117
  Since the defaults assume an active record class you need to override some of them:
114
118
 
115
119
  class Star
@@ -199,7 +203,7 @@ Assuming a Make (as in manufacturers of automobiles) model like this:
199
203
  :bury_treasure => true # Boolean: Should the array of objects in :swag be stored in the CsvPirate object for later inspection?
200
204
  :blackjack => {:humanize => '-'} # Hash: Specify how you want your CSV header
201
205
  # {:join => '-'} joins the method names called to get hte data for that column with '_' underscores.
202
- # {:humanize => '-'} first joins as above, then humanizes the string
206
+ # {:humanize => '-'} first joins as above, then humanizes the string (this is the default)
203
207
  # {:array => ['col1',col2','col3'] Uses the column names provided in the array. If the array provided is too short defaults to :humanize =>'_'
204
208
 
205
209
  # A customized version to create a tab delimited file for this class might look like this:
@@ -324,13 +328,20 @@ You have the same Make class as above, and you have a MakeController:
324
328
  class MakeController < ApplicationController
325
329
  def download_csv
326
330
  csv_pirate = Make.blindfold
327
- send_data csv_pirate.maroon,
328
- :type => 'text/csv; charset=iso-8859-1; header=present',
329
- :disposition => "attachment; filename=#{csv_pirate.nocturnal}"
331
+
332
+ # maroon saves the read to the file system, by using the text of the csv stored in the CsvPirate object.
333
+ send_data csv_pirate.maroon, ...
334
+ :type => 'text/csv; charset=iso-8859-1; header=present',
335
+ :disposition => "attachment; filename=#{csv_pirate.nocturnal}"
336
+
337
+ # However if CSVs are created using multiple CsvPirate objects that all append to a single file,
338
+ # we need to read the final product from the fs.
339
+ #send_file csv_pirate.brigantine,
340
+ # :type => 'text/csv; charset=utf-8; header=present',
341
+ # :disposition => "attachment; filename=#{csv_pirate.nocturnal}"
330
342
  end
331
343
  end
332
344
 
333
-
334
345
  == Advanced Example with Nested Methods
335
346
 
336
347
  You have a VehicleModel class and the same Make class as up above:
@@ -399,6 +410,14 @@ This allows you to modify the csv_pirate object before creating the csv like thi
399
410
  csv_pirate.booty -= [:id, :name]
400
411
  csv_pirate.hoist_mainstay()
401
412
 
413
+ == Tests
414
+
415
+ The tests are run with rspec. The test suite is expanding. Currently there is ample coverage of basic functionality.
416
+
417
+ To run tests cd to where ever you have csv_pirate installed, and do:
418
+
419
+ rake spec
420
+
402
421
  == BUGS (Not mine, Micrsoft's)
403
422
 
404
423
  Microsoft Office (Excel) "SYLK Invalid Format" Error will occur if the string "ID" (without quotes)
data/Rakefile CHANGED
@@ -4,8 +4,8 @@ begin
4
4
  require 'jeweler'
5
5
  Jeweler::Tasks.new do |gemspec|
6
6
  gemspec.name = "csv_pirate"
7
- gemspec.summary = "Easily create CSVs of any data that can be derived from your models (using pirates!)."
8
- gemspec.description = %q{CsvPirate is the easy way to create a CSV of essentially anything in Rails, in full pirate regalia.
7
+ gemspec.summary = "Easily create CSVs of any data that can be derived from instance methods on your classes."
8
+ gemspec.description = %q{CsvPirate is the easy way to create a CSV of essentially anything in Ruby, in full pirate regalia.
9
9
  It works better if you are wearing a tricorne!}
10
10
  gemspec.email = "peter.boling@gmail.com"
11
11
  gemspec.homepage = "http://github.com/pboling/csv_pirate"
@@ -18,6 +18,12 @@ It works better if you are wearing a tricorne!}
18
18
  "install.rb",
19
19
  "lib/csv_pirate.rb",
20
20
  "lib/ninth_bit/pirate_ship.rb",
21
+ "spec/csv_pirate_spec.rb",
22
+ "spec/pirate_ship_spec.rb",
23
+ "spec/spec.opts",
24
+ "spec/spec_helper.rb",
25
+ "spec/spec_helpers/glowing_gas_ball.rb",
26
+ "spec/spec_helpers/star.rb",
21
27
  "Rakefile",
22
28
  "LICENSE",
23
29
  "CHANGELOG",
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- :minor: 4
3
- :patch: 4
4
- :major: 3
2
+ :patch: 1
3
+ :major: 4
4
+ :minor: 0
5
5
  :build:
data/csv_pirate.gemspec CHANGED
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{csv_pirate}
8
- s.version = "3.4.4"
8
+ s.version = "4.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Peter Boling"]
12
- s.date = %q{2009-11-10}
13
- s.description = %q{CsvPirate is the easy way to create a CSV of essentially anything in Rails, in full pirate regalia.
12
+ s.date = %q{2010-01-15}
13
+ s.description = %q{CsvPirate is the easy way to create a CSV of essentially anything in Ruby, in full pirate regalia.
14
14
  It works better if you are wearing a tricorne!}
15
15
  s.email = %q{peter.boling@gmail.com}
16
16
  s.extra_rdoc_files = [
@@ -28,16 +28,25 @@ It works better if you are wearing a tricorne!}
28
28
  "install.rb",
29
29
  "lib/csv_pirate.rb",
30
30
  "lib/ninth_bit/pirate_ship.rb",
31
- "rails/init.rb"
31
+ "rails/init.rb",
32
+ "spec/csv_pirate_spec.rb",
33
+ "spec/pirate_ship_spec.rb",
34
+ "spec/spec.opts",
35
+ "spec/spec_helper.rb",
36
+ "spec/spec_helpers/glowing_gas_ball.rb",
37
+ "spec/spec_helpers/star.rb"
32
38
  ]
33
39
  s.homepage = %q{http://github.com/pboling/csv_pirate}
34
40
  s.rdoc_options = ["--charset=UTF-8"]
35
41
  s.require_paths = ["lib"]
36
42
  s.rubygems_version = %q{1.3.5}
37
- s.summary = %q{Easily create CSVs of any data that can be derived from your models (using pirates!).}
43
+ s.summary = %q{Easily create CSVs of any data that can be derived from instance methods on your classes.}
38
44
  s.test_files = [
39
45
  "spec/csv_pirate_spec.rb",
40
- "spec/spec_helper.rb"
46
+ "spec/pirate_ship_spec.rb",
47
+ "spec/spec_helper.rb",
48
+ "spec/spec_helpers/glowing_gas_ball.rb",
49
+ "spec/spec_helpers/star.rb"
41
50
  ]
42
51
 
43
52
  if s.respond_to? :specification_version then
data/init.rb CHANGED
@@ -1,9 +1 @@
1
- require 'csv_pirate'
2
- require 'ninth_bit/pirate_ship'
3
-
4
- # If you are using this on a vanilla Ruby class (no rails or active record) then extend your class like this:
5
- # MyClass.send(:extend, NinthBit::PirateShip::ActMethods) if defined?(MyClass)
6
- # Alternatively you can do this inside your class definition:
7
- # class MyClass
8
- # extend NinthBit::PirateShip::ActMethods
9
- # end
1
+ require 'rails/init'
data/lib/csv_pirate.rb CHANGED
@@ -7,12 +7,12 @@
7
7
  #Version: 1.0
8
8
  #Project owners:
9
9
  # peter.boling (The Cap'n)
10
- require 'faster_csv' unless defined?(FasterCSV)
11
10
 
12
11
  class CsvPirate
13
12
 
14
13
  BOOKIE = [:counter, :timestamp, :none]
15
14
  MOP_HEADS = [:clean, :dirty]
15
+ BRIGANTINE = [:first, :last]
16
16
 
17
17
  attr_accessor :waggoner # First part of filename
18
18
  attr_accessor :chart # directory, default is (['log','csv'])
@@ -52,7 +52,11 @@ class CsvPirate
52
52
  # {:humanize => '-'} first joins as above, then humanizes the string
53
53
  # {:array => ['col1',col2','col3'] Uses the column names provided in the array. If the array provided is too short defaults to :humanize =>'_'
54
54
 
55
- cattr_accessor :parlay # verbosity on a scale of 0 - 3 (0=:none, 1=:error, 2=:info, 3=:debug, 0 being no screen output, 1 is default
55
+ attr_accessor :brigantine # the complete file path
56
+ attr_accessor :pinnacle # the complete file path
57
+ class << self
58
+ attr_accessor :parlay # verbosity on a scale of 0 - 3 (0=:none, 1=:error, 2=:info, 3=:debug, 0 being no screen output, 1 is default
59
+ end
56
60
 
57
61
  # CsvPirate only works for commissions of swag OR grub!
58
62
  # :swag the ARrr collection of swag to work on (optional)
@@ -81,15 +85,15 @@ class CsvPirate
81
85
  # See README for examples
82
86
 
83
87
  def initialize(*args)
84
- raise ArgumentError, "must provide required options" if args.blank?
88
+ raise ArgumentError, "must provide required options" if args.nil?
85
89
 
86
90
  @swag = args.first[:swag]
87
91
  @grub = args.first[:grub]
88
92
 
89
93
  # if they provide both
90
- raise ArgumentError, "must provide either :swag or :grub, not both" if !self.swag.blank? && !self.grub.blank?
94
+ raise ArgumentError, "must provide either :swag or :grub, not both" if !self.swag.nil? && !self.grub.nil?
91
95
  # if they provide neither
92
- raise ArgumentError, "must provide either :swag or :grub" if self.swag.blank? && self.grub.blank?
96
+ raise ArgumentError, "must provide either :swag or :grub" if self.swag.nil? && self.grub.nil?
93
97
 
94
98
  @swab = args.first[:swab] || :counter
95
99
  raise ArgumentError, ":swab is #{self.swab.inspect}, but must be one of #{CsvPirate::BOOKIE.inspect}" unless CsvPirate::BOOKIE.include?(self.swab)
@@ -103,16 +107,17 @@ class CsvPirate
103
107
  @waggoner = args.first[:waggoner] || "#{self.grub || self.swag}"
104
108
  raise ArgumentError, ":waggoner is #{self.waggoner.inspect}, and must be a string at least one character long" if self.waggoner.nil? || self.waggoner.length < 1
105
109
 
106
- @booty = args.first[:booty] || []
110
+ @booty = args.first[:booty] || [] # would like to use Class#instance_variables for generic classes
107
111
  raise ArgumentError, ":booty is #{self.booty.inspect}, and must be an array of methods to call on a class for CSV data" if self.booty.nil? || !self.booty.is_a?(Array) || self.booty.empty?
108
112
 
109
113
  @chart = args.first[:chart] || ['log','csv']
110
114
  raise ArgumentError, ":chart is #{self.chart.inspect}, and must be an array of directory names, which will become the filepath for the csv file" if self.chart.nil? || !self.chart.is_a?(Array) || self.chart.empty?
111
115
 
112
116
  @aft = args.first[:aft] || '.csv'
113
- @chronometer = args.first[:chronometer] == false ? false : args.first[:chronometer] || Date.today
117
+ @chronometer = args.first[:chronometer] == false ? false : (args.first[:chronometer] || Date.today)
118
+
119
+ @spyglasses = (args.first[:spyglasses] || (self.respond_to?(:all) ? [:all] : nil)) if self.grub
114
120
 
115
- @spyglasses = (args.first[:spyglasses] || [:all]) if self.grub
116
121
  @shrouds = args.first[:shrouds] || ',' # for tsv, tab-delimited, "\t"
117
122
  raise ArgumentError, ":shrouds is #{self.shrouds.inspect}, and must be a string (e.g. ',' or '\t'), which will be used as the delimeter for the csv file" if self.shrouds.nil? || !self.shrouds.is_a?(String)
118
123
 
@@ -121,8 +126,8 @@ class CsvPirate
121
126
  @bury_treasure = args.first[:astrolabe] || false
122
127
  @buried_treasure = []
123
128
 
124
- #Default is different than default for has_csv_pirate because this might gem wants to be clean for use outside rails, and humanize may not always be defined for String class
125
- @blackjack = args.first[:blackjack] || {:join => '_'}
129
+ #does not rely on rails humanize!
130
+ @blackjack = args.first[:blackjack] || {:humanize => '_'}
126
131
 
127
132
  #Make sure the header array is the same length as the booty columns
128
133
  if self.blackjack.keys.first == :array && (self.blackjack.values.first.length != self.booty.length)
@@ -130,7 +135,9 @@ class CsvPirate
130
135
  puts "Warning: :blackjack reset to {:join => '_'} because the length of the :booty is different than the length of the array provided to :blackjack" if CsvPirate.parlance(2)
131
136
  end
132
137
 
133
- # Initialize doesn't write anything to a CSV,
138
+ @pinnacle = self.block_and_tackle
139
+
140
+ # Initialize doesn't write anything to a CSV,
134
141
  # but does create the traverse_board and opens the waggoner for reading / writing
135
142
  self.northwest_passage unless self.astrolabe
136
143
 
@@ -140,10 +147,13 @@ class CsvPirate
140
147
  # Once the traverse_board (dir) exists, then check if the rhumb_lines (file) already exists, and set our rhumb_lines counter
141
148
  @swabbie = self.insult_swabbie
142
149
 
143
- @nocturnal = File.basename(self.poop_deck)
150
+ @brigantine = self.poop_deck(args.first[:brigantine])
151
+
152
+ @nocturnal = File.basename(self.brigantine)
153
+
144
154
 
145
155
  # Then open the rhumb_lines
146
- self.rhumb_lines = File.open(File.expand_path(self.poop_deck),self.astrolabe ? "r" : "a")
156
+ self.rhumb_lines = File.open(File.expand_path(self.brigantine),self.astrolabe ? "r" : "a")
147
157
  end
148
158
 
149
159
  def self.create(*args)
@@ -234,7 +244,7 @@ class CsvPirate
234
244
  def jolly_roger
235
245
  if self.bury_treasure
236
246
  if self.buried_treasure.is_a?(Array)
237
- puts "Found #{self.buried_treasure.length} deniers buried here: '#{self.poop_deck}'" if CsvPirate.parlay && CsvPirate.parlance(1)
247
+ puts "Found #{self.buried_treasure.length} deniers buried here: '#{self.brigantine}'" if CsvPirate.parlay && CsvPirate.parlance(1)
238
248
  puts "You must weigh_anchor to review your plunder!" if CsvPirate.parlay && CsvPirate.parlance(1)
239
249
  else
240
250
  puts "Failed to locate treasure" if CsvPirate.parlay && CsvPirate.parlance(1)
@@ -252,35 +262,6 @@ class CsvPirate
252
262
  end
253
263
  end
254
264
 
255
- # create the header of the CSV (column/method names)
256
- # returns an array of strings for CSV header based on blackjack
257
- def block_and_tackle
258
- self.blackjack.map do |k,v|
259
- case k
260
- #Joining is only relevant when the booty contains a nested hash of method calls as at least one of the booty array elements
261
- #Use the booty (methods) as the column headers
262
- when :join then self.binnacle(v, false)
263
- #Use the humanized booty (methods) as the column headers
264
- when :humanize then self.binnacle(v, true)
265
- when :array then v
266
- end
267
- end.first
268
- end
269
-
270
- #returns an array of strings for CSV header based on booty
271
- def binnacle(join_value, humanize = true)
272
- self.booty.map do |compass|
273
- string = compass.is_a?(Hash) ?
274
- self.run_through(compass, join_value) :
275
- compass.is_a?(String) ?
276
- compass :
277
- compass.is_a?(Symbol) ?
278
- compass.to_s :
279
- compass.to_s
280
- humanize ? string.humanize : string
281
- end
282
- end
283
-
284
265
  #Takes a potentially nested hash element of a booty array and turns it into a string for a column header
285
266
  # hash = {:a => {:b => {:c => {:d => {"e" => "fghi"}}}}}
286
267
  # run_through(hash, '_')
@@ -297,30 +278,102 @@ class CsvPirate
297
278
  end
298
279
 
299
280
  #complete file path
300
- def poop_deck
301
- "#{self.analemma}#{self.swabbie}#{self.aft}"
281
+ def poop_deck(brig)
282
+ if BRIGANTINE.include?(brig)
283
+ self.old_csv_dump(brig)
284
+ elsif brig.is_a?(String)
285
+ "#{self.analemma}#{brig}"
286
+ else
287
+ "#{self.analemma}#{self.swabbie}#{self.aft}"
288
+ end
302
289
  end
303
290
 
304
- # Swabs the poop_deck if the mop is clean. (!)
291
+ # Swabs the poop_deck (of the brigantine) if the mop is clean. (!)
305
292
  def swab_poop_deck
306
- self.rhumb_lines.truncate(0) if self.swab == :none && self.mop == :clean && File.size(self.poop_deck) > 0
293
+ self.rhumb_lines.truncate(0) if self.swab == :none && self.mop == :clean && File.size(self.brigantine) > 0
307
294
  end
308
295
 
309
296
  # Must be done on order to rummage through the loot found by the pirate ship
310
297
  def weigh_anchor
311
- CsvPirate.rinse(self.poop_deck)
298
+ CsvPirate.rinse(self.brigantine)
312
299
  end
313
300
 
314
301
  # Sink your own ship! Or run a block of code on each row of the current CSV
315
302
  def scuttle(&block)
316
303
  return false unless block_given?
317
- CsvPirate.broadside(self.poop_deck) do |careen|
304
+ CsvPirate.broadside(self.brigantine) do |careen|
318
305
  yield careen
319
306
  end
320
307
  end
321
308
 
309
+ def to_memory(exclude_id = true, exclude_timestamps = true)
310
+ return nil unless self.grub
311
+ begin
312
+ example = self.grub.new
313
+ rescue Exception
314
+ puts "cannot instantiate instance of #{self.grub} with #{self.grub}.new. CsvPirate#to_memory works most reliably when #{self.grub}.new works with no arguments." if CsvPirate.parlance(1)
315
+ example = nil
316
+ end
317
+ buccaneers = []
318
+ self.scuttle do |row|
319
+ #puts "#{self.pinnacle.first.inspect} #{row[self.pinnacle.first].inspect}"
320
+ buccaneers << self.grub.new(self.data_hash_from_row(row, exclude_id, exclude_timestamps, example))
321
+ end
322
+ buccaneers
323
+ end
324
+
325
+ def data_hash_from_row(row, exclude_id = true, exclude_timestamps = true, example = nil)
326
+ data_hash = {}
327
+ my_booty = self.booty.reject {|x| x.is_a?(Hash)}
328
+ my_booty = exclude_id ? my_booty.reject {|x| a = x.to_sym; [:id, :ID,:dbid, :DBID, :db_id, :DB_ID].include?(a)} : self.booty
329
+ my_booty = exclude_timestamps ? my_booty.reject {|x| a = x.to_sym; [:created_at, :updated_at, :created_on, :updated_on].include?(a)} : self.booty
330
+ my_booty = my_booty.reject {|x| !example.respond_to?("#{x}=".to_sym)} unless example.nil?
331
+ my_booty.each do |method|
332
+ #puts "#{self.pinnacle[index]}"
333
+ data_hash = data_hash.merge({method => row[self.pinnacle[self.booty.index(method)]]})
334
+ end
335
+ #puts "#{data_hash.inspect}"
336
+ data_hash
337
+ end
338
+
339
+ # Grab an old CSV dump (first or last)
340
+ def old_csv_dump(brig)
341
+ file = Dir.entries(self.traverse_board).reject {|x| x.match(/^\./)}.sort.send(brig)
342
+ "#{self.traverse_board}#{file}"
343
+ end
344
+
322
345
  protected
323
346
 
347
+ # create the header of the CSV (column/method names)
348
+ # returns an array of strings for CSV header based on blackjack
349
+ def block_and_tackle
350
+ self.blackjack.map do |k,v|
351
+ case k
352
+ #Joining is only relevant when the booty contains a nested hash of method calls as at least one of the booty array elements
353
+ #Use the booty (methods) as the column headers
354
+ when :join then self.binnacle(v, false)
355
+ #Use the humanized booty (methods) as the column headers
356
+ when :humanize then self.binnacle(v, true)
357
+ when :array then v
358
+ end
359
+ end.first
360
+ end
361
+
362
+ #returns an array of strings for CSV header based on booty
363
+ def binnacle(join_value, humanize = true)
364
+ self.booty.map do |compass|
365
+ string = compass.is_a?(Hash) ?
366
+ self.run_through(compass, join_value) :
367
+ compass.is_a?(String) ?
368
+ compass :
369
+ compass.is_a?(Symbol) ?
370
+ compass.to_s :
371
+ compass.to_s
372
+ humanize ? string.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize : string
373
+ end
374
+ end
375
+
376
+ # The directory path to the csv
324
377
  def traverse_board
325
378
  #If we have rails environment then we use rails root, otherwise self.chart stands on its own as a relative path
326
379
  "#{self.north_pole}#{self.chart.join('/')}/"
@@ -358,18 +411,21 @@ class CsvPirate
358
411
  index = base.rindex('.')
359
412
  tail = index.nil? ? nil : base[index+1,base.length]
360
413
  # Ensure numbers
361
- counter = tail.nil? ? 0 : tail[/\d*/].to_i
414
+ tail.nil? ? 0 : tail[/\d*/].to_i
362
415
  end
363
-
416
+
417
+ # Get all the files in the dir
418
+ def axe
419
+ Dir.glob(self.lantern)
420
+ end
421
+
422
+ # File increment for next CSV to dump
364
423
  def boatswain
365
424
  return self.swabbie unless self.swabbie.nil?
366
- counter = 0
367
- bowspirit = Dir.glob(self.lantern)
368
425
  highval = 0
369
- bowspirit.each do |flotsam|
426
+ self.axe.each do |flotsam|
370
427
  counter = self.filibuster(flotsam)
371
428
  highval = ((highval <=> counter) == 1) ? highval : counter
372
- counter = 0
373
429
  end
374
430
  ".#{highval + 1}"
375
431
  end
@@ -409,7 +465,7 @@ class CsvPirate
409
465
  spoils = spoils.send(east.to_sym)
410
466
  unless spoils.nil?
411
467
  if west.is_a?(Hash)
412
- # Recursive nadness is here!
468
+ # Recursive madness is here!
413
469
  spoils = CsvPirate.marlinespike(spoils, west)
414
470
  else
415
471
  spoils = spoils.send(west.to_sym)
@@ -431,9 +487,7 @@ class CsvPirate
431
487
  # Sink other ships! Or run a block of code on each row of a CSV
432
488
  def self.broadside(galley, &block)
433
489
  return false unless block_given?
434
- count = 1 if report_kills
435
490
  FasterCSV.foreach(galley, {:headers => :first_row, :return_headers => false}) do |gun|
436
- puts "Galleys sunk: #{count+=1}" if CsvPirate.parlance(1)
437
491
  yield gun
438
492
  end
439
493
  end
@@ -11,15 +11,16 @@ module NinthBit
11
11
  options[:chart] ||= ['log','csv']
12
12
  options[:aft] ||= '.csv'
13
13
  options[:gibbet] ||= '.export'
14
- #Needs to be defined at runtime, doesn't make sense here
15
- #options[:chronometer] ||= Date.today
14
+ #Needs to be defined at runtime, doesn't make sense here unless set to false, except to be overridden at runtime
15
+ # Default is nil so that the CsvPirate default will kick-in.
16
+ options[:chronometer] ||= nil
16
17
  options[:waggoner] ||= "#{self}"
17
18
  options[:swag] ||= nil
18
19
  options[:swab] ||= :counter
19
20
  options[:mop] ||= :clean
20
21
  options[:shrouds] ||= ','
21
22
  options[:grub] ||= self if options[:swag].nil?
22
- options[:spyglasses] ||= [:all]
23
+ options[:spyglasses] ||= (self.respond_to?(:all) ? [:all] : nil) if options[:grub]
23
24
  # Have to protect against model definitions pre-migration, since column names will fail if
24
25
  options[:booty] ||= check_booty ? self.column_names : []
25
26
  options[:bury_treasure] ||= true
@@ -27,9 +28,9 @@ module NinthBit
27
28
  options[:parlay] ||= 1
28
29
 
29
30
  # if they provide both
30
- raise ArgumentError, "must provide either :swag or :grub, not both" if !options[:swag].blank? && !options[:grub].blank?
31
+ raise ArgumentError, "must provide either :swag or :grub, not both" if !options[:swag].nil? && !options[:grub].nil?
31
32
  # if they provide neither
32
- raise ArgumentError, "must provide either :swag or :grub" if options[:swag].blank? && options[:grub].blank?
33
+ raise ArgumentError, "must provide either :swag or :grub" if options[:swag].nil? && options[:grub].nil?
33
34
  raise ArgumentError, ":swab is #{options[:swab].inspect}, but must be one of #{CsvPirate::BOOKIE.inspect}" unless CsvPirate::BOOKIE.include?(options[:swab])
34
35
  raise ArgumentError, ":mop is #{options[:mop].inspect}, but must be one of #{CsvPirate::MOP_HEADS.inspect}" unless CsvPirate::MOP_HEADS.include?(options[:mop])
35
36
  raise ArgumentError, ":gibbet is #{options[:gibbet].inspect}, and does not contain a '.' character, which is required when using iterative filenames (set :swab => :none to turn off iterative filenames)" if options[:swab] != :none && (options[:gibbet].nil? || !options[:gibbet].include?('.'))
@@ -41,6 +42,10 @@ module NinthBit
41
42
 
42
43
  extend ClassMethods unless (class << self; included_modules; end).include?(ClassMethods)
43
44
 
45
+ class << self
46
+ attr_accessor :piratey_options
47
+ end
48
+
44
49
  self.piratey_options = options
45
50
 
46
51
  end
@@ -58,10 +63,6 @@ module NinthBit
58
63
 
59
64
  module ClassMethods
60
65
 
61
- def self.extended(base)
62
- base.class_inheritable_accessor :piratey_options
63
- end
64
-
65
66
  # intended for use with send_data for downloading the text of the csv:
66
67
  # send_data Make.say_your_last_words
67
68
  # TODO: Fix say_your_last_words so it works! Use send_data args for real
@@ -103,6 +104,29 @@ module NinthBit
103
104
  CsvPirate.new(self.piratey_args(args))
104
105
  end
105
106
 
107
+ def weigh_anchor(args = {})
108
+ pargs = self.piratey_args(args)
109
+ pargs.merge!({
110
+ :gibbet => '.dump',
111
+ :chart => pargs[:chart] + ["dumps"],
112
+ })
113
+ CsvPirate.create(pargs)
114
+ end
115
+
116
+ def raise_anchor(args = {})
117
+ pargs = self.piratey_args(args)
118
+ pargs.merge!({
119
+ :chart => pargs[:chart] + ["dumps"],
120
+ :brigantine => :last
121
+ })
122
+ csv_pirate = CsvPirate.new(pargs)
123
+
124
+ csv_pirate.to_memory.map do |obj|
125
+ obj.save(false) if obj.respond_to?(:save)
126
+ obj
127
+ end
128
+ end
129
+
106
130
  protected
107
131
 
108
132
  def piratey_args(args = {})
@@ -110,7 +134,7 @@ module NinthBit
110
134
  return { :chart => args[:chart] || self.piratey_options[:chart],
111
135
  :aft => args[:aft] || self.piratey_options[:aft],
112
136
  :gibbet => args[:gibbet] || self.piratey_options[:gibbet],
113
- :chronometer => args[:chronometer] == false ? false : args[:chronometer] || Date.today,
137
+ :chronometer => get_chronometer(args[:chronometer]),
114
138
  :waggoner => args[:waggoner] || self.piratey_options[:waggoner] || "#{self}",
115
139
  :swag => args[:swag] || self.piratey_options[:swag],
116
140
  :swab => args[:swab] || self.piratey_options[:swab],
@@ -123,6 +147,14 @@ module NinthBit
123
147
  :bury_treasure => args[:bury_treasure] || self.piratey_options[:bury_treasure] }
124
148
  end
125
149
 
150
+ def get_chronometer(chron)
151
+ chron == false ?
152
+ false :
153
+ (chron || (self.piratey_options[:chronometer] == false ?
154
+ false :
155
+ (self.piratey_options[:chronometer] || Date.today)))
156
+ end
157
+
126
158
  end
127
159
 
128
160
  end
data/rails/init.rb CHANGED
@@ -1,4 +1,11 @@
1
- require 'faster_csv'
1
+ begin
2
+ require 'rubygems'
3
+ gem 'fastercsv'
4
+ rescue LoadError
5
+ "Unable to load dependencies: rubygems or fastercsv"
6
+ end
7
+
8
+ require 'faster_csv' unless defined?(FasterCSV)
2
9
  require 'csv_pirate'
3
10
  require 'ninth_bit/pirate_ship'
4
11
 
@@ -1,7 +1,195 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
3
  describe "CsvPirate" do
4
- it "fails" do
5
- fail "hey buddy, you should probably rename this file and start specing for real"
4
+ describe "#initialize" do
5
+ before(:each) do
6
+ @csv_pirate = CsvPirate.new({
7
+ :grub => GlowingGasBall,
8
+ :spyglasses => [:get_stars],
9
+ :chart => ["spec","csv","GlowingGasBall"],
10
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
11
+ :chronometer => false,
12
+ :gibbet => "",
13
+ :aft => ".csv",
14
+ :swab => :none,
15
+ :mop => :clean,
16
+ :waggoner => 'data'
17
+ })
18
+ end
19
+
20
+ it "should return an instance of CsvPirate" do
21
+ @csv_pirate.class.should == CsvPirate
22
+ end
23
+
24
+ it "should not export anything" do
25
+ @csv_pirate.maroon.should == ""
26
+ end
6
27
  end
28
+
29
+ describe "#create" do
30
+ before(:each) do
31
+ @csv_pirate = CsvPirate.create({
32
+ :grub => GlowingGasBall,
33
+ :spyglasses => [:get_stars],
34
+ :chart => ["spec","csv","GlowingGasBall"],
35
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
36
+ :chronometer => false,
37
+ :gibbet => "",
38
+ :aft => ".csv",
39
+ :swab => :none,
40
+ :mop => :clean,
41
+ :waggoner => 'data'
42
+ })
43
+ end
44
+
45
+ it "should return an instance of CsvPirate" do
46
+ @csv_pirate.class.should == CsvPirate
47
+ end
48
+
49
+ it "should store export in maroon instance variable" do
50
+ @csv_pirate.maroon.should == "Name,Distance,Spectral type,Name hash,Name next,Name upcase,Star vowels\nProxima Centauri,4.2 LY,M5.5Vc,-1176188012,Proxima Centaurj,PROXIMA CENTAURI,Pr*x*m* C*nt**r*\nRigil Kentaurus,4.3 LY,G2V,1916094624,Rigil Kentaurut,RIGIL KENTAURUS,R*g*l K*nt**r*s\nBarnard's Star,5.9 LY,M3.8V,1003964756,Barnard's Stas,BARNARD'S STAR,B*rn*rd's St*r\nWolf 359,7.7 LY,M5.8Vc,-1717989858,Wolf 360,WOLF 359,W*lf 359\nLalande 21185,8.26 LY,M2V,466625069,Lalande 21186,LALANDE 21185,L*l*nd* 21185\nLuyten 726-8A and B,8.73 LY,M5.5 de & M6 Ve,1260790153,Luyten 726-8A and C,LUYTEN 726-8A AND B,L*yt*n 726-8A *nd B\nSirius A and B,8.6 LY,A1Vm,1177502705,Sirius A and C,SIRIUS A AND B,S*r**s A *nd B\nRoss 154,9.693 LY,M3.5,2120976706,Ross 155,ROSS 154,R*ss 154\nRoss 248,10.32 LY,M5.5V,2129428738,Ross 249,ROSS 248,R*ss 248\nEpsilon Eridani,10.5 LY,K2V,931307088,Epsilon Eridanj,EPSILON ERIDANI,Eps*l*n Er*d*n*\n"
51
+ end
52
+ end
53
+
54
+ describe "#hoist_mainstay" do
55
+ before(:each) do
56
+ @csv_pirate = CsvPirate.new({
57
+ :grub => GlowingGasBall,
58
+ :spyglasses => [:get_stars],
59
+ :chart => ["spec","csv","GlowingGasBall"],
60
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
61
+ :chronometer => false,
62
+ :gibbet => "",
63
+ :aft => ".csv",
64
+ :swab => :none,
65
+ :mop => :clean,
66
+ :waggoner => 'data'
67
+ })
68
+ end
69
+
70
+ it "should return an instance of String" do
71
+ @csv_pirate.hoist_mainstay.class.should == String
72
+ end
73
+
74
+ it "should return the export as a string" do
75
+ @csv_pirate.hoist_mainstay.should == "Name,Distance,Spectral type,Name hash,Name next,Name upcase,Star vowels\nProxima Centauri,4.2 LY,M5.5Vc,-1176188012,Proxima Centaurj,PROXIMA CENTAURI,Pr*x*m* C*nt**r*\nRigil Kentaurus,4.3 LY,G2V,1916094624,Rigil Kentaurut,RIGIL KENTAURUS,R*g*l K*nt**r*s\nBarnard's Star,5.9 LY,M3.8V,1003964756,Barnard's Stas,BARNARD'S STAR,B*rn*rd's St*r\nWolf 359,7.7 LY,M5.8Vc,-1717989858,Wolf 360,WOLF 359,W*lf 359\nLalande 21185,8.26 LY,M2V,466625069,Lalande 21186,LALANDE 21185,L*l*nd* 21185\nLuyten 726-8A and B,8.73 LY,M5.5 de & M6 Ve,1260790153,Luyten 726-8A and C,LUYTEN 726-8A AND B,L*yt*n 726-8A *nd B\nSirius A and B,8.6 LY,A1Vm,1177502705,Sirius A and C,SIRIUS A AND B,S*r**s A *nd B\nRoss 154,9.693 LY,M3.5,2120976706,Ross 155,ROSS 154,R*ss 154\nRoss 248,10.32 LY,M5.5V,2129428738,Ross 249,ROSS 248,R*ss 248\nEpsilon Eridani,10.5 LY,K2V,931307088,Epsilon Eridanj,EPSILON ERIDANI,Eps*l*n Er*d*n*\n"
76
+ end
77
+
78
+ it "should store export in maroon instance variable" do
79
+ @csv_pirate.maroon.should == ""
80
+ @csv_pirate.hoist_mainstay
81
+ @csv_pirate.maroon.should == "Name,Distance,Spectral type,Name hash,Name next,Name upcase,Star vowels\nProxima Centauri,4.2 LY,M5.5Vc,-1176188012,Proxima Centaurj,PROXIMA CENTAURI,Pr*x*m* C*nt**r*\nRigil Kentaurus,4.3 LY,G2V,1916094624,Rigil Kentaurut,RIGIL KENTAURUS,R*g*l K*nt**r*s\nBarnard's Star,5.9 LY,M3.8V,1003964756,Barnard's Stas,BARNARD'S STAR,B*rn*rd's St*r\nWolf 359,7.7 LY,M5.8Vc,-1717989858,Wolf 360,WOLF 359,W*lf 359\nLalande 21185,8.26 LY,M2V,466625069,Lalande 21186,LALANDE 21185,L*l*nd* 21185\nLuyten 726-8A and B,8.73 LY,M5.5 de & M6 Ve,1260790153,Luyten 726-8A and C,LUYTEN 726-8A AND B,L*yt*n 726-8A *nd B\nSirius A and B,8.6 LY,A1Vm,1177502705,Sirius A and C,SIRIUS A AND B,S*r**s A *nd B\nRoss 154,9.693 LY,M3.5,2120976706,Ross 155,ROSS 154,R*ss 154\nRoss 248,10.32 LY,M5.5V,2129428738,Ross 249,ROSS 248,R*ss 248\nEpsilon Eridani,10.5 LY,K2V,931307088,Epsilon Eridanj,EPSILON ERIDANI,Eps*l*n Er*d*n*\n"
82
+ end
83
+ end
84
+
85
+ describe "#old_csv_dump" do
86
+
87
+ before(:each) do
88
+ ["1/1/1998","2/2/2002","1/2/2003","3/2/2001","2/1/2007"].map {|x| Date.parse(x)}.each do |date|
89
+ @csv_pirate = CsvPirate.new({
90
+ :grub => GlowingGasBall,
91
+ :spyglasses => [:get_stars],
92
+ :chart => ["spec","csv","GlowingGasBall","dumps"],
93
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
94
+ :chronometer => date,
95
+ :swab => :none,
96
+ :mop => :clean
97
+ })
98
+ @csv_pirate.hoist_mainstay
99
+ end
100
+ end
101
+
102
+ it "should find first (oldest) dump" do
103
+ @new_csv_pirate = CsvPirate.new({
104
+ :grub => GlowingGasBall,
105
+ :spyglasses => [:get_stars],
106
+ :chart => ["spec","csv","GlowingGasBall","dumps"],
107
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
108
+ :chronometer => false,
109
+ :brigantine => :first,
110
+ :swab => :none,
111
+ :mop => :clean
112
+ })
113
+ @new_csv_pirate.brigantine.should == "spec/csv/GlowingGasBall/dumps/GlowingGasBall.19980101.export.csv"
114
+ end
115
+
116
+ it "should find last (newest) dump" do
117
+ @new_csv_pirate = CsvPirate.new({
118
+ :grub => GlowingGasBall,
119
+ :spyglasses => [:get_stars],
120
+ :chart => ["spec","csv","GlowingGasBall","dumps"],
121
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
122
+ :chronometer => false,
123
+ :brigantine => :last,
124
+ :swab => :none,
125
+ :mop => :clean
126
+ })
127
+ @new_csv_pirate.brigantine.should == "spec/csv/GlowingGasBall/dumps/GlowingGasBall.20070201.export.csv"
128
+ end
129
+ end
130
+
131
+ describe "#to_memory" do
132
+
133
+ before(:each) do
134
+ ["1/1/1998","2/2/2002","1/2/2003","3/2/2001","2/1/2007"].map {|x| Date.parse(x)}.each do |date|
135
+ @csv_pirate = CsvPirate.new({
136
+ :grub => GlowingGasBall,
137
+ :spyglasses => [:get_stars],
138
+ :chart => ["spec","csv","GlowingGasBall","dumps"],
139
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
140
+ :chronometer => date,
141
+ :swab => :none,
142
+ :mop => :clean
143
+ })
144
+ @csv_pirate.hoist_mainstay
145
+ end
146
+ end
147
+
148
+ it "should return an array of 10 grubs built from data in CSV" do
149
+ @new_csv_pirate = CsvPirate.new({
150
+ :grub => GlowingGasBall,
151
+ :spyglasses => [:get_stars],
152
+ :chart => ["spec","csv","GlowingGasBall","dumps"],
153
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
154
+ :chronometer => false,
155
+ :brigantine => :last,
156
+ :swab => :none,
157
+ :mop => :clean
158
+ })
159
+ @new_csv_pirate.brigantine.should == "spec/csv/GlowingGasBall/dumps/GlowingGasBall.20070201.export.csv"
160
+ @new_csv_pirate.to_memory.class.should == Array
161
+ @new_csv_pirate.to_memory.length.should == 10
162
+ end
163
+ end
164
+
165
+ describe ":blackjack option" do
166
+ before(:each) do
167
+ @csv_pirate = CsvPirate.new({
168
+ :grub => GlowingGasBall,
169
+ :spyglasses => [:get_stars],
170
+ :chart => ["spec","csv","GlowingGasBall"],
171
+ :booty => [:name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
172
+ :chronometer => false,
173
+ :gibbet => "",
174
+ :aft => ".csv",
175
+ :swab => :none,
176
+ :mop => :clean,
177
+ :waggoner => 'data'
178
+ })
179
+ end
180
+
181
+ it "should be {humanize => '_'} by default" do
182
+ @csv_pirate.blackjack.should == {:humanize => '_'}
183
+ @csv_pirate.hoist_mainstay
184
+ @csv_pirate.maroon.should == "Name,Distance,Spectral type,Name hash,Name next,Name upcase,Star vowels\nProxima Centauri,4.2 LY,M5.5Vc,-1176188012,Proxima Centaurj,PROXIMA CENTAURI,Pr*x*m* C*nt**r*\nRigil Kentaurus,4.3 LY,G2V,1916094624,Rigil Kentaurut,RIGIL KENTAURUS,R*g*l K*nt**r*s\nBarnard's Star,5.9 LY,M3.8V,1003964756,Barnard's Stas,BARNARD'S STAR,B*rn*rd's St*r\nWolf 359,7.7 LY,M5.8Vc,-1717989858,Wolf 360,WOLF 359,W*lf 359\nLalande 21185,8.26 LY,M2V,466625069,Lalande 21186,LALANDE 21185,L*l*nd* 21185\nLuyten 726-8A and B,8.73 LY,M5.5 de & M6 Ve,1260790153,Luyten 726-8A and C,LUYTEN 726-8A AND B,L*yt*n 726-8A *nd B\nSirius A and B,8.6 LY,A1Vm,1177502705,Sirius A and C,SIRIUS A AND B,S*r**s A *nd B\nRoss 154,9.693 LY,M3.5,2120976706,Ross 155,ROSS 154,R*ss 154\nRoss 248,10.32 LY,M5.5V,2129428738,Ross 249,ROSS 248,R*ss 248\nEpsilon Eridani,10.5 LY,K2V,931307088,Epsilon Eridanj,EPSILON ERIDANI,Eps*l*n Er*d*n*\n"
185
+ end
186
+
187
+ it "should work as {:join => '_'}" do
188
+ @csv_pirate.blackjack = {:join => '_'}
189
+ @csv_pirate.blackjack.should == {:join => '_'}
190
+ @csv_pirate.hoist_mainstay
191
+ @csv_pirate.maroon.should == "name,distance,spectral_type,name_hash,name_next,name_upcase,star_vowels\nProxima Centauri,4.2 LY,M5.5Vc,-1176188012,Proxima Centaurj,PROXIMA CENTAURI,Pr*x*m* C*nt**r*\nRigil Kentaurus,4.3 LY,G2V,1916094624,Rigil Kentaurut,RIGIL KENTAURUS,R*g*l K*nt**r*s\nBarnard's Star,5.9 LY,M3.8V,1003964756,Barnard's Stas,BARNARD'S STAR,B*rn*rd's St*r\nWolf 359,7.7 LY,M5.8Vc,-1717989858,Wolf 360,WOLF 359,W*lf 359\nLalande 21185,8.26 LY,M2V,466625069,Lalande 21186,LALANDE 21185,L*l*nd* 21185\nLuyten 726-8A and B,8.73 LY,M5.5 de & M6 Ve,1260790153,Luyten 726-8A and C,LUYTEN 726-8A AND B,L*yt*n 726-8A *nd B\nSirius A and B,8.6 LY,A1Vm,1177502705,Sirius A and C,SIRIUS A AND B,S*r**s A *nd B\nRoss 154,9.693 LY,M3.5,2120976706,Ross 155,ROSS 154,R*ss 154\nRoss 248,10.32 LY,M5.5V,2129428738,Ross 249,ROSS 248,R*ss 248\nEpsilon Eridani,10.5 LY,K2V,931307088,Epsilon Eridanj,EPSILON ERIDANI,Eps*l*n Er*d*n*\n"
192
+ end
193
+ end
194
+
7
195
  end
@@ -0,0 +1,69 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "PirateShip" do
4
+ describe "#walk_the_plank" do
5
+ before(:each) do
6
+ @csv_pirate = Star.walk_the_plank
7
+ end
8
+
9
+ it "should return a string" do
10
+ @csv_pirate.class.should == String
11
+ end
12
+ end
13
+
14
+ describe "#blindfold" do
15
+ before(:each) do
16
+ @csv_pirate = Star.blindfold
17
+ end
18
+
19
+ it "should return an instance of CsvPirate" do
20
+ @csv_pirate.class.should == CsvPirate
21
+ end
22
+ end
23
+
24
+ describe "#land_ho" do
25
+ before(:each) do
26
+ @csv_pirate = Star.land_ho
27
+ end
28
+
29
+ it "should return an instance of CsvPirate" do
30
+ @csv_pirate.class.should == CsvPirate
31
+ end
32
+ end
33
+
34
+ describe "#land_ho" do
35
+ before(:each) do
36
+ @csv_pirate = Star.land_ho
37
+ end
38
+
39
+ it "should return an instance of CsvPirate" do
40
+ @csv_pirate.class.should == CsvPirate
41
+ end
42
+ end
43
+
44
+ describe "#weigh_anchor" do
45
+ before(:each) do
46
+ @csv_pirate = Star.weigh_anchor({:chronometer => Date.parse("2/1/2007")})
47
+ end
48
+
49
+ it "should return an instance of CsvPirate" do
50
+ @csv_pirate.class.should == CsvPirate
51
+ @csv_pirate.chart.should == ["spec","csv","Star","dumps"]
52
+ end
53
+ end
54
+
55
+ describe "#raise_anchor" do
56
+ before(:each) do
57
+ @csv_pirate = Star.weigh_anchor({:chronometer => Date.parse("3/29/2002")})
58
+ @csv_pirate = Star.weigh_anchor({:chronometer => Date.parse("6/14/2004")})
59
+ @csv_pirate = Star.weigh_anchor({:chronometer => Date.parse("12/25/1962")})
60
+ @csv_pirate = Star.raise_anchor()
61
+ end
62
+
63
+ it "should return an array of 10 grubs built from data in CSV" do
64
+ @csv_pirate.class.should == Array
65
+ @csv_pirate.length.should == 10
66
+ end
67
+ end
68
+
69
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,7 @@
1
+ --colour
2
+ --format
3
+ specdoc
4
+ --loadby
5
+ mtime
6
+ --reverse
7
+ --backtrace
data/spec/spec_helper.rb CHANGED
@@ -2,8 +2,11 @@ require 'spec'
2
2
 
3
3
  $LOAD_PATH.unshift(File.dirname(__FILE__))
4
4
 
5
- require 'csv_pirate'
5
+ require 'init'
6
6
 
7
7
  Spec::Runner.configure do |config|
8
8
 
9
9
  end
10
+
11
+ # require all files inside spec_helpers
12
+ Dir[File.join(File.dirname(__FILE__), "spec_helpers/*.rb")].each { |file| require file }
@@ -0,0 +1,30 @@
1
+ class GlowingGasBall
2
+
3
+ attr_accessor :name, :distance, :spectral_type
4
+
5
+ def initialize(*args)
6
+ @name = args.first[:name]
7
+ @distance = args.first[:distance]
8
+ @spectral_type = args.first[:spectral_type]
9
+ end
10
+
11
+ def star_vowels
12
+ self.name.tr('aeiou', '*')
13
+ end
14
+
15
+ def self.get_stars
16
+ [
17
+ GlowingGasBall.new(:name => "Proxima Centauri", :distance => "4.2 LY", :spectral_type => "M5.5Vc"),
18
+ GlowingGasBall.new(:name => "Rigil Kentaurus", :distance => "4.3 LY", :spectral_type => "G2V"),
19
+ GlowingGasBall.new(:name => "Barnard's Star", :distance => "5.9 LY", :spectral_type => "M3.8V"),
20
+ GlowingGasBall.new(:name => "Wolf 359", :distance => "7.7 LY", :spectral_type => "M5.8Vc"),
21
+ GlowingGasBall.new(:name => "Lalande 21185", :distance => "8.26 LY", :spectral_type => "M2V"),
22
+ GlowingGasBall.new(:name => "Luyten 726-8A and B", :distance => "8.73 LY", :spectral_type => "M5.5 de & M6 Ve"),
23
+ GlowingGasBall.new(:name => "Sirius A and B", :distance => "8.6 LY", :spectral_type => "A1Vm"),
24
+ GlowingGasBall.new(:name => "Ross 154", :distance => "9.693 LY", :spectral_type => "M3.5"),
25
+ GlowingGasBall.new(:name => "Ross 248", :distance => "10.32 LY", :spectral_type => "M5.5V"),
26
+ GlowingGasBall.new(:name => "Epsilon Eridani", :distance => "10.5 LY", :spectral_type => "K2V")
27
+ ]
28
+ end
29
+
30
+ end
@@ -0,0 +1,29 @@
1
+ class Star < GlowingGasBall
2
+
3
+ extend NinthBit::PirateShip::ActMethods
4
+ has_csv_pirate_ship :booty => [ :name, :distance, :spectral_type, {:name => :hash}, {:name => :next}, {:name => :upcase}, :star_vowels ],
5
+ :spyglasses => [:get_stars],
6
+ :chart => ["spec","csv","Star"],
7
+ :chronometer => false,
8
+ :gibbet => "",
9
+ :aft => ".csv",
10
+ :swab => :none,
11
+ :mop => :clean,
12
+ :waggoner => 'data'
13
+
14
+ def self.get_stars
15
+ [
16
+ Star.new(:name => "Proxima Centauri", :distance => "4.2 LY", :spectral_type => "M5.5Vc"),
17
+ Star.new(:name => "Rigil Kentaurus", :distance => "4.3 LY", :spectral_type => "G2V"),
18
+ Star.new(:name => "Barnard's Star", :distance => "5.9 LY", :spectral_type => "M3.8V"),
19
+ Star.new(:name => "Wolf 359", :distance => "7.7 LY", :spectral_type => "M5.8Vc"),
20
+ Star.new(:name => "Lalande 21185", :distance => "8.26 LY", :spectral_type => "M2V"),
21
+ Star.new(:name => "Luyten 726-8A and B", :distance => "8.73 LY", :spectral_type => "M5.5 de & M6 Ve"),
22
+ Star.new(:name => "Sirius A and B", :distance => "8.6 LY", :spectral_type => "A1Vm"),
23
+ Star.new(:name => "Ross 154", :distance => "9.693 LY", :spectral_type => "M3.5"),
24
+ Star.new(:name => "Ross 248", :distance => "10.32 LY", :spectral_type => "M5.5V"),
25
+ Star.new(:name => "Epsilon Eridani", :distance => "10.5 LY", :spectral_type => "K2V")
26
+ ]
27
+ end
28
+
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv_pirate
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.4
4
+ version: 4.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-10 00:00:00 -05:00
12
+ date: 2010-01-15 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -23,7 +23,7 @@ dependencies:
23
23
  version: "0"
24
24
  version:
25
25
  description: |-
26
- CsvPirate is the easy way to create a CSV of essentially anything in Rails, in full pirate regalia.
26
+ CsvPirate is the easy way to create a CSV of essentially anything in Ruby, in full pirate regalia.
27
27
  It works better if you are wearing a tricorne!
28
28
  email: peter.boling@gmail.com
29
29
  executables: []
@@ -45,6 +45,12 @@ files:
45
45
  - lib/csv_pirate.rb
46
46
  - lib/ninth_bit/pirate_ship.rb
47
47
  - rails/init.rb
48
+ - spec/csv_pirate_spec.rb
49
+ - spec/pirate_ship_spec.rb
50
+ - spec/spec.opts
51
+ - spec/spec_helper.rb
52
+ - spec/spec_helpers/glowing_gas_ball.rb
53
+ - spec/spec_helpers/star.rb
48
54
  has_rdoc: true
49
55
  homepage: http://github.com/pboling/csv_pirate
50
56
  licenses: []
@@ -72,7 +78,10 @@ rubyforge_project:
72
78
  rubygems_version: 1.3.5
73
79
  signing_key:
74
80
  specification_version: 3
75
- summary: Easily create CSVs of any data that can be derived from your models (using pirates!).
81
+ summary: Easily create CSVs of any data that can be derived from instance methods on your classes.
76
82
  test_files:
77
83
  - spec/csv_pirate_spec.rb
84
+ - spec/pirate_ship_spec.rb
78
85
  - spec/spec_helper.rb
86
+ - spec/spec_helpers/glowing_gas_ball.rb
87
+ - spec/spec_helpers/star.rb