movable_erb 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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
+