liangzan-comma 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg
2
+ .swp
3
+ comma.gemspec
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Marcus Crafter
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
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.
@@ -0,0 +1,133 @@
1
+ = COMMA
2
+
3
+ http://github.com/crafterm/comma
4
+
5
+ == DESCRIPTION:
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.
8
+
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
+
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
+
13
+ An example Comma CSV enabled ActiveRecord class:
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
40
+
41
+ Annotated, the comma description is as follows:
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
+
64
+ 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
+
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
+
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
+
70
+ Multiple CSV descriptions can also be specified for the same class, eg:
71
+
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
+
106
+ You can specify which output format you would like to use via an optional parameter to to_comma:
107
+
108
+ Book.limited(10).to_comma(:brief)
109
+
110
+ Specifying no description name to to_comma is equivalent to specifying :default as the description name.
111
+
112
+ You can pass options for FasterCVS, e.g.
113
+
114
+ Book.limited(10).to_comma(:style => :brief, :col_sep => ';', :force_quotes => true)
115
+
116
+ When used with Rails (ie. add 'comma' as a gem dependency), Comma automatically adds support for rendering CSV output in your controllers:
117
+
118
+ class BooksController < ApplicationController
119
+
120
+ def index
121
+ respond_to do |format|
122
+ format.csv { render :csv => Book.limited(50) }
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ If you have any questions or suggestions for Comma, please feel free to contact me at crafterm@redartisan.com, all feedback welcome!
129
+
130
+ == DEPENDENCIES
131
+
132
+ If you're on ruby 1.8.*, the fasterCSV gem is recommended for performance reasons.
133
+ gem install fastercsv
@@ -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.1
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'comma'
@@ -0,0 +1,39 @@
1
+ # conditional loading of activesupport
2
+ if defined? Rails and Rails.version < '2.3.5'
3
+ require 'activesupport'
4
+ else
5
+ require 'active_support'
6
+ end
7
+
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"
21
+ end
22
+ require 'csv'
23
+ FasterCSV = CSV
24
+ end
25
+ end
26
+
27
+ require 'comma/extractors'
28
+ require 'comma/generator'
29
+ require 'comma/array'
30
+ require 'comma/object'
31
+ require 'comma/render_as_csv'
32
+
33
+ if defined?(ActiveRecord)
34
+ require 'comma/namedscope'
35
+ end
36
+
37
+ if defined?(ActionController)
38
+ ActionController::Base.send :include, RenderAsCSV
39
+ end
@@ -0,0 +1,5 @@
1
+ class Array
2
+ def to_comma(style = :default)
3
+ Comma::Generator.new(self, style).run(:each)
4
+ end
5
+ end
@@ -0,0 +1,75 @@
1
+ module Comma
2
+
3
+ class Extractor
4
+
5
+ def initialize(instance, &block)
6
+ @instance = instance
7
+ @block = block
8
+ @results = []
9
+ end
10
+
11
+ def results
12
+ instance_eval &@block
13
+ @results
14
+ end
15
+
16
+ def id(*args)
17
+ method_missing(:id, *args)
18
+ end
19
+ end
20
+
21
+ class HeaderExtractor < Extractor
22
+
23
+ def method_missing(sym, *args, &block)
24
+ @results << sym.to_s.humanize if args.blank?
25
+
26
+ args.each do |arg|
27
+ case arg
28
+ when Hash
29
+ arg.each do |k, v|
30
+ @results << ((v.is_a? String) ? v : v.to_s.humanize)
31
+ end
32
+ when Symbol
33
+ @results << arg.to_s.humanize
34
+ when String
35
+ @results << arg
36
+ else
37
+ raise "Unknown header symbol #{arg.inspect}"
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ class DataExtractor < Extractor
44
+
45
+ def method_missing(sym, *args, &block)
46
+ if args.blank?
47
+ result = block ? yield(@instance.send(sym)) : @instance.send(sym)
48
+ @results << result.to_s
49
+ end
50
+
51
+ args.each do |arg|
52
+ case arg
53
+ when Hash
54
+ arg.each do |k, v|
55
+ if block
56
+ @results << (@instance.send(sym).nil? ? '' : yield(@instance.send(sym).send(k)).to_s )
57
+ else
58
+ @results << (@instance.send(sym).nil? ? '' : @instance.send(sym).send(k).to_s )
59
+ end
60
+ end
61
+ when Symbol
62
+ if block
63
+ @results << (@instance.send(sym).nil? ? '' : yield(@instance.send(sym).send(arg)).to_s)
64
+ else
65
+ @results << ( @instance.send(sym).nil? ? '' : @instance.send(sym).send(arg).to_s )
66
+ end
67
+ when String
68
+ @results << (block ? yield(@instance.send(sym)) : @instance.send(sym)).to_s
69
+ else
70
+ raise "Unknown data symbol #{arg.inspect}"
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -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
@@ -0,0 +1,6 @@
1
+ class ActiveRecord::NamedScope::Scope
2
+ def to_comma(style = :default)
3
+ Comma::Generator.new(self, style).run(:find_each)
4
+ end
5
+ end
6
+
@@ -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,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
@@ -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
@@ -0,0 +1 @@
1
+ --colour
@@ -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 ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: liangzan-comma
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ platform: ruby
6
+ authors:
7
+ - Marcus Crafter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-16 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.2.2
34
+ version:
35
+ description: Ruby Comma Seperated Values generation library
36
+ email: crafterm@redartisan.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - README.rdoc
43
+ files:
44
+ - .gitignore
45
+ - MIT-LICENSE
46
+ - README.rdoc
47
+ - Rakefile
48
+ - VERSION
49
+ - init.rb
50
+ - lib/comma.rb
51
+ - lib/comma/array.rb
52
+ - lib/comma/extractors.rb
53
+ - lib/comma/generator.rb
54
+ - lib/comma/namedscope.rb
55
+ - lib/comma/object.rb
56
+ - lib/comma/render_as_csv.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
62
+ has_rdoc: true
63
+ homepage: http://github.com/crafterm/comma
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project: comma
86
+ rubygems_version: 1.3.5
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Ruby Comma Seperated Values generation library
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