movable_erb 0.2.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 ADDED
@@ -0,0 +1,5 @@
1
+ v0.2.1 Fixing bug with CLI tool when no filename given
2
+
3
+ v0.2.0 Complete rework from ground up. Old API is deprecated.
4
+
5
+ v0.1.3 First working version on Github
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ == The MIT License
2
+
3
+ Copyright (c) 2009
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,21 @@
1
+ CHANGELOG
2
+ LICENSE
3
+ Manifest
4
+ README.rdoc
5
+ Rakefile
6
+ bin/movable_erb
7
+ cucumber.yml
8
+ features/csv.feature
9
+ features/step_definitions/csv_steps.rb
10
+ features/step_definitions/tmp.csv
11
+ features/support/env.rb
12
+ lib/movable_erb.rb
13
+ lib/templates/mtimport.erb
14
+ movable_erb.gemspec
15
+ spec/csv_spec.rb
16
+ spec/fixtures/advanced.csv
17
+ spec/fixtures/example.csv
18
+ spec/fixtures/template.erb
19
+ spec/spec.opts
20
+ spec/spec_helper.rb
21
+ tasks/rspec.rake
data/README.rdoc ADDED
@@ -0,0 +1,75 @@
1
+ = Movable Erb
2
+
3
+ by Joshua Davey
4
+ http://github.com/jgdavey/movable_erb
5
+
6
+ == Description
7
+
8
+ A simple CSV to MTImport conversion utility.
9
+ Useful for mapping contacts data into individual entries in Movable Type.
10
+
11
+ MTImport format is simple enough that most blogging platforms can import it, so this utility could ease the pain of moving some older data structure in CSV format into a blog platform.
12
+
13
+ == Requirements
14
+
15
+ * fastercsv gem
16
+
17
+ == Installation
18
+
19
+ [sudo] gem install jgdavey-movable_erb
20
+
21
+ == Usage
22
+
23
+ MovableErb uses the header names in the first row of
24
+ the CSV file to map to each of the mtimport’s values:
25
+ Title, Body, Extended, Category, and Tags.
26
+
27
+ So, a CSV file that looks like:
28
+ Title,Body,Extended
29
+ Title of a Post,Body content (can include html, etc),Extended content
30
+
31
+ will become:
32
+ TITLE: Title of a Post
33
+ -----
34
+ BODY:
35
+
36
+ Body content (can include html, etc)
37
+
38
+ -----
39
+ EXTENDED:
40
+
41
+ Extended content
42
+
43
+ You can even specify more than one header column as Title, Body, etc.,
44
+ and they will be combined into one entity, joined by:
45
+ * a comma for one-line attributes (title, author), or
46
+ * a newline for multi-line (Body, Extended)
47
+
48
+ === Commandline usage
49
+ After installing the gem, just run
50
+
51
+ movable_erb [options] yourfile.csv
52
+
53
+
54
+ == The MIT License
55
+
56
+ Copyright (c) 2009
57
+
58
+ Permission is hereby granted, free of charge, to any person obtaining
59
+ a copy of this software and associated documentation files (the
60
+ 'Software'), to deal in the Software without restriction, including
61
+ without limitation the rights to use, copy, modify, merge, publish,
62
+ distribute, sublicense, and/or sell copies of the Software, and to
63
+ permit persons to whom the Software is furnished to do so, subject to
64
+ the following conditions:
65
+
66
+ The above copyright notice and this permission notice shall be
67
+ included in all copies or substantial portions of the Software.
68
+
69
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
70
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
71
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
72
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
73
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
74
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
75
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('movable_erb') do |p|
6
+ p.description = "A General-purpose CSV to ERB template formatter"
7
+ p.url = "http://github.com/jgdavey/movable_erb"
8
+ p.author = "Joshua Davey"
9
+ p.email = "josh@joshuadavey.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*", "coverage/*"]
11
+ p.development_dependencies = ['rspec']
12
+ p.executable_pattern = ["bin/*"]
13
+ p.runtime_dependencies = ["fastercsv", "trollop"]
14
+ end
15
+
16
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
17
+
data/bin/movable_erb ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pp'
3
+ require 'rubygems'
4
+ require 'trollop'
5
+
6
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib movable_erb]))
7
+
8
+ DEFAULT_TEMPLATE = File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib templates mtimport.erb]))
9
+
10
+ opts = Trollop::options do
11
+
12
+ version "MovableErb v#{MovableErb::VERSION} (c) 2009 Joshua Davey"
13
+ banner <<-EOS
14
+ Usage:
15
+
16
+ movable_erb [options] <filenames.csv>
17
+
18
+ Options:
19
+
20
+ EOS
21
+
22
+ # Options
23
+ opt :separator, "Separator between records", :default => "", :short => '-s'
24
+ opt :template, "path to ERB template", :default => DEFAULT_TEMPLATE, :short => '-t'
25
+
26
+ # Show the help screen when no file given
27
+ educate if ARGV.empty?
28
+
29
+ # Only continue if the CSV file is found
30
+ Trollop::die "That file could not be found" unless ARGV.first && File.exist?(ARGV.first)
31
+ end
32
+
33
+ # Paths for CSV files are left in ARGV
34
+ ARGV.each do |csv|
35
+ opts.merge!(:csv => csv)
36
+ puts MovableErb.new(opts).convert
37
+ end
data/cucumber.yml ADDED
@@ -0,0 +1 @@
1
+ default: --tags ~wip features
@@ -0,0 +1,40 @@
1
+ Feature: CSV Conversion
2
+ In order to convert my list of contacts to blog format
3
+ As a Command-line user
4
+ I want to use commandline utility to convert CSV files to MTImport files
5
+
6
+ Scenario: A short CSV of contacts
7
+ Given I am on the commandline
8
+ When I invoke the utility with the following CSV file:
9
+ """
10
+ Title,Body,Body
11
+ John,773-123-1234,john@example.com
12
+ Abigail,,abby@example.com
13
+ Bernard,903-294-3921,
14
+ """
15
+ Then I should see the following output:
16
+ """
17
+ TITLE: John
18
+ -----
19
+ BODY:
20
+
21
+ 773-123-1234
22
+ john@example.com
23
+
24
+ --------
25
+ TITLE: Abigail
26
+ -----
27
+ BODY:
28
+
29
+ abby@example.com
30
+
31
+ --------
32
+ TITLE: Bernard
33
+ -----
34
+ BODY:
35
+
36
+ 903-294-3921
37
+
38
+ --------
39
+
40
+ """
@@ -0,0 +1,14 @@
1
+ Given /^I am on the commandline$/ do
2
+ # dummy step
3
+ end
4
+
5
+ When /^I invoke the utility with the following CSV file:?$/ do |string|
6
+ File.open(File.dirname(__FILE__) + '/tmp.csv', 'w') {|f| f.write(string) }
7
+ puts FasterCSV.parse(string).inspect
8
+ @erb = MovableErb.new({:csv => File.dirname(__FILE__) + '/tmp.csv', :separator => ''})
9
+ end
10
+
11
+ Then /^I should see the following output:?$/ do |string|
12
+ puts @erb.csv.to_hashes.inspect
13
+ @erb.convert.should == string
14
+ end
@@ -0,0 +1,4 @@
1
+ Title,Body,Body
2
+ John,773-123-1234,john@example.com
3
+ Abigail,,abby@example.com
4
+ Bernard,903-294-3921,
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. .. lib movable_erb]))
5
+
6
+ require "mocha"
7
+
8
+ World(Mocha::API)
9
+
10
+ Before do
11
+ mocha_setup
12
+ end
13
+
14
+ After do
15
+ begin
16
+ mocha_verify
17
+ ensure
18
+ mocha_teardown
19
+ end
20
+ end
@@ -0,0 +1,129 @@
1
+ # @author Joshua Davey
2
+ # @version 0.2.4
3
+ class MovableErb
4
+ VERSION = "0.2.4"
5
+ attr_accessor :csv, :erb, :separator
6
+
7
+ DEFAULT_TEMPLATE = File.expand_path(File.dirname(__FILE__) + '/templates/mtimport.erb')
8
+
9
+ ##
10
+ # @param [Hash] options
11
+ # @option options [String] :template ("mtimport.erb") Path to the ERB template file to use
12
+ # @option options [String] :csv <b>Required.</b> Path to the CSV file to convert
13
+ # @option options [String] :separator ("") Defaults to empty String, ""
14
+ def initialize(options = {})
15
+ @erb = MovableErb::Erb.setup do |erb|
16
+ erb.template = options[:template] || DEFAULT_TEMPLATE
17
+ end
18
+ if options[:csv]
19
+ @csv = MovableErb::CSV.setup do |csv|
20
+ csv.filename = options[:csv]
21
+ end
22
+ end
23
+ @separator = options[:separator] || ""
24
+ end
25
+
26
+ ##
27
+ # Converts each row of the CSV file and collects it into @results
28
+ # @return [String] parsed results joined by the separator
29
+ def convert
30
+ @results = []
31
+ csv.parse!
32
+ csv.hashes.each do |hash_data|
33
+ erb.data = hash_data
34
+ @results << erb.build!
35
+ end
36
+ @results.join(separator)
37
+ end
38
+ end
39
+
40
+ ##
41
+ # Loads a CSV document into an array of hashes
42
+ class MovableErb::CSV
43
+ require 'fastercsv'
44
+
45
+ attr_accessor :filename, :hashes
46
+
47
+ ##
48
+ # Initializes and yields a new instance
49
+ # @yield [csv] a new instance of {MovableErb::CSV}
50
+ # @return [MovableErb::CSV]
51
+ def self.setup(&block)
52
+ csv = self.new
53
+ yield csv
54
+ csv.parse!
55
+ end
56
+
57
+ ##
58
+ # Internally calls {#to_hashes}, but returns self
59
+ # @see to_hashes
60
+ # @return [MovableErb::CSV] self
61
+ def parse!
62
+ @hashes = self.to_hashes
63
+ self
64
+ end
65
+
66
+ ##
67
+ # Reads the CSV file into an array of hashes
68
+ # @return [Array] an Array of Hashes
69
+ def to_hashes
70
+ array_of_arrays = FasterCSV.read(filename)
71
+ headers = array_of_arrays.shift
72
+ headers.each { |h| h.downcase! && h.gsub!(/\s/,"_") } if headers
73
+ hashes = Array.new(array_of_arrays.length) { Hash.new }
74
+ array_of_arrays.each_with_index do |row,i|
75
+ headers.each_with_index do |header, j|
76
+ unless row[j].nil?
77
+ hashes[i][header] = [] if hashes[i][header].nil?
78
+ hashes[i][header] << row[j]
79
+ end
80
+ end
81
+ end
82
+ hashes
83
+ end
84
+ end
85
+
86
+ ##
87
+ # Convenience class to setup and parse data with an ERB template.
88
+ class MovableErb::Erb
89
+ require 'erb'
90
+
91
+ attr_accessor :template, :parsed_string, :data
92
+
93
+ ##
94
+ # Creates a new instance and allow manipulation of it via block.
95
+ #
96
+ # This can be used to initialize and parse quickly.
97
+ #
98
+ # @yield [erb] a new instance of {MovableErb::Erb}
99
+ #
100
+ # @example Create a new instance, setup and build the template
101
+ # @erb = MovableErb::Erb.setup do |erb|
102
+ # erb.data = {'hash' => 'of', 'meaningful' => 'values'}
103
+ # erb.template = "path/to/template.erb"
104
+ # erb.build!
105
+ # end
106
+ # @return [MovableErb::Erb]
107
+ def self.setup
108
+ erb = self.new
109
+ yield erb
110
+ erb
111
+ end
112
+
113
+ ##
114
+ # Sets the template file to use and reads it into a string
115
+ #
116
+ # Note: this is required before {#build!} can be called.
117
+ # @return [String] the unparsed template
118
+ def template=(template_file)
119
+ @template = File.read template_file
120
+ end
121
+
122
+ ##
123
+ # Using the specified template, this will parse the template
124
+ # @return [String] the parsed template
125
+ def build!
126
+ erb = ERB.new(template, nil, '<>')
127
+ @parsed_string = erb.result(binding) if erb
128
+ end
129
+ end
@@ -0,0 +1,22 @@
1
+ TITLE: <%= data['title'].join(', ') if data['title'] %>
2
+ <% if data['author'] %>
3
+ AUTHOR: <%= data['author'].join(', ') %>
4
+ <% end %>
5
+ <% data['category'] && data['category'].each do |cat| %>
6
+ CATEGORY: <%= cat %>
7
+ <% end %>
8
+ -----
9
+ BODY:
10
+
11
+ <%= data['body'].join("\n") if data['body'] %>
12
+
13
+ <% if data['extended_body'] %>
14
+
15
+ -----
16
+ EXTENDED BODY:
17
+
18
+ <%= data['extended_body'] %>
19
+
20
+ <% end %>
21
+
22
+ --------
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{movable_erb}
5
+ s.version = "0.2.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Joshua Davey"]
9
+ s.date = %q{2009-10-08}
10
+ s.default_executable = %q{movable_erb}
11
+ s.description = %q{A General-purpose CSV to ERB template formatter}
12
+ s.email = %q{josh@joshuadavey.com}
13
+ s.executables = ["movable_erb"]
14
+ s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "bin/movable_erb", "lib/movable_erb.rb", "lib/templates/mtimport.erb", "tasks/rspec.rake"]
15
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.rdoc", "Rakefile", "bin/movable_erb", "cucumber.yml", "features/csv.feature", "features/step_definitions/csv_steps.rb", "features/step_definitions/tmp.csv", "features/support/env.rb", "lib/movable_erb.rb", "lib/templates/mtimport.erb", "movable_erb.gemspec", "spec/csv_spec.rb", "spec/fixtures/advanced.csv", "spec/fixtures/example.csv", "spec/fixtures/template.erb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/rspec.rake"]
16
+ s.homepage = %q{http://github.com/jgdavey/movable_erb}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Movable_erb", "--main", "README.rdoc"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{movable_erb}
20
+ s.rubygems_version = %q{1.3.5}
21
+ s.summary = %q{A General-purpose CSV to ERB template formatter}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<fastercsv>, [">= 0"])
29
+ s.add_runtime_dependency(%q<trollop>, [">= 0"])
30
+ s.add_development_dependency(%q<rspec>, [">= 0"])
31
+ else
32
+ s.add_dependency(%q<fastercsv>, [">= 0"])
33
+ s.add_dependency(%q<trollop>, [">= 0"])
34
+ s.add_dependency(%q<rspec>, [">= 0"])
35
+ end
36
+ else
37
+ s.add_dependency(%q<fastercsv>, [">= 0"])
38
+ s.add_dependency(%q<trollop>, [">= 0"])
39
+ s.add_dependency(%q<rspec>, [">= 0"])
40
+ end
41
+ end
data/spec/csv_spec.rb ADDED
@@ -0,0 +1,289 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ TEMPLATE_FIXTURE = File.expand_path(File.dirname(__FILE__) + '/fixtures/template.erb')
4
+ CSV_FIXTURE = File.expand_path(File.dirname(__FILE__) + '/fixtures/example.csv')
5
+
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
20
+
21
+ context "#convert" do
22
+ before(:each) do
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
27
+ end
28
+
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")
33
+ end
34
+
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")
40
+ end
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
57
+ end
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)
64
+ end
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
80
+ end
81
+
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
116
+ before(:each) do
117
+ @csv = MovableErb::CSV.new
118
+ end
119
+
120
+ context "shortcut setup class method" do
121
+ before(:each) do
122
+ MovableErb::CSV.any_instance.stubs(:filename).returns("fake")
123
+ FasterCSV.stubs(:read).returns([])
124
+ end
125
+
126
+ it "should create a new instance" do
127
+ MovableErb::CSV.setup do |csv|
128
+ csv.should be_a(MovableErb::CSV)
129
+ end
130
+ end
131
+
132
+ it "should return the new instance" do
133
+ MovableErb::CSV.setup { |csv| @instance = csv }.should == @instance
134
+ end
135
+
136
+ it "should return the new instance (2)" do
137
+ MovableErb::CSV.setup do |csv|
138
+ @instance = csv
139
+ 'fakey fake string'
140
+ end.should == @instance
141
+ end
142
+
143
+ it "should raise an error if no block given" do
144
+ lambda { MovableErb::CSV.setup }.should raise_error('no block given')
145
+ end
146
+
147
+ it "should call parse!" do
148
+ MovableErb::CSV.any_instance.expects(:parse!)
149
+ MovableErb::CSV.setup { |csv| true }
150
+ end
151
+ end
152
+ end
153
+
154
+ describe "parsing" do
155
+ before(:each) do
156
+ FasterCSV.stubs(:read).returns([["row1"], ["row2"]])
157
+ @csv = MovableErb::CSV.new
158
+ @csv.filename = "test.csv"
159
+ end
160
+
161
+ it "#parse! should return self" do
162
+ @csv.parse!.should == @csv
163
+ end
164
+
165
+ it "#parse! should modify attribute hashes (via to_hashes)" do
166
+ @csv.expects(:to_hashes)
167
+ @csv.parse!
168
+ end
169
+
170
+ context "#to_hashes" do
171
+ it "should read from file" do
172
+ FasterCSV.expects(:read).with("test.csv").returns([[]])
173
+ @csv.to_hashes
174
+ end
175
+
176
+ it "should return an array of hashes (1 rows, 1 column)" do
177
+ @csv.to_hashes.should == [{'row1' => ['row2']}]
178
+ end
179
+
180
+ it "should downcase the header row" do
181
+ FasterCSV.stubs(:read).returns([["Name"],["Billy Bob"]])
182
+ @csv.to_hashes.should == [{'name' => ['Billy Bob']}]
183
+ end
184
+
185
+ it "should convert the header row to snake_case" do
186
+ FasterCSV.stubs(:read).returns([["Extended Body"],["Billy Bob"]])
187
+ @csv.to_hashes.should == [{'extended_body' => ['Billy Bob']}]
188
+ end
189
+
190
+ it "should return an array of hashes (3 rows, 3 columns)" do
191
+ FasterCSV.stubs(:read).returns([["Name", "Phone", "Email"],
192
+ ["John", "773-123-1234", "john@example.com"],
193
+ ["Abigail", nil, "abby@example.com"],
194
+ ["Casius", nil, nil]])
195
+ @csv.to_hashes.should == [
196
+ {'name' => ['John'], 'phone' => ['773-123-1234'], 'email' => ['john@example.com'] },
197
+ {'name' => ['Abigail'], 'email' => ['abby@example.com'] },
198
+ {'name' => ['Casius'],}
199
+ ]
200
+ end
201
+
202
+ it "should collect values with the same key" do
203
+ FasterCSV.stubs(:read).returns([["Name", "Name", "Email"], ["John", "James", "john@example.com"]])
204
+ @csv.to_hashes.should == [{'name' => ['John', 'James'],'email' => ['john@example.com']}]
205
+ end
206
+
207
+ it "should collect values with the same key (more than 2)" do
208
+ FasterCSV.stubs(:read).returns([["Name", "Name", "Name"], ["John", "James", "Jill"]])
209
+ @csv.to_hashes.should == [{'name' => ['John', 'James', 'Jill']}]
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ describe MovableErb::Erb do
216
+ context "initializing" do
217
+ it "should initialize with a template file" do
218
+ MovableErb::Erb.new.should be_a(MovableErb::Erb)
219
+ end
220
+ end
221
+
222
+ context "loading a template" do
223
+ it "template setter should load a file into @template" do
224
+ File.expects(:read).with("filename.erb").returns("This is a template")
225
+ @erb = MovableErb::Erb.new
226
+ @erb.template = 'filename.erb'
227
+ @erb.template.should == 'This is a template'
228
+ end
229
+ end
230
+
231
+ context "data hash" do
232
+ it "should accept a data hash" do
233
+ @erb = MovableErb::Erb.new
234
+ @erb.data = {'these' => 'params'}
235
+ @erb.data.should == {'these' => 'params'}
236
+ end
237
+ end
238
+
239
+ context "shortcut setup class method" do
240
+ it "should create a new instance" do
241
+ MovableErb::Erb.setup do |erb|
242
+ erb.should be_a(MovableErb::Erb)
243
+ end
244
+ end
245
+
246
+ it "should return the new instance" do
247
+ MovableErb::Erb.setup { |erb| @instance = erb }.should == @instance
248
+ end
249
+
250
+ it "should return the new instance (2)" do
251
+ MovableErb::Erb.setup do |erb|
252
+ @instance = erb
253
+ 'fakey fake string'
254
+ end.should == @instance
255
+ end
256
+
257
+ it "should raise an error if no block given" do
258
+ lambda { MovableErb::Erb.setup }.should raise_error('no block given')
259
+ end
260
+ end
261
+
262
+ context "#build!" do
263
+ before(:each) do
264
+ @erb = MovableErb::Erb.new
265
+ end
266
+
267
+ it "should create a new ERB instance with @template" do
268
+ @erb.stubs(:template).returns("string")
269
+ ERB.expects(:new)
270
+ @erb.build!
271
+ end
272
+
273
+ it "should set @parsed_string" do
274
+ @erb.stubs(:template).returns("string")
275
+ @erb.build!
276
+ @erb.parsed_string.should_not be_nil
277
+ end
278
+
279
+ it "should parse a template with data given" do
280
+ @erb.template = TEMPLATE_FIXTURE
281
+ @erb.data = {'name' => 'Johnny', 'email' => 'john@example.com'}
282
+ @erb.build!
283
+ @erb.parsed_string.should == <<-ERB.gsub(/^\s+/,'')
284
+ Name: Johnny
285
+ Email: john@example.com
286
+ ERB
287
+ end
288
+ end
289
+ 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,5 @@
1
+ Name,Phone,Email
2
+ John,773-123-1234,john@example.com
3
+ Abigail,,abby@example.com
4
+ Bernard,903-294-3921,
5
+ Casius,,
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib movable_erb]))
4
+
5
+ Spec::Runner.configure do |config|
6
+ config.mock_with :mocha
7
+ end
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 ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: movable_erb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Davey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-08 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fastercsv
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
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
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ description: A General-purpose CSV to ERB template formatter
46
+ email: josh@joshuadavey.com
47
+ executables:
48
+ - movable_erb
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - CHANGELOG
53
+ - LICENSE
54
+ - README.rdoc
55
+ - bin/movable_erb
56
+ - lib/movable_erb.rb
57
+ - lib/templates/mtimport.erb
58
+ - tasks/rspec.rake
59
+ files:
60
+ - CHANGELOG
61
+ - LICENSE
62
+ - Manifest
63
+ - README.rdoc
64
+ - Rakefile
65
+ - bin/movable_erb
66
+ - cucumber.yml
67
+ - features/csv.feature
68
+ - features/step_definitions/csv_steps.rb
69
+ - features/step_definitions/tmp.csv
70
+ - features/support/env.rb
71
+ - lib/movable_erb.rb
72
+ - lib/templates/mtimport.erb
73
+ - movable_erb.gemspec
74
+ - spec/csv_spec.rb
75
+ - spec/fixtures/advanced.csv
76
+ - spec/fixtures/example.csv
77
+ - spec/fixtures/template.erb
78
+ - spec/spec.opts
79
+ - spec/spec_helper.rb
80
+ - tasks/rspec.rake
81
+ has_rdoc: true
82
+ homepage: http://github.com/jgdavey/movable_erb
83
+ licenses: []
84
+
85
+ post_install_message:
86
+ rdoc_options:
87
+ - --line-numbers
88
+ - --inline-source
89
+ - --title
90
+ - Movable_erb
91
+ - --main
92
+ - README.rdoc
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ version:
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: "1.2"
106
+ version:
107
+ requirements: []
108
+
109
+ rubyforge_project: movable_erb
110
+ rubygems_version: 1.3.5
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: A General-purpose CSV to ERB template formatter
114
+ test_files: []
115
+