comma 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/{README.markdown → README.rdoc} +7 -6
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/comma.rb +28 -57
- data/lib/comma/RenderAsCSV.rb +12 -0
- data/lib/comma/array.rb +5 -0
- data/lib/comma/generator.rb +35 -0
- data/lib/comma/namedscope.rb +6 -0
- data/lib/comma/object.rb +17 -0
- data/spec/comma/ar_spec.rb +39 -0
- data/spec/comma/comma_spec.rb +204 -0
- data/spec/comma/extractors_spec.rb +91 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +38 -0
- metadata +31 -14
data/.gitignore
ADDED
@@ -1,14 +1,14 @@
|
|
1
1
|
= COMMA
|
2
2
|
|
3
|
-
|
3
|
+
http://github.com/crafterm/comma
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
7
|
-
Comma is a CSV (ie. comma separated values) generation extension for Ruby objects, that lets you seamlessly define a CSV output format via a small DSL. Comma works well on pure Ruby objects with attributes, as well as complex ones such as ActiveRecord objects with associations, extensions, etc. It doesn't distinguish between attributes, methods, associations, extensions, etc - they all are considered equal and invoked identically via the Comma DSL description. Multiple different CSV output descriptions can also be defined.
|
7
|
+
Comma is a CSV (ie. comma separated values) generation extension for Ruby objects, that lets you seamlessly define a CSV output format via a small DSL. Comma works well on pure Ruby objects with attributes, as well as complex ones such as ActiveRecord objects with associations, extensions, etc. It doesn't distinguish between attributes, methods, associations, extensions, etc. - they all are considered equal and invoked identically via the Comma DSL description. Multiple different CSV output descriptions can also be defined.
|
8
8
|
|
9
9
|
When multiple objects in an Array are converted to CSV, the output includes generation of a header row reflected from names of the properties requested, or specified via the DSL.
|
10
10
|
|
11
|
-
CSV can be a bit of a boring format - the motivation behind Comma was to have a CSV extension that was simple, flexible, and would treat attributes, methods, associations, etc
|
11
|
+
CSV can be a bit of a boring format - the motivation behind Comma was to have a CSV extension that was simple, flexible, and would treat attributes, methods, associations, etc., all the same without the need for any complex configuration, and also work on Ruby objects, not just ActiveRecord or other base class derivatives.
|
12
12
|
|
13
13
|
An example Comma CSV enabled ActiveRecord class:
|
14
14
|
|
@@ -47,7 +47,7 @@ Annotated, the comma description is as follows:
|
|
47
47
|
name
|
48
48
|
description
|
49
49
|
|
50
|
-
# pages is an association returning an array, :size is called on the association results, with the header name
|
50
|
+
# pages is an association returning an array, :size is called on the association results, with the header name specified as 'Pages'
|
51
51
|
pages :size => 'Pages'
|
52
52
|
|
53
53
|
# publisher is an association returning an object, :name is called on the associated object, with the reflected header 'Name'
|
@@ -65,7 +65,7 @@ In the above example, any of the declarations (name, description, pages, publish
|
|
65
65
|
|
66
66
|
You can get the CSV representation of any object by calling the to_comma method, optionally providing a CSV description name to use.
|
67
67
|
|
68
|
-
Object values are automatically converted to strings via to_s allowing you to reuse any existing to_s methods on your objects (instead of having to call particular properties or define CSV specific output methods). Header names are also automatically humanized when reflected (eg.
|
68
|
+
Object values are automatically converted to strings via to_s allowing you to reuse any existing to_s methods on your objects (instead of having to call particular properties or define CSV specific output methods). Header names are also automatically humanized when reflected (eg. Replacing _ characters with whitespace). The 'isbn' example above shows how multiple values can be added to the CSV output.
|
69
69
|
|
70
70
|
Multiple CSV descriptions can also be specified for the same class, eg:
|
71
71
|
|
@@ -129,4 +129,5 @@ If you have any questions or suggestions for Comma, please feel free to contact
|
|
129
129
|
|
130
130
|
== DEPENDENCIES
|
131
131
|
|
132
|
-
If you're on ruby 1.8.*,
|
132
|
+
If you're on ruby 1.8.*, the fasterCSV gem is recommended for performance reasons.
|
133
|
+
gem install fastercsv
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "comma"
|
8
|
+
gem.summary = "Ruby Comma Seperated Values generation library"
|
9
|
+
gem.description = "Ruby Comma Seperated Values generation library"
|
10
|
+
gem.email = "crafterm@redartisan.com"
|
11
|
+
gem.rubyforge_project = 'comma'
|
12
|
+
gem.homepage = "http://github.com/crafterm/comma"
|
13
|
+
gem.authors = ["Marcus Crafter"]
|
14
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
15
|
+
gem.add_dependency("activesupport", ">= 2.2.2")
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'spec/rake/spectask'
|
24
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
25
|
+
spec.libs << 'lib' << 'spec'
|
26
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
27
|
+
end
|
28
|
+
|
29
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
30
|
+
spec.libs << 'lib' << 'spec'
|
31
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
+
spec.rcov = true
|
33
|
+
end
|
34
|
+
|
35
|
+
task :spec => :check_dependencies
|
36
|
+
|
37
|
+
task :default => :spec
|
38
|
+
|
39
|
+
require 'rake/rdoctask'
|
40
|
+
Rake::RDocTask.new do |rdoc|
|
41
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
42
|
+
|
43
|
+
rdoc.rdoc_dir = 'rdoc'
|
44
|
+
rdoc.title = "comma #{version}"
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
47
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'comma'
|
data/lib/comma.rb
CHANGED
@@ -1,68 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require '
|
6
|
-
FasterCSV = CSV
|
7
|
-
else
|
8
|
-
require 'fastercsv'
|
1
|
+
# conditional loading of activesupport
|
2
|
+
if defined? Rails and Rails.version < '2.3.5'
|
3
|
+
require 'activesupport'
|
4
|
+
else
|
5
|
+
require 'active_support'
|
9
6
|
end
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
csv << object.to_comma(style)
|
25
|
-
end
|
8
|
+
# load the right csv library
|
9
|
+
if RUBY_VERSION >= '1.9'
|
10
|
+
require 'csv'
|
11
|
+
FasterCSV = CSV
|
12
|
+
else
|
13
|
+
begin
|
14
|
+
# try faster csv
|
15
|
+
require 'fastercsv'
|
16
|
+
rescue Error => e
|
17
|
+
if defined? Rails
|
18
|
+
Rails.logger.info "FasterCSV not installed, falling back on CSV"
|
19
|
+
else
|
20
|
+
puts "FasterCSV not installed, falling back on CSV"
|
26
21
|
end
|
22
|
+
require 'csv'
|
23
|
+
FasterCSV = CSV
|
27
24
|
end
|
28
25
|
end
|
29
26
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
raise "No comma format for class #{self.class} defined for style #{style}" unless self.comma_formats and self.comma_formats[style]
|
39
|
-
Comma::DataExtractor.new(self, &self.comma_formats[style]).results
|
40
|
-
end
|
41
|
-
|
42
|
-
def to_comma_headers(style = :default)
|
43
|
-
raise "No comma format for class #{self.class} defined for style #{style}" unless self.comma_formats and self.comma_formats[style]
|
44
|
-
Comma::HeaderExtractor.new(self, &self.comma_formats[style]).results
|
45
|
-
end
|
27
|
+
require 'comma/extractors'
|
28
|
+
require 'comma/generator'
|
29
|
+
require 'comma/array'
|
30
|
+
require 'comma/object'
|
31
|
+
require 'comma/renderascsv'
|
32
|
+
|
33
|
+
if defined?(ActiveRecord)
|
34
|
+
require 'comma/namedscope'
|
46
35
|
end
|
47
36
|
|
48
37
|
if defined?(ActionController)
|
49
|
-
module RenderAsCSV
|
50
|
-
|
51
|
-
def self.included(base)
|
52
|
-
base.send :include, InstanceMethods
|
53
|
-
base.alias_method_chain :render, :csv
|
54
|
-
end
|
55
|
-
|
56
|
-
module InstanceMethods
|
57
|
-
def render_with_csv(options = nil, extra_options = {}, &block)
|
58
|
-
return render_without_csv(options, extra_options, &block) unless options.is_a?(Hash) and options[:csv]
|
59
|
-
data = options.delete(:csv)
|
60
|
-
style = options.delete(:style) || :default
|
61
|
-
send_data Array(data).to_comma(style), options.merge(:type => :csv)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
38
|
ActionController::Base.send :include, RenderAsCSV
|
68
39
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RenderAsCSV
|
2
|
+
def self.included(base)
|
3
|
+
base.alias_method_chain :render, :csv
|
4
|
+
end
|
5
|
+
|
6
|
+
def render_with_csv(options = nil, extra_options = {}, &block)
|
7
|
+
return render_without_csv(options, extra_options, &block) unless options.is_a?(Hash) and options[:csv]
|
8
|
+
data = options.delete(:csv)
|
9
|
+
style = options.delete(:style) || :default
|
10
|
+
send_data Array(data).to_comma(style), options.merge(:type => :csv)
|
11
|
+
end
|
12
|
+
end
|
data/lib/comma/array.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Comma
|
2
|
+
|
3
|
+
class Generator
|
4
|
+
|
5
|
+
def initialize(instance, style)
|
6
|
+
@instance = instance
|
7
|
+
@style = style
|
8
|
+
@options = {}
|
9
|
+
|
10
|
+
if @style.is_a? Hash
|
11
|
+
@options = @style.clone
|
12
|
+
@style = @options.delete(:style) || :default
|
13
|
+
@filename = @options.delete(:filename)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(iterator_method)
|
18
|
+
if @filename
|
19
|
+
FasterCSV.open(@filename, 'w'){ |csv| append_csv(csv, iterator_method) } and return true
|
20
|
+
else
|
21
|
+
FasterCSV.generate(@options){ |csv| append_csv(csv, iterator_method) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def append_csv(csv, iterator_method)
|
27
|
+
return '' if @instance.empty?
|
28
|
+
csv << @instance.first.to_comma_headers(@style) # REVISIT: request to optionally include headers
|
29
|
+
@instance.send(iterator_method) do |object|
|
30
|
+
csv << object.to_comma(@style)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/comma/object.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Object
|
2
|
+
class_inheritable_accessor :comma_formats
|
3
|
+
|
4
|
+
def self.comma(style = :default, &block)
|
5
|
+
(self.comma_formats ||= {})[style] = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_comma(style = :default)
|
9
|
+
raise "No comma format for class #{self.class} defined for style #{style}" unless self.comma_formats and self.comma_formats[style]
|
10
|
+
Comma::DataExtractor.new(self, &self.comma_formats[style]).results
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_comma_headers(style = :default)
|
14
|
+
raise "No comma format for class #{self.class} defined for style #{style}" unless self.comma_formats and self.comma_formats[style]
|
15
|
+
Comma::HeaderExtractor.new(self, &self.comma_formats[style]).results
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
describe Comma, 'generating CSV from an ActiveRecord object' do
|
5
|
+
before(:all) do
|
6
|
+
class Person < ActiveRecord::Base
|
7
|
+
named_scope :teenagers, :conditions => { :age => 13..19 }
|
8
|
+
comma do
|
9
|
+
name
|
10
|
+
age
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
15
|
+
Column = ActiveRecord::ConnectionAdapters::Column
|
16
|
+
end
|
17
|
+
|
18
|
+
before do
|
19
|
+
Person.stub!(:columns).and_return [Column.new('age', 0, 'integer', false),
|
20
|
+
Column.new('name', nil, 'string', false) ]
|
21
|
+
Person.stub!(:table_exists?).and_return(true)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'case' do
|
25
|
+
before do
|
26
|
+
people = [ Person.new(:age => 18, :name => 'Junior') ]
|
27
|
+
Person.stub!(:find_every).and_return people
|
28
|
+
Person.stub!(:calculate).with(:count, :all, {}).and_return people.size
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should extend ActiveRecord::NamedScope::Scope to add a #to_comma method which will return CSV content for objects within the scope' do
|
32
|
+
Person.teenagers.to_comma.should == "Name,Age\nJunior,18\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should find in batches' do
|
36
|
+
Person.teenagers.to_comma
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Comma do
|
4
|
+
|
5
|
+
it 'should extend object to add a comma method' do
|
6
|
+
Object.should respond_to(:comma)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should extend object to have a to_comma method' do
|
10
|
+
Object.should respond_to(:to_comma)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should extend object to have a to_comma_headers method' do
|
14
|
+
Object.should respond_to(:to_comma_headers)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Comma, 'generating CSV' do
|
20
|
+
|
21
|
+
before do
|
22
|
+
@isbn = Isbn.new('123123123', '321321321')
|
23
|
+
@book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
|
24
|
+
|
25
|
+
@books = []
|
26
|
+
@books << @book
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should extend Array to add a #to_comma method which will return CSV content for objects within the array' do
|
30
|
+
@books.to_comma.should == "Title,Description,Issuer,ISBN-10,ISBN-13\nSmalltalk-80,Language and Implementation,ISBN,123123123,321321321\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should return an empty string when generating CSV from an empty array' do
|
34
|
+
Array.new.to_comma.should == ''
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should change the style when specified" do
|
38
|
+
@books.to_comma(:brief).should == "Name,Description\nSmalltalk-80,Language and Implementation\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'with :filename specified' do
|
42
|
+
before{ @books.to_comma(:filename => 'comma.csv') }
|
43
|
+
after{ File.delete('comma.csv') }
|
44
|
+
|
45
|
+
it "should write to the file" do
|
46
|
+
File.read('comma.csv').should == "Title,Description,Issuer,ISBN-10,ISBN-13\nSmalltalk-80,Language and Implementation,ISBN,123123123,321321321\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "with FasterCVS options" do
|
51
|
+
it "should not change when options are empty" do
|
52
|
+
@books.to_comma({}).should == "Title,Description,Issuer,ISBN-10,ISBN-13\nSmalltalk-80,Language and Implementation,ISBN,123123123,321321321\n"
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should accept the options in #to_comma and generate the appropriate CSV' do
|
56
|
+
@books.to_comma(:col_sep => ';', :force_quotes => true).should == "\"Title\";\"Description\";\"Issuer\";\"ISBN-10\";\"ISBN-13\"\n\"Smalltalk-80\";\"Language and Implementation\";\"ISBN\";\"123123123\";\"321321321\"\n"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should change the style when specified" do
|
60
|
+
@books.to_comma(:style => :brief, :col_sep => ';', :force_quotes => true).should == "\"Name\";\"Description\"\n\"Smalltalk-80\";\"Language and Implementation\"\n"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe Comma, 'defining CSV descriptions' do
|
66
|
+
|
67
|
+
describe 'with an unnamed description' do
|
68
|
+
|
69
|
+
before do
|
70
|
+
class Foo
|
71
|
+
comma do; end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should name the current description :default if no name has been provided' do
|
76
|
+
Foo.comma_formats.should_not be_empty
|
77
|
+
Foo.comma_formats[:default].should_not be_nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe 'with a named description' do
|
82
|
+
|
83
|
+
before do
|
84
|
+
class Bar
|
85
|
+
comma do; end
|
86
|
+
comma :detailed do; end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should use the provided name to index the comma format' do
|
91
|
+
Bar.comma_formats.should_not be_empty
|
92
|
+
Bar.comma_formats[:default].should_not be_nil
|
93
|
+
Bar.comma_formats[:detailed].should_not be_nil
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe Comma, 'to_comma data/headers object extensions' do
|
99
|
+
|
100
|
+
describe 'with unnamed descriptions' do
|
101
|
+
|
102
|
+
before do
|
103
|
+
class Foo
|
104
|
+
attr_accessor :content
|
105
|
+
comma do; content; end
|
106
|
+
|
107
|
+
def initialize(content)
|
108
|
+
@content = content
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
@foo = Foo.new('content')
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should return and array of data content, using the :default CSV description if none requested' do
|
116
|
+
@foo.to_comma.should == %w(content)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should return and array of header content, using the :default CSV description if none requested' do
|
120
|
+
@foo.to_comma_headers.should == %w(Content)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should return the CSV representation including header and content when called on an array' do
|
124
|
+
Array(@foo).to_comma.should == "Content\ncontent\n"
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
describe 'with named descriptions' do
|
130
|
+
|
131
|
+
before do
|
132
|
+
class Foo
|
133
|
+
attr_accessor :content
|
134
|
+
comma :detailed do; content; end
|
135
|
+
|
136
|
+
def initialize(content)
|
137
|
+
@content = content
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
@foo = Foo.new('content')
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should return and array of data content, using the :default CSV description if none requested' do
|
145
|
+
@foo.to_comma(:detailed).should == %w(content)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should return and array of header content, using the :default CSV description if none requested' do
|
149
|
+
@foo.to_comma_headers(:detailed).should == %w(Content)
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should return the CSV representation including header and content when called on an array' do
|
153
|
+
Array(@foo).to_comma(:detailed).should == "Content\ncontent\n"
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should raise an error if the requested description is not avaliable' do
|
157
|
+
lambda { @foo.to_comma(:bad) }.should raise_error
|
158
|
+
lambda { @foo.to_comma_headers(:bad) }.should raise_error
|
159
|
+
lambda { Array(@foo).to_comma(:bad) }.should raise_error
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
describe 'with block' do
|
165
|
+
before do
|
166
|
+
class Foo
|
167
|
+
attr_accessor :content, :created_at, :updated_at
|
168
|
+
comma do
|
169
|
+
time_to_s = lambda { |i| i && i.to_s(:db) }
|
170
|
+
content
|
171
|
+
content('Truncated Content') {|i| i && i.length > 10 ? i[0..10] : '---' }
|
172
|
+
created_at &time_to_s
|
173
|
+
updated_at &time_to_s
|
174
|
+
end
|
175
|
+
|
176
|
+
def initialize(content, created_at = Time.now, updated_at = Time.now)
|
177
|
+
@content = content
|
178
|
+
@created_at = created_at
|
179
|
+
@updated_at = updated_at
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
@time = Time.now
|
184
|
+
@content = 'content ' * 5
|
185
|
+
@foo = Foo.new @content, @time, @time
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should return yielded values by block' do
|
189
|
+
header, foo = Array(@foo).to_comma.split("\n")
|
190
|
+
foo.should == [@content, @content[0..10], @time.to_s(:db), @time.to_s(:db)].join(',')
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
describe 'on an object with no comma declaration' do
|
196
|
+
|
197
|
+
it 'should raise an error mentioning there is no comma description defined for that class' do
|
198
|
+
lambda { 'a string'.to_comma }.should raise_error('No comma format for class String defined for style default')
|
199
|
+
lambda { 'a string'.to_comma_headers }.should raise_error('No comma format for class String defined for style default')
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
# comma do
|
4
|
+
# name 'Title'
|
5
|
+
# description
|
6
|
+
#
|
7
|
+
# isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
|
8
|
+
# end
|
9
|
+
|
10
|
+
describe Comma::HeaderExtractor do
|
11
|
+
|
12
|
+
before do
|
13
|
+
@isbn = Isbn.new('123123123', '321321321')
|
14
|
+
@book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
|
15
|
+
|
16
|
+
@headers = @book.to_comma_headers
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'when no parameters are provided' do
|
20
|
+
|
21
|
+
it 'should use the method name as the header name, humanized' do
|
22
|
+
@headers.should include('Description')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'when given a string description as a parameter' do
|
27
|
+
|
28
|
+
it 'should use the string value, unmodified' do
|
29
|
+
@headers.should include('Title')
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'when an hash is passed as a parameter' do
|
34
|
+
|
35
|
+
describe 'with a string value' do
|
36
|
+
|
37
|
+
it 'should use the string value, unmodified' do
|
38
|
+
@headers.should include('ISBN-10')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'with a non-string value' do
|
43
|
+
|
44
|
+
it 'should use the non string value converted to a string, humanized' do
|
45
|
+
@headers.should include('Issuer')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
describe Comma::DataExtractor do
|
54
|
+
|
55
|
+
before do
|
56
|
+
@isbn = Isbn.new('123123123', '321321321')
|
57
|
+
@book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
|
58
|
+
|
59
|
+
@data = @book.to_comma
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'when no parameters are provided' do
|
63
|
+
|
64
|
+
it 'should use the string value returned by sending the method name on the object' do
|
65
|
+
@data.should include('Language and Implementation')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe 'when given a string description as a parameter' do
|
70
|
+
|
71
|
+
it 'should use the string value returned by sending the method name on the object' do
|
72
|
+
@data.should include('Smalltalk-80')
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'when an hash is passed as a parameter' do
|
77
|
+
|
78
|
+
describe 'with a string value' do
|
79
|
+
|
80
|
+
it 'should use the string value, returned by sending the hash key to the object' do
|
81
|
+
@data.should include('123123123')
|
82
|
+
@data.should include('321321321')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should not fail when an associated object is nil' do
|
86
|
+
lambda { Book.new('Smalltalk-80', 'Language and Implementation', nil).to_comma }.should_not raise_error
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
|
4
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
5
|
+
require 'comma'
|
6
|
+
|
7
|
+
|
8
|
+
class Book
|
9
|
+
attr_accessor :name, :description, :isbn
|
10
|
+
|
11
|
+
def initialize(name, description, isbn)
|
12
|
+
@name, @description, @isbn = name, description, isbn
|
13
|
+
end
|
14
|
+
|
15
|
+
comma do
|
16
|
+
name 'Title'
|
17
|
+
description
|
18
|
+
|
19
|
+
isbn :authority => :issuer
|
20
|
+
isbn :number_10 => 'ISBN-10'
|
21
|
+
isbn :number_13 => 'ISBN-13'
|
22
|
+
end
|
23
|
+
|
24
|
+
comma :brief do
|
25
|
+
name
|
26
|
+
description
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Isbn
|
31
|
+
attr_accessor :number_10, :number_13
|
32
|
+
|
33
|
+
def initialize(isbn_10, isbn_13)
|
34
|
+
@number_10, @number_13 = isbn_10, isbn_13
|
35
|
+
end
|
36
|
+
|
37
|
+
def authority; 'ISBN'; end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: comma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcus Crafter
|
@@ -9,18 +9,18 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-13 00:00:00 +13:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
17
|
-
type: :
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
18
|
version_requirement:
|
19
19
|
version_requirements: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.
|
23
|
+
version: 1.2.9
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activesupport
|
@@ -32,26 +32,40 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 2.2.2
|
34
34
|
version:
|
35
|
-
description:
|
35
|
+
description: Ruby Comma Seperated Values generation library
|
36
36
|
email: crafterm@redartisan.com
|
37
37
|
executables: []
|
38
38
|
|
39
39
|
extensions: []
|
40
40
|
|
41
|
-
extra_rdoc_files:
|
42
|
-
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
43
|
files:
|
44
|
-
-
|
44
|
+
- .gitignore
|
45
45
|
- MIT-LICENSE
|
46
|
+
- README.rdoc
|
47
|
+
- Rakefile
|
48
|
+
- VERSION
|
49
|
+
- init.rb
|
46
50
|
- lib/comma.rb
|
51
|
+
- lib/comma/RenderAsCSV.rb
|
52
|
+
- lib/comma/array.rb
|
47
53
|
- lib/comma/extractors.rb
|
54
|
+
- lib/comma/generator.rb
|
55
|
+
- lib/comma/namedscope.rb
|
56
|
+
- lib/comma/object.rb
|
57
|
+
- spec/comma/ar_spec.rb
|
58
|
+
- spec/comma/comma_spec.rb
|
59
|
+
- spec/comma/extractors_spec.rb
|
60
|
+
- spec/spec.opts
|
61
|
+
- spec/spec_helper.rb
|
48
62
|
has_rdoc: true
|
49
63
|
homepage: http://github.com/crafterm/comma
|
50
64
|
licenses: []
|
51
65
|
|
52
66
|
post_install_message:
|
53
|
-
rdoc_options:
|
54
|
-
|
67
|
+
rdoc_options:
|
68
|
+
- --charset=UTF-8
|
55
69
|
require_paths:
|
56
70
|
- lib
|
57
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -68,10 +82,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
82
|
version:
|
69
83
|
requirements: []
|
70
84
|
|
71
|
-
rubyforge_project:
|
85
|
+
rubyforge_project: comma
|
72
86
|
rubygems_version: 1.3.5
|
73
87
|
signing_key:
|
74
88
|
specification_version: 3
|
75
89
|
summary: Ruby Comma Seperated Values generation library
|
76
|
-
test_files:
|
77
|
-
|
90
|
+
test_files:
|
91
|
+
- spec/comma/ar_spec.rb
|
92
|
+
- spec/comma/comma_spec.rb
|
93
|
+
- spec/comma/extractors_spec.rb
|
94
|
+
- spec/spec_helper.rb
|