comma 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,3 @@
1
1
  pkg/*
2
2
  .*.swp
3
3
  *~
4
- *.gemspec
data/MIT-LICENSE CHANGED
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -12,55 +12,61 @@ CSV can be a bit of a boring format - the motivation behind Comma was to have a
12
12
 
13
13
  An example Comma CSV enabled ActiveRecord class:
14
14
 
15
- class Book < ActiveRecord::Base
16
-
17
- # ================
18
- # = Associations =
19
- # ================
20
- has_many :pages
21
- has_one :isbn
22
- belongs_to :publisher
23
-
24
- # ===============
25
- # = CSV support =
26
- # ===============
27
- comma do
28
-
29
- name
30
- description
31
-
32
- pages :size => 'Pages'
33
- publisher :name
34
- isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
35
- blurb 'Summary'
36
-
37
- end
38
-
39
- end
15
+ class Book < ActiveRecord::Base
16
+
17
+ # ================
18
+ # = Associations =
19
+ # ================
20
+ has_many :pages
21
+ has_one :isbn
22
+ belongs_to :publisher
23
+
24
+ # ===============
25
+ # = CSV support =
26
+ # ===============
27
+ comma do
28
+
29
+ name
30
+ description
31
+
32
+ pages :size => 'Pages'
33
+ publisher :name
34
+ isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
35
+ blurb 'Summary'
36
+
37
+ end
38
+
39
+ end
40
40
 
41
41
  Annotated, the comma description is as follows:
42
42
 
43
- # starts a Comma description block, generating 2 methods #to_comma and #to_comma_headers for this class.
44
- comma do
45
-
46
- # name, description are attributes of Book with the header being reflected as 'Name', 'Description'
47
- name
48
- description
49
-
50
- # pages is an association returning an array, :size is called on the association results, with the header name specified as 'Pages'
51
- pages :size => 'Pages'
52
-
53
- # publisher is an association returning an object, :name is called on the associated object, with the reflected header 'Name'
54
- publisher :name
55
-
56
- # isbn is an association returning an object, :number_10 and :number_13 are called on the object with the specified headers 'ISBN-10' and 'ISBN-13'
57
- isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
58
-
59
- # blurb is an attribute of Book, with the header being specified directly as 'Summary'
60
- blurb 'Summary'
61
-
62
- end
63
-
43
+ # starts a Comma description block, generating 2 methods #to_comma and
44
+ # #to_comma_headers for this class.
45
+ comma do
46
+
47
+ # name, description are attributes of Book with the header being reflected as
48
+ # 'Name', 'Description'
49
+ name
50
+ description
51
+
52
+ # pages is an association returning an array, :size is called on the
53
+ # association results, with the header name specified as 'Pages'
54
+ pages :size => 'Pages'
55
+
56
+ # publisher is an association returning an object, :name is called on the
57
+ # associated object, with the reflected header 'Name'
58
+ publisher :name
59
+
60
+ # isbn is an association returning an object, :number_10 and :number_13 are
61
+ # called on the object with the specified headers 'ISBN-10' and 'ISBN-13'
62
+ isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
63
+
64
+ # blurb is an attribute of Book, with the header being specified directly
65
+ # as 'Summary'
66
+ blurb 'Summary'
67
+
68
+ end
69
+
64
70
  In the above example, any of the declarations (name, description, pages, publisher, isbn, blurb, etc), could be methods, attributes, associations, etc - no distinction during configuration is required, as everything is invoked via Ruby's #send method.
65
71
 
66
72
  You can get the CSV representation of any object by calling the to_comma method, optionally providing a CSV description name to use.
@@ -69,85 +75,133 @@ Object values are automatically converted to strings via to_s allowing you to re
69
75
 
70
76
  Multiple CSV descriptions can also be specified for the same class, eg:
71
77
 
72
- class Book < ActiveRecord::Base
73
-
74
- # ================
75
- # = Associations =
76
- # ================
77
- has_many :pages
78
- has_one :isbn
79
- belongs_to :publisher
80
-
81
- # ===============
82
- # = CSV support =
83
- # ===============
84
- comma do
85
-
86
- name
87
- description
88
-
89
- pages :size => 'Pages'
90
- publisher :name
91
- isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
92
- blurb 'Summary'
93
-
94
- end
95
-
96
- comma :brief do
97
-
98
- name
99
- description
100
- blurb 'Summary'
101
-
102
- end
103
-
104
- end
105
-
78
+ class Book < ActiveRecord::Base
79
+
80
+ # ================
81
+ # = Associations =
82
+ # ================
83
+ has_many :pages
84
+ has_one :isbn
85
+ belongs_to :publisher
86
+
87
+ # ===============
88
+ # = CSV support =
89
+ # ===============
90
+ comma do
91
+
92
+ name
93
+ description
94
+
95
+ pages :size => 'Pages'
96
+ publisher :name
97
+ isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
98
+ blurb 'Summary'
99
+
100
+ end
101
+
102
+ comma :brief do
103
+
104
+ name
105
+ description
106
+ blurb 'Summary'
107
+
108
+ end
109
+
110
+ end
111
+
106
112
  You can specify which output format you would like to use via an optional parameter to to_comma:
107
113
 
108
- Book.limited(10).to_comma(:brief)
114
+ Book.limited(10).to_comma(:brief)
109
115
 
110
116
  Specifying no description name to to_comma is equivalent to specifying :default as the description name.
111
117
 
112
118
  You can pass options for FasterCSV, e.g.
113
119
 
114
- Book.limited(10).to_comma(:style => :brief, :col_sep => ';', :force_quotes => true)
120
+ Book.limited(10).to_comma(:style => :brief,
121
+ :col_sep => ';',
122
+ :force_quotes => true)
115
123
 
116
124
  You can pass the :filename option and have Comma writes the CSV output to this file:
117
125
 
118
- Book.limited(10).to_comma(:filename => 'books.csv')
126
+ Book.limited(10).to_comma(:filename => 'books.csv')
127
+
128
+ == Using blocks
129
+
130
+ For more complex relationships you can pass blocks for calculated values, or related values. Following the previous example here is a comma set using blocks (both with and without labels for your CSV headings):
131
+
132
+ class Publisher < ActiveRecord::Base
133
+ # ================
134
+ # = Associations =
135
+ # ================
136
+ has_one :primary_contact, :class_name => "User" #(basic user with a name)
137
+ has_many :users
138
+ end
139
+
140
+ class Book < ActiveRecord::Base
141
+
142
+ # ================
143
+ # = Associations =
144
+ # ================
145
+ has_many :pages
146
+ has_one :isbn
147
+ belongs_to :publisher
148
+
149
+ # ===============
150
+ # = CSV support =
151
+ # ===============
152
+ comma do
153
+ name
154
+ description
155
+
156
+ pages :size => 'Pages'
157
+ publisher :name
158
+ publisher { |publisher| publisher.primary_contact.name.to_s.titleize }
159
+ publisher 'Number of publisher users' do |publisher| publisher.users.size end
160
+ isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
161
+ blurb 'Summary'
162
+
163
+ end
164
+
165
+ end
166
+
167
+
168
+ In the preceding example, the 2 new fields added (both based on the publisher relationship) mean that the following will be added:
169
+ - the first example 'publishers_contact' is loaded straight as a block. The value returned by the lambda is displayed with a header value of 'Publisher'
170
+ - the second example 'total_publishers_users' is sent via a hash and a custom label is set, if used in the first examples method the header would be 'Publisher', but sent as a hash the header is 'Number of publisher users'.
119
171
 
120
172
  === USING WITH RAILS
121
173
 
122
174
  When used with Rails (ie. add 'comma' as a gem dependency), Comma automatically adds support for rendering CSV output in your controllers:
123
175
 
124
- class BooksController < ApplicationController
176
+ class BooksController < ApplicationController
177
+
178
+ def index
179
+ respond_to do |format|
180
+ format.csv { render :csv => Book.limited(50) }
181
+ end
182
+ end
125
183
 
126
- def index
127
- respond_to do |format|
128
- format.csv { render :csv => Book.limited(50) }
129
- end
130
- end
184
+ end
131
185
 
132
- end
133
-
134
186
  When used with Rails 2.3.*, Comma also adds support for exporting named scopes:
135
187
 
136
- class Book < ActiveRecord::Base
137
- named_scope :recent,
138
- lambda { { :conditions => ['created_at > ?', 1.month.ago] } }
188
+ class Book < ActiveRecord::Base
189
+ named_scope :recent,
190
+ lambda { { :conditions => ['created_at > ?', 1.month.ago] } }
139
191
 
140
- # ...
141
- end
192
+ # ...
193
+ end
142
194
 
143
195
  Calling the to_comma method on the named scope will internally use Rails' find_each method, instantiating only 1,000 ActiveRecord objects at a time:
144
196
 
145
- Book.recent.to_comma
197
+ Book.recent.to_comma
146
198
 
147
199
  == DEPENDENCIES
148
200
 
149
201
  If you're on Ruby 1.8.*, the FasterCSV gem is recommended for performance reasons.
150
202
 
151
- gem install fastercsv
203
+ gem install fastercsv
152
204
 
153
205
  If you have any questions or suggestions for Comma, please feel free to contact me at crafterm@redartisan.com, all feedback welcome!
206
+
207
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.2
1
+ 0.4.0
data/comma.gemspec ADDED
@@ -0,0 +1,70 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{comma}
8
+ s.version = "0.4.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Marcus Crafter"]
12
+ s.date = %q{2010-10-19}
13
+ s.description = %q{Ruby Comma Seperated Values generation library}
14
+ s.email = %q{crafterm@redartisan.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "MIT-LICENSE",
21
+ "README.rdoc",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "comma.gemspec",
25
+ "init.rb",
26
+ "lib/comma.rb",
27
+ "lib/comma/array.rb",
28
+ "lib/comma/association_proxy.rb",
29
+ "lib/comma/extractors.rb",
30
+ "lib/comma/generator.rb",
31
+ "lib/comma/named_scope.rb",
32
+ "lib/comma/object.rb",
33
+ "lib/comma/render_as_csv.rb",
34
+ "spec/comma/ar_spec.rb",
35
+ "spec/comma/comma_spec.rb",
36
+ "spec/comma/extractors_spec.rb",
37
+ "spec/spec.opts",
38
+ "spec/spec_helper.rb",
39
+ "sudo"
40
+ ]
41
+ s.homepage = %q{http://github.com/crafterm/comma}
42
+ s.rdoc_options = ["--charset=UTF-8"]
43
+ s.require_paths = ["lib"]
44
+ s.rubyforge_project = %q{comma}
45
+ s.rubygems_version = %q{1.3.7}
46
+ s.summary = %q{Ruby Comma Seperated Values generation library}
47
+ s.test_files = [
48
+ "spec/comma/ar_spec.rb",
49
+ "spec/comma/comma_spec.rb",
50
+ "spec/comma/extractors_spec.rb",
51
+ "spec/spec_helper.rb"
52
+ ]
53
+
54
+ if s.respond_to? :specification_version then
55
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
60
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.2.2"])
61
+ else
62
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
63
+ s.add_dependency(%q<activesupport>, [">= 2.2.2"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
67
+ s.add_dependency(%q<activesupport>, [">= 2.2.2"])
68
+ end
69
+ end
70
+
data/lib/comma.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  # conditional loading of activesupport
2
- if defined? Rails and Rails.version < '2.3.5'
3
- require 'activesupport'
4
- else
2
+ if defined? Rails and (Rails.version.split('.').map(&:to_i) <=> [2,3,5]) < 0
3
+ require 'activesupport'
4
+ else
5
5
  require 'active_support/core_ext/class/inheritable_attributes'
6
6
  end
7
7
 
8
8
  # load the right csv library
9
9
  if RUBY_VERSION >= '1.9'
10
- require 'csv'
10
+ require 'csv'
11
11
  FasterCSV = CSV
12
- else
12
+ else
13
13
  begin
14
14
  # try faster csv
15
15
  require 'fastercsv'
16
- rescue Error => e
16
+ rescue StandardError => e
17
17
  if defined? Rails
18
18
  Rails.logger.info "FasterCSV not installed, falling back on CSV"
19
19
  else
@@ -32,6 +32,7 @@ require 'comma/render_as_csv'
32
32
 
33
33
  if defined?(ActiveRecord)
34
34
  require 'comma/named_scope'
35
+ require 'comma/association_proxy'
35
36
  end
36
37
 
37
38
  if defined?(ActionController)
@@ -0,0 +1,6 @@
1
+ class ActiveRecord::Associations::AssociationProxy
2
+ def to_comma(style = :default)
3
+ #Bug in Rails 2.3.5, this is a workaround as association_proxy.rb doesn't pass the &block in the send method so it silently fails
4
+ Comma::Generator.new(Array(self), style).run(:each)
5
+ end
6
+ end
@@ -22,7 +22,6 @@ module Comma
22
22
 
23
23
  def method_missing(sym, *args, &block)
24
24
  @results << sym.to_s.humanize if args.blank?
25
-
26
25
  args.each do |arg|
27
26
  case arg
28
27
  when Hash
@@ -3,4 +3,3 @@ class ActiveRecord::NamedScope::Scope
3
3
  Comma::Generator.new(self, style).run(:find_each)
4
4
  end
5
5
  end
6
-
data/lib/comma/object.rb CHANGED
@@ -1,15 +1,15 @@
1
1
  class Object
2
2
  class_inheritable_accessor :comma_formats
3
-
3
+
4
4
  def self.comma(style = :default, &block)
5
5
  (self.comma_formats ||= {})[style] = block
6
6
  end
7
-
7
+
8
8
  def to_comma(style = :default)
9
9
  raise "No comma format for class #{self.class} defined for style #{style}" unless self.comma_formats and self.comma_formats[style]
10
10
  Comma::DataExtractor.new(self, &self.comma_formats[style]).results
11
11
  end
12
-
12
+
13
13
  def to_comma_headers(style = :default)
14
14
  raise "No comma format for class #{self.class} defined for style #{style}" unless self.comma_formats and self.comma_formats[style]
15
15
  Comma::HeaderExtractor.new(self, &self.comma_formats[style]).results
@@ -4,9 +4,39 @@ module RenderAsCSV
4
4
  end
5
5
 
6
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)
7
+ return render_without_csv(options, extra_options, &block) unless options.is_a?(Hash) and options[:csv].present?
8
+
9
+ content = options.delete(:csv)
10
+ style = options.delete(:style) || :default
11
+ filename = options.delete(:filename)
12
+
13
+ headers.merge!(
14
+ 'Content-Transfer-Encoding' => 'binary',
15
+ 'Content-Type' => 'text/csv; charset=utf-8'
16
+ )
17
+ filename_header_value = "attachment"
18
+ filename_header_value += "; filename=\"#{filename}\"" if filename.present?
19
+ headers.merge!('Content-Disposition' => filename_header_value)
20
+
21
+ @performed_render = false
22
+
23
+ render_stream :status => 200,
24
+ :content => Array(content),
25
+ :style => style
26
+ end
27
+
28
+ protected
29
+
30
+ def render_stream(options)
31
+ status = options[:status]
32
+ content = options[:content]
33
+ style = options[:style]
34
+
35
+ render :status => status, :text => Proc.new { |response, output|
36
+ output.write FasterCSV.generate_line(content.first.to_comma_headers(style))
37
+ content.each { |line| output.write FasterCSV.generate_line(line.to_comma(style)) }
38
+ }
11
39
  end
12
40
  end
41
+
42
+ #credit : http://ramblingsonrails.com/download-a-large-amount-of-data-in-csv-from-rails
@@ -1,31 +1,31 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
3
  describe Comma do
4
-
4
+
5
5
  it 'should extend object to add a comma method' do
6
6
  Object.should respond_to(:comma)
7
7
  end
8
-
8
+
9
9
  it 'should extend object to have a to_comma method' do
10
10
  Object.should respond_to(:to_comma)
11
11
  end
12
-
12
+
13
13
  it 'should extend object to have a to_comma_headers method' do
14
14
  Object.should respond_to(:to_comma_headers)
15
15
  end
16
-
16
+
17
17
  end
18
18
 
19
19
  describe Comma, 'generating CSV' do
20
-
20
+
21
21
  before do
22
22
  @isbn = Isbn.new('123123123', '321321321')
23
23
  @book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
24
-
24
+
25
25
  @books = []
26
26
  @books << @book
27
27
  end
28
-
28
+
29
29
  it 'should extend Array to add a #to_comma method which will return CSV content for objects within the array' do
30
30
  @books.to_comma.should == "Title,Description,Issuer,ISBN-10,ISBN-13\nSmalltalk-80,Language and Implementation,ISBN,123123123,321321321\n"
31
31
  end
@@ -69,30 +69,30 @@ describe Comma, 'generating CSV' do
69
69
  end
70
70
 
71
71
  describe Comma, 'defining CSV descriptions' do
72
-
72
+
73
73
  describe 'with an unnamed description' do
74
-
74
+
75
75
  before do
76
76
  class Foo
77
77
  comma do; end
78
- end
78
+ end
79
79
  end
80
-
80
+
81
81
  it 'should name the current description :default if no name has been provided' do
82
82
  Foo.comma_formats.should_not be_empty
83
83
  Foo.comma_formats[:default].should_not be_nil
84
84
  end
85
85
  end
86
-
86
+
87
87
  describe 'with a named description' do
88
-
88
+
89
89
  before do
90
90
  class Bar
91
91
  comma do; end
92
92
  comma :detailed do; end
93
- end
93
+ end
94
94
  end
95
-
95
+
96
96
  it 'should use the provided name to index the comma format' do
97
97
  Bar.comma_formats.should_not be_empty
98
98
  Bar.comma_formats[:default].should_not be_nil
@@ -102,22 +102,22 @@ describe Comma, 'defining CSV descriptions' do
102
102
  end
103
103
 
104
104
  describe Comma, 'to_comma data/headers object extensions' do
105
-
105
+
106
106
  describe 'with unnamed descriptions' do
107
-
107
+
108
108
  before do
109
109
  class Foo
110
110
  attr_accessor :content
111
111
  comma do; content; end
112
-
112
+
113
113
  def initialize(content)
114
114
  @content = content
115
115
  end
116
116
  end
117
-
117
+
118
118
  @foo = Foo.new('content')
119
119
  end
120
-
120
+
121
121
  it 'should return and array of data content, using the :default CSV description if none requested' do
122
122
  @foo.to_comma.should == %w(content)
123
123
  end
@@ -125,28 +125,28 @@ describe Comma, 'to_comma data/headers object extensions' do
125
125
  it 'should return and array of header content, using the :default CSV description if none requested' do
126
126
  @foo.to_comma_headers.should == %w(Content)
127
127
  end
128
-
128
+
129
129
  it 'should return the CSV representation including header and content when called on an array' do
130
130
  Array(@foo).to_comma.should == "Content\ncontent\n"
131
131
  end
132
132
 
133
133
  end
134
-
134
+
135
135
  describe 'with named descriptions' do
136
-
136
+
137
137
  before do
138
138
  class Foo
139
139
  attr_accessor :content
140
140
  comma :detailed do; content; end
141
-
141
+
142
142
  def initialize(content)
143
143
  @content = content
144
144
  end
145
145
  end
146
-
146
+
147
147
  @foo = Foo.new('content')
148
148
  end
149
-
149
+
150
150
  it 'should return and array of data content, using the :default CSV description if none requested' do
151
151
  @foo.to_comma(:detailed).should == %w(content)
152
152
  end
@@ -154,17 +154,17 @@ describe Comma, 'to_comma data/headers object extensions' do
154
154
  it 'should return and array of header content, using the :default CSV description if none requested' do
155
155
  @foo.to_comma_headers(:detailed).should == %w(Content)
156
156
  end
157
-
157
+
158
158
  it 'should return the CSV representation including header and content when called on an array' do
159
159
  Array(@foo).to_comma(:detailed).should == "Content\ncontent\n"
160
160
  end
161
-
161
+
162
162
  it 'should raise an error if the requested description is not avaliable' do
163
163
  lambda { @foo.to_comma(:bad) }.should raise_error
164
164
  lambda { @foo.to_comma_headers(:bad) }.should raise_error
165
165
  lambda { Array(@foo).to_comma(:bad) }.should raise_error
166
166
  end
167
-
167
+
168
168
  end
169
169
 
170
170
  describe 'with block' do
@@ -172,39 +172,46 @@ describe Comma, 'to_comma data/headers object extensions' do
172
172
  class Foo
173
173
  attr_accessor :content, :created_at, :updated_at
174
174
  comma do
175
- time_to_s = lambda { |i| i && i.to_s(:db) }
176
175
  content
177
176
  content('Truncated Content') {|i| i && i.length > 10 ? i[0..10] : '---' }
178
- created_at &time_to_s
179
- updated_at &time_to_s
177
+ created_at { |i| i && i.to_s(:db) }
178
+ updated_at { |i| i && i.to_s(:db) }
179
+ created_at 'Created Custom Label' do |i| i && i.to_s(:short) end
180
+ updated_at 'Updated at Custom Label' do |i| i && i.to_s(:short) end
180
181
  end
181
-
182
+
182
183
  def initialize(content, created_at = Time.now, updated_at = Time.now)
183
184
  @content = content
184
185
  @created_at = created_at
185
186
  @updated_at = updated_at
186
187
  end
187
188
  end
188
-
189
+
189
190
  @time = Time.now
190
191
  @content = 'content ' * 5
191
192
  @foo = Foo.new @content, @time, @time
192
193
  end
193
-
194
+
194
195
  it 'should return yielded values by block' do
195
196
  header, foo = Array(@foo).to_comma.split("\n")
196
- foo.should == [@content, @content[0..10], @time.to_s(:db), @time.to_s(:db)].join(',')
197
+ foo.should == [@content, @content[0..10], @time.to_s(:db), @time.to_s(:db), @time.to_s(:short), @time.to_s(:short)].join(',')
197
198
  end
198
-
199
+
200
+ it 'should return headers with custom labels from block' do
201
+ header, foo = Array(@foo).to_comma.split("\n")
202
+ header.should == ['Content', 'Truncated Content', 'Created at', 'Updated at', 'Created Custom Label', 'Updated at Custom Label'].join(',')
203
+ end
204
+
199
205
  end
200
-
206
+
207
+
201
208
  describe 'on an object with no comma declaration' do
202
-
209
+
203
210
  it 'should raise an error mentioning there is no comma description defined for that class' do
204
211
  lambda { 'a string'.to_comma }.should raise_error('No comma format for class String defined for style default')
205
212
  lambda { 'a string'.to_comma_headers }.should raise_error('No comma format for class String defined for style default')
206
213
  end
207
-
214
+
208
215
  end
209
-
216
+
210
217
  end
@@ -3,89 +3,89 @@ require File.dirname(__FILE__) + '/../spec_helper'
3
3
  # comma do
4
4
  # name 'Title'
5
5
  # description
6
- #
6
+ #
7
7
  # isbn :number_10 => 'ISBN-10', :number_13 => 'ISBN-13'
8
8
  # end
9
9
 
10
10
  describe Comma::HeaderExtractor do
11
-
11
+
12
12
  before do
13
13
  @isbn = Isbn.new('123123123', '321321321')
14
14
  @book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
15
-
15
+
16
16
  @headers = @book.to_comma_headers
17
17
  end
18
-
18
+
19
19
  describe 'when no parameters are provided' do
20
-
20
+
21
21
  it 'should use the method name as the header name, humanized' do
22
22
  @headers.should include('Description')
23
23
  end
24
24
  end
25
-
25
+
26
26
  describe 'when given a string description as a parameter' do
27
-
27
+
28
28
  it 'should use the string value, unmodified' do
29
29
  @headers.should include('Title')
30
30
  end
31
31
  end
32
-
32
+
33
33
  describe 'when an hash is passed as a parameter' do
34
-
34
+
35
35
  describe 'with a string value' do
36
-
36
+
37
37
  it 'should use the string value, unmodified' do
38
38
  @headers.should include('ISBN-10')
39
39
  end
40
40
  end
41
-
41
+
42
42
  describe 'with a non-string value' do
43
-
43
+
44
44
  it 'should use the non string value converted to a string, humanized' do
45
45
  @headers.should include('Issuer')
46
46
  end
47
47
  end
48
-
48
+
49
49
  end
50
-
50
+
51
51
  end
52
52
 
53
53
  describe Comma::DataExtractor do
54
-
54
+
55
55
  before do
56
56
  @isbn = Isbn.new('123123123', '321321321')
57
57
  @book = Book.new('Smalltalk-80', 'Language and Implementation', @isbn)
58
-
58
+
59
59
  @data = @book.to_comma
60
60
  end
61
-
61
+
62
62
  describe 'when no parameters are provided' do
63
-
63
+
64
64
  it 'should use the string value returned by sending the method name on the object' do
65
65
  @data.should include('Language and Implementation')
66
66
  end
67
67
  end
68
-
68
+
69
69
  describe 'when given a string description as a parameter' do
70
-
70
+
71
71
  it 'should use the string value returned by sending the method name on the object' do
72
72
  @data.should include('Smalltalk-80')
73
73
  end
74
74
  end
75
-
75
+
76
76
  describe 'when an hash is passed as a parameter' do
77
-
77
+
78
78
  describe 'with a string value' do
79
-
79
+
80
80
  it 'should use the string value, returned by sending the hash key to the object' do
81
81
  @data.should include('123123123')
82
82
  @data.should include('321321321')
83
83
  end
84
-
84
+
85
85
  it 'should not fail when an associated object is nil' do
86
86
  lambda { Book.new('Smalltalk-80', 'Language and Implementation', nil).to_comma }.should_not raise_error
87
87
  end
88
88
  end
89
89
  end
90
-
91
- end
90
+
91
+ end
data/spec/spec.opts CHANGED
@@ -1 +1 @@
1
- --colour
1
+ --colour
data/spec/spec_helper.rb CHANGED
@@ -1,27 +1,29 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
- require 'active_record'
3
+ require 'activerecord'
4
+ ActiveRecord::ActiveRecordError # http://tinyurl.com/24f84gf
4
5
 
5
6
  $:.unshift(File.dirname(__FILE__) + '/../lib')
7
+
6
8
  require 'comma'
7
9
 
8
10
 
9
11
  class Book
10
12
  attr_accessor :name, :description, :isbn
11
-
13
+
12
14
  def initialize(name, description, isbn)
13
15
  @name, @description, @isbn = name, description, isbn
14
16
  end
15
-
17
+
16
18
  comma do
17
19
  name 'Title'
18
20
  description
19
-
21
+
20
22
  isbn :authority => :issuer
21
23
  isbn :number_10 => 'ISBN-10'
22
24
  isbn :number_13 => 'ISBN-13'
23
25
  end
24
-
26
+
25
27
  comma :brief do
26
28
  name
27
29
  description
@@ -30,10 +32,10 @@ end
30
32
 
31
33
  class Isbn
32
34
  attr_accessor :number_10, :number_13
33
-
35
+
34
36
  def initialize(isbn_10, isbn_13)
35
37
  @number_10, @number_13 = isbn_10, isbn_13
36
38
  end
37
-
39
+
38
40
  def authority; 'ISBN'; end
39
41
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Marcus Crafter
@@ -9,29 +15,41 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-01-06 00:00:00 +11:00
18
+ date: 2010-10-19 00:00:00 +11:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: rspec
17
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 2
33
+ - 9
23
34
  version: 1.2.9
24
- version:
35
+ type: :development
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: activesupport
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 2
48
+ - 2
49
+ - 2
33
50
  version: 2.2.2
34
- version:
51
+ type: :runtime
52
+ version_requirements: *id002
35
53
  description: Ruby Comma Seperated Values generation library
36
54
  email: crafterm@redartisan.com
37
55
  executables: []
@@ -46,9 +64,11 @@ files:
46
64
  - README.rdoc
47
65
  - Rakefile
48
66
  - VERSION
67
+ - comma.gemspec
49
68
  - init.rb
50
69
  - lib/comma.rb
51
70
  - lib/comma/array.rb
71
+ - lib/comma/association_proxy.rb
52
72
  - lib/comma/extractors.rb
53
73
  - lib/comma/generator.rb
54
74
  - lib/comma/named_scope.rb
@@ -70,21 +90,27 @@ rdoc_options:
70
90
  require_paths:
71
91
  - lib
72
92
  required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
73
94
  requirements:
74
95
  - - ">="
75
96
  - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
76
100
  version: "0"
77
- version:
78
101
  required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
79
103
  requirements:
80
104
  - - ">="
81
105
  - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
82
109
  version: "0"
83
- version:
84
110
  requirements: []
85
111
 
86
112
  rubyforge_project: comma
87
- rubygems_version: 1.3.5
113
+ rubygems_version: 1.3.7
88
114
  signing_key:
89
115
  specification_version: 3
90
116
  summary: Ruby Comma Seperated Values generation library