jgdavey-movable_erb 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/csv_spec.rb CHANGED
@@ -1,73 +1,322 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
2
 
2
- require File.join(File.dirname(__FILE__), %w[spec_helper])
3
+ TEMPLATE_FIXTURE = File.expand_path(File.dirname(__FILE__) + '/fixtures/template.erb')
4
+ CSV_FIXTURE = File.expand_path(File.dirname(__FILE__) + '/fixtures/example.csv')
3
5
 
4
- describe MovableErb::Csv do
5
- describe "intialization" do
6
+ describe MovableErb do
7
+ it "should have a CSV instance" do
8
+ m = MovableErb.new
9
+ m.csv = MovableErb::CSV.setup do |csv|
10
+ csv.filename = CSV_FIXTURE
11
+ end.should be_a(MovableErb::CSV)
12
+ end
13
+
14
+ it "should have an Erb instance" do
15
+ m = MovableErb.new
16
+ m.erb = MovableErb::Erb.setup do |erb|
17
+ true
18
+ end.should be_a(MovableErb::Erb)
19
+ end
6
20
 
21
+ context "#convert" do
7
22
  before(:each) do
8
- @csv = MovableErb::Csv.new({:file => 'example.csv'})
23
+ @m = MovableErb.new
24
+ end
25
+ it "should raise an error if it's missing a CSV and/or Erb instance" do
26
+ lambda { @m.convert }.should raise_error
9
27
  end
10
28
 
11
- it "should accept arguments" do
12
- @csv.should_not be_nil
29
+ it "should raise an error if it's CSV instance can't parse!" do
30
+ @m.erb = MovableErb::Erb.setup { |erb| erb.template = TEMPLATE_FIXTURE }
31
+ @m.csv = "Random string"
32
+ lambda { @m.convert }.should raise_error(NoMethodError, "undefined method `parse!' for \"Random string\":String")
13
33
  end
14
34
 
15
- it "should have @file attribute match passed in value" do
16
- @csv.file.should eql('./example.csv')
35
+ it "should raise an error if it's missing an Erb instance" do
36
+ String.any_instance.stubs(:data=).returns('')
37
+ @m.csv = MovableErb::CSV.setup { |csv| csv.filename = CSV_FIXTURE }
38
+ @m.erb = "Random string"
39
+ lambda { @m.convert }.should raise_error(NoMethodError, "undefined method `build!' for \"Random string\":String")
17
40
  end
18
-
19
- it "should allow files in sub-folders" do
20
- @csv = MovableErb::Csv.new({:file => 'subfolder/example.csv'})
21
- @csv.file.should eql('./subfolder/example.csv')
41
+
42
+ it "should convert the CSV to a string with the Erb template" do
43
+ @m.csv = MovableErb::CSV.setup { |csv| csv.filename = CSV_FIXTURE }
44
+ @m.erb = MovableErb::Erb.setup { |erb| erb.template = TEMPLATE_FIXTURE }
45
+ @m.separator = "\n"
46
+ @m.convert.should == <<-ERB.gsub(/^ +/, "")
47
+ Name: John
48
+ Email: john@example.com
49
+
50
+ Name: Abigail
51
+ Email: abby@example.com
52
+
53
+ Name: Bernard
54
+
55
+ Name: Casius
56
+ ERB
22
57
  end
23
-
24
- it "should recognize the dot as current folder" do
25
- @csv = MovableErb::Csv.new({:file => './example.csv'})
26
- @csv.file.should eql('./example.csv')
58
+ end
59
+
60
+ context "initilization" do
61
+ it "should take a hash of options" do
62
+ m = MovableErb.new({:hash => 'of options'})
63
+ m.should be_a(MovableErb)
27
64
  end
28
65
 
66
+ it "should set the template file" do
67
+ m = MovableErb.new({ :template => TEMPLATE_FIXTURE })
68
+ m.erb.template.should == File.read(TEMPLATE_FIXTURE)
69
+ end
70
+
71
+ it "should set the csv file" do
72
+ m = MovableErb.new({ :csv => CSV_FIXTURE })
73
+ m.csv.filename.should == CSV_FIXTURE
74
+ end
75
+
76
+ it "should set a separator if given" do
77
+ m = MovableErb.new({ :separator => ', ' })
78
+ m.separator.should == ', '
79
+ end
29
80
  end
30
81
 
31
- describe "opening the file" do
82
+ context "full-on run-through" do
83
+ it "should work!" do
84
+ movable_erb = MovableErb.new({
85
+ :csv => File.expand_path(File.dirname(__FILE__) + '/fixtures/advanced.csv'),
86
+ :separator => ''
87
+ })
88
+ movable_erb.convert.should == <<-ERB.gsub(/^ +/, "")
89
+ TITLE: Hambone
90
+ CATEGORY: Silly
91
+ CATEGORY: Blah
92
+ -----
93
+ BODY:
94
+
95
+ This is the content for hambone
96
+
97
+ --------
98
+ TITLE: WillyNilly
99
+ -----
100
+ BODY:
101
+
102
+ More body
103
+
104
+ --------
105
+ ERB
106
+ end
107
+ end
108
+ end
109
+
110
+ describe MovableErb::CSV do
111
+ it "should be an instance of itself" do
112
+ MovableErb::CSV.new.should be_a(MovableErb::CSV)
113
+ end
114
+
115
+ describe "setup" do
32
116
  before(:each) do
33
- @file_to_open = File.join(File.dirname(__FILE__), 'fixtures', 'example.csv')
34
- @csv = MovableErb::Csv.new({:file => @file_to_open})
117
+ @csv = MovableErb::CSV.new
35
118
  end
36
119
 
37
- it "should find the file" do
38
- File.open(@file_to_open).should_not be_nil
120
+ it "should setup with a block" do
121
+ @csv.setup {|csv| false }.should == @csv
39
122
  end
40
123
 
41
- it "should populate rows" do
42
- @csv.rows.should_not be_nil
124
+ it "should accept a file argument" do
125
+ FasterCSV.stubs(:read).returns([])
126
+ @csv.setup do |csv|
127
+ csv.filename = "test.csv"
128
+ end.should == @csv
129
+ end
130
+
131
+ it "should call parse if filename given in block" do
132
+ @csv.expects(:parse!).returns('')
133
+ @csv.setup { |csv| csv.filename = "test.csv" }
134
+ end
135
+
136
+ it "should not call parse if filename not given in block" do
137
+ @csv.expects(:parse!).never
138
+ @csv.setup { |csv| false }
139
+ end
140
+
141
+ context "shortcut setup class method" do
142
+ before(:each) do
143
+ MovableErb::CSV.any_instance.stubs(:filename).returns("fake")
144
+ FasterCSV.stubs(:read).returns([])
145
+ end
146
+
147
+ it "should create a new instance" do
148
+ MovableErb::CSV.setup do |csv|
149
+ csv.should be_a(MovableErb::CSV)
150
+ end
151
+ end
152
+
153
+ it "should return the new instance" do
154
+ MovableErb::CSV.setup { |csv| @instance = csv }.should == @instance
155
+ end
156
+
157
+ it "should return the new instance (2)" do
158
+ MovableErb::CSV.setup do |csv|
159
+ @instance = csv
160
+ 'fakey fake string'
161
+ end.should == @instance
162
+ end
163
+
164
+ it "should raise an error if no block given" do
165
+ lambda { MovableErb::CSV.setup }.should raise_error('no block given')
166
+ end
167
+
168
+ it "should call parse!" do
169
+ MovableErb::CSV.any_instance.expects(:parse!)
170
+ MovableErb::CSV.setup { |csv| true }
171
+ end
43
172
  end
44
173
  end
45
-
46
- describe "rows" do
174
+
175
+ describe "parsing" do
47
176
  before(:each) do
48
- @file_to_open = File.join(File.dirname(__FILE__), 'fixtures', 'example.csv')
49
- @csv = MovableErb::Csv.new({:file => @file_to_open})
177
+ FasterCSV.stubs(:read).returns([["row1"], ["row2"]])
178
+ @csv = MovableErb::CSV.new
179
+ @csv.filename = "test.csv"
180
+ end
181
+
182
+ it "#parse! should return self" do
183
+ @csv.parse!.should == @csv
184
+ end
185
+
186
+ it "#parse! should modify attribute hashes (via to_hashes)" do
187
+ @csv.expects(:to_hashes)
188
+ @csv.parse!
50
189
  end
51
190
 
52
- it "should be an array of arrays" do
53
- @csv.rows.should be_instance_of(Array)
54
- @csv.rows.each do |row|
55
- row.should be_instance_of(Array)
191
+ context "#to_hashes" do
192
+ it "should read from file" do
193
+ FasterCSV.expects(:read).with("test.csv").returns([[]])
194
+ @csv.to_hashes
195
+ end
196
+
197
+ it "should return an array of hashes (1 rows, 1 column)" do
198
+ @csv.to_hashes.should == [{'row1' => ['row2']}]
199
+ end
200
+
201
+ it "should downcase the header row" do
202
+ FasterCSV.stubs(:read).returns([["Name"],["Billy Bob"]])
203
+ @csv.to_hashes.should == [{'name' => ['Billy Bob']}]
204
+ end
205
+
206
+ it "should convert the header row to snake_case" do
207
+ FasterCSV.stubs(:read).returns([["Extended Body"],["Billy Bob"]])
208
+ @csv.to_hashes.should == [{'extended_body' => ['Billy Bob']}]
209
+ end
210
+
211
+ it "should return an array of hashes (3 rows, 3 columns)" do
212
+ FasterCSV.stubs(:read).returns([["Name", "Phone", "Email"],
213
+ ["John", "773-123-1234", "john@example.com"],
214
+ ["Abigail", nil, "abby@example.com"],
215
+ ["Casius", nil, nil]])
216
+ @csv.to_hashes.should == [
217
+ {'name' => ['John'], 'phone' => ['773-123-1234'], 'email' => ['john@example.com'] },
218
+ {'name' => ['Abigail'], 'email' => ['abby@example.com'] },
219
+ {'name' => ['Casius'],}
220
+ ]
221
+ end
222
+
223
+ it "should collect values with the same key" do
224
+ FasterCSV.stubs(:read).returns([["Name", "Name", "Email"], ["John", "James", "john@example.com"]])
225
+ @csv.to_hashes.should == [{'name' => ['John', 'James'],'email' => ['john@example.com']}]
226
+ end
227
+
228
+ it "should collect values with the same key (more than 2)" do
229
+ FasterCSV.stubs(:read).returns([["Name", "Name", "Name"], ["John", "James", "Jill"]])
230
+ @csv.to_hashes.should == [{'name' => ['John', 'James', 'Jill']}]
56
231
  end
57
232
  end
233
+ end
234
+ end
58
235
 
59
- it "should have a header row" do
60
- @csv.header.should eql(['Name','Phone','Email'])
236
+ describe MovableErb::Erb do
237
+ context "initializing" do
238
+ it "should initialize with a template file" do
239
+ MovableErb::Erb.new.should be_a(MovableErb::Erb)
61
240
  end
241
+ end
62
242
 
63
- it "should exclude header from data" do
64
- @csv.data.first.should_not eql(['Name','Phone','Email'])
243
+ context "loading a template" do
244
+ it "template setter should load a file into @template" do
245
+ File.expects(:read).with("filename.erb").returns("This is a template")
246
+ @erb = MovableErb::Erb.new
247
+ @erb.template = 'filename.erb'
248
+ @erb.template.should == 'This is a template'
65
249
  end
66
-
67
- it "should should have data" do
68
- @csv.data.first.should eql(['John','773-123-1234','john@example.com'])
250
+ end
251
+
252
+ context "data hash" do
253
+ it "should accept a data hash" do
254
+ @erb = MovableErb::Erb.new
255
+ @erb.data = {'these' => 'params'}
256
+ @erb.data.should == {'these' => 'params'}
69
257
  end
70
258
  end
71
- end
72
259
 
73
- # EOF
260
+ context "setting up with block" do
261
+ before(:each) do
262
+ @erb = MovableErb::Erb.new
263
+ end
264
+
265
+ it "should accept a block that yields itself" do
266
+ @erb.setup do |erb|
267
+ erb.should == @erb
268
+ end
269
+ end
270
+ end
271
+
272
+ context "shortcut setup class method" do
273
+ it "should create a new instance" do
274
+ MovableErb::Erb.setup do |erb|
275
+ erb.should be_a(MovableErb::Erb)
276
+ end
277
+ end
278
+
279
+ it "should return the new instance" do
280
+ MovableErb::Erb.setup { |erb| @instance = erb }.should == @instance
281
+ end
282
+
283
+ it "should return the new instance (2)" do
284
+ MovableErb::Erb.setup do |erb|
285
+ @instance = erb
286
+ 'fakey fake string'
287
+ end.should == @instance
288
+ end
289
+
290
+ it "should raise an error if no block given" do
291
+ lambda { MovableErb::Erb.setup }.should raise_error('no block given')
292
+ end
293
+ end
294
+
295
+ context "#build!" do
296
+ before(:each) do
297
+ @erb = MovableErb::Erb.new
298
+ end
299
+
300
+ it "should create a new ERB instance with @template" do
301
+ @erb.stubs(:template).returns("string")
302
+ ERB.expects(:new)
303
+ @erb.build!
304
+ end
305
+
306
+ it "should set @parsed_string" do
307
+ @erb.stubs(:template).returns("string")
308
+ @erb.build!
309
+ @erb.parsed_string.should_not be_nil
310
+ end
311
+
312
+ it "should parse a template with data given" do
313
+ @erb.template = TEMPLATE_FIXTURE
314
+ @erb.data = {'name' => 'Johnny', 'email' => 'john@example.com'}
315
+ @erb.build!
316
+ @erb.parsed_string.should == <<-ERB.gsub(/^\s+/,'')
317
+ Name: Johnny
318
+ Email: john@example.com
319
+ ERB
320
+ end
321
+ end
322
+ end
@@ -0,0 +1,3 @@
1
+ Title,Body,Category,Category
2
+ Hambone,This is the content for hambone,Silly,Blah
3
+ WillyNilly,More body,,
@@ -0,0 +1,4 @@
1
+ Name: <%= data['name'] %>
2
+ <% if data['email'] %>
3
+ Email: <%= data['email'] %>
4
+ <% end %>
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --diff u
data/spec/spec_helper.rb CHANGED
@@ -1,18 +1,7 @@
1
1
  require 'rubygems'
2
- require 'fastercsv'
3
2
 
4
- require File.expand_path(
5
- File.join(File.dirname(__FILE__), %w[.. lib movable_erb]))
3
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib movable_erb]))
6
4
 
7
5
  Spec::Runner.configure do |config|
8
- # == Mock Framework
9
- #
10
- # RSpec uses it's own mocking framework by default. If you prefer to
11
- # use mocha, flexmock or RR, uncomment the appropriate line:
12
- #
13
- # config.mock_with :mocha
14
- # config.mock_with :flexmock
15
- # config.mock_with :rr
6
+ config.mock_with :mocha
16
7
  end
17
-
18
- # EOF
data/tasks/rspec.rake ADDED
@@ -0,0 +1,11 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ namespace :spec do
4
+ desc "Run all examples with RCov"
5
+ Spec::Rake::SpecTask.new('rcov') do |t|
6
+ t.spec_files = FileList['spec']
7
+ t.spec_opts << ["--color"]
8
+ t.rcov = true
9
+ t.rcov_opts = ['--exclude', 'spec/,tasks/,coverage/,features/,/System/,/Library/']
10
+ end
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jgdavey-movable_erb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Davey
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-18 00:00:00 -07:00
12
+ date: 2009-09-26 00:00:00 -07:00
13
13
  default_executable: movable_erb
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -23,47 +23,72 @@ dependencies:
23
23
  version: "0"
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
- name: bones
26
+ name: trollop
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
27
37
  type: :development
28
38
  version_requirement:
29
39
  version_requirements: !ruby/object:Gem::Requirement
30
40
  requirements:
31
41
  - - ">="
32
42
  - !ruby/object:Gem::Version
33
- version: 2.5.0
43
+ version: "0"
34
44
  version:
35
- description: "Usage: movable_erb [options]"
45
+ description: A General-purpose CSV to ERB template formatter
36
46
  email: josh@joshuadavey.com
37
47
  executables:
38
48
  - movable_erb
39
49
  extensions: []
40
50
 
41
51
  extra_rdoc_files:
42
- - History.txt
52
+ - CHANGELOG
53
+ - LICENSE
54
+ - README.md
43
55
  - bin/movable_erb
44
- - lib/movable_erb/templates/default.erb
56
+ - lib/movable_erb.rb
57
+ - lib/templates/mtimport.erb
58
+ - tasks/rspec.rake
45
59
  files:
46
- - History.txt
47
- - README.textile
60
+ - CHANGELOG
61
+ - LICENSE
62
+ - README.md
48
63
  - Rakefile
49
64
  - bin/movable_erb
65
+ - cucumber.yml
66
+ - features/csv.feature
67
+ - features/step_definitions/csv_steps.rb
68
+ - features/step_definitions/tmp.csv
69
+ - features/support/env.rb
50
70
  - lib/movable_erb.rb
51
- - lib/movable_erb/csv.rb
52
- - lib/movable_erb/mtimport.rb
53
- - lib/movable_erb/templates/default.erb
54
- - movable_erb.gemspec
71
+ - lib/templates/mtimport.erb
55
72
  - spec/csv_spec.rb
73
+ - spec/fixtures/advanced.csv
56
74
  - spec/fixtures/example.csv
57
- - spec/movable_erb_spec.rb
58
- - spec/mtimport_spec.rb
75
+ - spec/fixtures/template.erb
76
+ - spec/spec.opts
59
77
  - spec/spec_helper.rb
60
- - test/test_movable_erb.rb
61
- has_rdoc: true
62
- homepage: http://github.com/jgdavey/movable_erb/
78
+ - tasks/rspec.rake
79
+ - Manifest
80
+ - movable_erb.gemspec
81
+ has_rdoc: false
82
+ homepage: http://github.com/jgdavey/movable_erb
83
+ licenses:
63
84
  post_install_message:
64
85
  rdoc_options:
86
+ - --line-numbers
87
+ - --inline-source
88
+ - --title
89
+ - Movable_erb
65
90
  - --main
66
- - README.textile
91
+ - README.md
67
92
  require_paths:
68
93
  - lib
69
94
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -76,14 +101,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
101
  requirements:
77
102
  - - ">="
78
103
  - !ruby/object:Gem::Version
79
- version: "0"
104
+ version: "1.2"
80
105
  version:
81
106
  requirements: []
82
107
 
83
108
  rubyforge_project: movable_erb
84
- rubygems_version: 1.2.0
109
+ rubygems_version: 1.3.5
85
110
  signing_key:
86
111
  specification_version: 3
87
- summary: A simple CSV to MTImport conversion utility
88
- test_files:
89
- - test/test_movable_erb.rb
112
+ summary: A General-purpose CSV to ERB template formatter
113
+ test_files: []
114
+
data/History.txt DELETED
@@ -1,4 +0,0 @@
1
- == 0.1.0 / 2009-04-03
2
-
3
- * 1 major enhancement
4
- * Birthday!
@@ -1,30 +0,0 @@
1
- require 'rubygems'
2
- require 'fastercsv'
3
-
4
- module MovableErb
5
- class Csv
6
- attr_reader :file
7
- def initialize(args)
8
- if args[:file]
9
- args[:file].gsub!(/^([^\.\/])/,'./\1')
10
- @file = args[:file]
11
- end
12
- end
13
-
14
- def rows
15
- FasterCSV.read(file)
16
- end
17
-
18
- def header
19
- rows.first
20
- end
21
-
22
- def data
23
- rows[1..rows.length]
24
- end
25
-
26
- def body
27
- data
28
- end
29
- end
30
- end
@@ -1,65 +0,0 @@
1
- module MovableErb
2
- class MTImport
3
- require 'erb'
4
-
5
- COLUMNNAMES = ['title','body','extended', 'category', 'tags']
6
-
7
- attr_accessor :csv, :template, :columns
8
-
9
- def initialize(args = {})
10
- if args[:csv]
11
- @csv = Csv.new(args[:csv])
12
- @columns = {:body => nil, :title => nil}
13
- end
14
- @template = args[:template] || File.join(File.dirname(__FILE__), 'templates', 'default.erb')
15
- end
16
-
17
- def header_rows
18
- if @csv
19
- @csv.header
20
- else
21
- raise "No CSV file"
22
- end
23
- end
24
-
25
- def setup_column_nums
26
- COLUMNNAMES.each do |colname|
27
- @columns[colname.to_sym] = header_rows.to_enum(:each_with_index).collect do |x,i|
28
- i if x.downcase == colname
29
- end.compact
30
- end
31
- # Useful defaults
32
- @columns[:title] = [0] if @columns[:title].empty?
33
- @columns[:body] = [1] if @columns[:body].empty?
34
- @columns
35
- end
36
-
37
- def column_nums_for(column)
38
- @columns[column.to_sym]
39
- end
40
-
41
- def content_for(column, row = 0)
42
- content = column_nums_for(column).map do |i|
43
- csv.body[row][i]
44
- end
45
- end
46
-
47
-
48
- def render_with_template(template = @template)
49
- rendered = []
50
- csv.body.each_with_index do |row, i|
51
- title = content_for('title', i).join(" ")
52
- body = content_for('body', i).join("\n")
53
- extended = content_for('extended', i).join("\n")
54
- category = content_for('category', i).join(" ")
55
- tags = content_for('tags', i).join(", ")
56
- erb = File.open(template, "rb").read
57
- r = ERB.new(erb, 0, '<>') if erb
58
- b = binding
59
- rendered << r.result(b)
60
- end
61
- rendered.join("--------\n")
62
- end
63
-
64
- end
65
- end
@@ -1,21 +0,0 @@
1
- TITLE: <%= title %>
2
- <% if category && !category.empty? %>
3
- CATEGORY: <%= category %>
4
- <% end %>
5
- <% if tags && !tags.empty? %>
6
- TAGS: <%= tags %>
7
- <% end %>
8
- -----
9
- BODY:
10
-
11
- <%= body %>
12
-
13
-
14
- <% unless extended.nil? || extended.empty? %>
15
- -----
16
- EXTENDED:
17
-
18
- <%= extended %>
19
-
20
-
21
- <% end %>
@@ -1,10 +0,0 @@
1
-
2
- require File.join(File.dirname(__FILE__), %w[spec_helper])
3
-
4
- describe MovableErb do
5
- it "should have class Csv" do
6
- MovableErb::Csv.should_not be_nil
7
- end
8
- end
9
-
10
- # EOF