active_export 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -5,6 +5,6 @@
5
5
  _yardoc
6
6
  doc/
7
7
  coverage
8
- tmp
8
+ tmp/*
9
9
  log/*
10
10
  Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+ - ruby-head
5
+ - rbx-19mode
6
+ gemfile:
7
+ - spec/gemfiles/Gemfile.rails.3.0
8
+ - spec/gemfiles/Gemfile.rails.3.1
9
+ - spec/gemfiles/Gemfile.rails.3.2
10
+ branches:
11
+ only:
12
+ - master
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gemspec
5
5
 
6
6
  group :development, :test do
7
7
  gem 'rake', '~> 0.9.2.2', :require => false
8
- gem 'rails', ">= #{ENV['RAILS'] || '3.0.0'}"
8
+ gem 'rails', ">= 3.0.0"
9
9
 
10
10
  gem 'yard'
11
11
  gem 'rdiscount'
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ActiveExport
1
+ # ActiveExport [![Build Status](https://secure.travis-ci.org/kengos/active_export.png?branch=master)](http://travis-ci.org/kengos/active_export)[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/kengos/active_export)
2
2
 
3
3
  ActiveExport generate from ActiveRecord or others to CSV String or CSV file.
4
4
 
@@ -18,6 +18,30 @@ module ActiveExport
18
18
  end
19
19
 
20
20
  class << self
21
+ # Generate Csv String
22
+ # @param [Array, ActiveRecord::Relation] data
23
+ # @param [Symbol, String] source
24
+ # @param [Symobl, String] namespace
25
+ # @param [Hash] options ({})
26
+ # @option options [Array] :eval_methods
27
+ # @option options [Array] :label_keys
28
+ # @option options [String] :label_prefix
29
+ # @option options [Hash] :csv_options (see http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html)
30
+ # @return [String] Csv String
31
+ def export(data, source, namespace, options = {})
32
+ new(source, namespace, options).export(data)
33
+ end
34
+
35
+ # Generate Csv File
36
+ # @param [Array, ActiveRecord::Relation] data
37
+ # @param [Symbol, String] source YAML File alias name (see ActiveExport::Configuration#sources)
38
+ # @param [Symbol, String] namespace YAML File namespace
39
+ # @param [String, Filepath] filename Csv File name
40
+ # @param [Hash] options ({}) (see .export)
41
+ def export_file(data, source, namespace, filename, options = {})
42
+ new(source, namespace, options).export_file(data, filename)
43
+ end
44
+
21
45
  def translate(key, scope = [])
22
46
  defaults = [
23
47
  :"active_export.#{scope.join('.')}.#{key.to_s.gsub('.', '_')}",
@@ -46,6 +70,19 @@ module ActiveExport
46
70
  end
47
71
  end
48
72
 
73
+ # Export data to exporter
74
+ # @param [Array, ActiveRecord::Relation] data Export target data
75
+ # @param [Object] Object needs to support '<<' accessor
76
+ def export_data(data, exporter)
77
+ if data.respond_to?(:find_in_batches) && data.respond_to?(:orders) && data.orders.blank? && data.respond_to?(:taken) && data.taken.blank?
78
+ data.find_in_batches(find_in_batches_options) do |group|
79
+ group.each{|f| exporter << generate_value(f) }
80
+ end
81
+ else
82
+ data.each{|f| exporter << generate_value(f) }
83
+ end
84
+ end
85
+
49
86
  # Convert value for export string
50
87
  # @todo refactor me
51
88
  def convert(value)
@@ -98,5 +135,24 @@ module ActiveExport
98
135
  def translate(key, scope = nil)
99
136
  self.class.translate(key, scope || default_scope)
100
137
  end
138
+
139
+ protected
140
+
141
+ def generate_header
142
+ self.label_keys.inject([]) {|result, key|
143
+ result << translate(key_name(key))
144
+ }
145
+ end
146
+
147
+ def generate_value(row)
148
+ self.eval_methods.inject([]){|result, f|
149
+ v = row.send(:eval, f) rescue nil
150
+ result << convert(v)
151
+ }
152
+ end
153
+
154
+ def find_in_batches_options
155
+ self.config.default_find_in_batches_options.merge( self.options[:find_in_batches_options] || {} )
156
+ end
101
157
  end
102
158
  end
@@ -4,32 +4,6 @@ require 'csv'
4
4
 
5
5
  module ActiveExport
6
6
  class Csv < ::ActiveExport::Base
7
- # Generate Csv String
8
- # @param [Array, ActiveRecord::Relation] data
9
- # @param [Symbol, String] source
10
- # @param [Symobl, String] namespace
11
- # @param [Hash] options ({})
12
- # @option options [Array] :eval_methods
13
- # @option options [Array] :label_keys
14
- # @option options [String] :label_prefix
15
- # @option options [Hash] :csv_options (see http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html)
16
- # @return [String] Csv String
17
- # @exmaple
18
- # AcriveExport::Csv.export(data, :source, :namespace)
19
- def self.export(data, source, namespace, options = {})
20
- new(source, namespace, options).export(data)
21
- end
22
-
23
- # Generate Csv File
24
- # @param [Array, ActiveRecord::Relation] data
25
- # @param [Symbol, String] source YAML File alias name (see ActiveExport::Configuration#sources)
26
- # @param [Symbol, String] namespace YAML File namespace
27
- # @param [String, Filepath] filename Csv File name
28
- # @param [Hash] options ({}) (see .export)
29
- def self.export_file(data, source, namespace, filename, options = {})
30
- new(source, namespace, options).export_file(data, filename)
31
- end
32
-
33
7
  def export(data)
34
8
  CSV.generate(csv_options) do |csv|
35
9
  csv << generate_header if header?
@@ -38,7 +12,7 @@ module ActiveExport
38
12
  end
39
13
 
40
14
  def export_file(data, filename)
41
- File.atomic_write(filename) do |file|
15
+ File.atomic_write(filename.to_s) do |file|
42
16
  CSV.open(file, "wb", csv_options) do |csv|
43
17
  csv << generate_header if header?
44
18
  export_data(data, csv)
@@ -47,36 +21,7 @@ module ActiveExport
47
21
  filename
48
22
  end
49
23
 
50
- # Export data to exporter
51
- # @param [Array, ActiveRecord::Relation] data Export target data
52
- # @param [CSV, Array, String] exporter CSV class or Array class, or String class (should support '<<' accessor)
53
- def export_data(data, exporter)
54
- if data.respond_to?(:find_in_batches) && data.respond_to?(:orders) && data.orders.blank? && data.respond_to?(:taken) && data.taken.blank?
55
- data.find_in_batches(find_in_batches_options) do |group|
56
- group.each{|f| exporter << generate_value(f) }
57
- end
58
- else
59
- data.each{|f| exporter << generate_value(f) }
60
- end
61
- end
62
-
63
24
  protected
64
- def generate_header
65
- self.label_keys.inject([]) {|result, key|
66
- result << translate(key_name(key))
67
- }
68
- end
69
-
70
- def generate_value(row)
71
- self.eval_methods.inject([]){|result, f|
72
- v = row.send(:eval, f) rescue nil
73
- result << convert(v)
74
- }
75
- end
76
-
77
- def find_in_batches_options
78
- self.config.default_find_in_batches_options.merge( self.options[:find_in_batches_options] || {} )
79
- end
80
25
 
81
26
  def csv_options
82
27
  self.config.default_csv_options.merge( self.options[:csv_options] || {} )
@@ -1,3 +1,3 @@
1
1
  module ActiveExport
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+
3
+ module ActiveExport
4
+ class Xml < ::ActiveExport::Base
5
+ # @return [String] XML style string
6
+ def export(data)
7
+ str = ''
8
+ str << source[:xml_format][:header]
9
+ [].tap {|o| export_data(data, o)}.inject([]) do |result, f|
10
+ result << {}.tap{|o|
11
+ self.label_keys.each_with_index {|k, i| o[k] = f[i] }
12
+ }
13
+ end.each do |f|
14
+ str << binding(f)
15
+ end
16
+ str << source[:xml_format][:footer]
17
+ str
18
+ end
19
+
20
+ def export_file(data, filename)
21
+ File.atomic_write(filename.to_s) do |file|
22
+ file.write export(data)
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ # @params [Hash] values Format: { label_1: value_1, ... }
29
+ def binding(values)
30
+ result_string = binding_source.dup
31
+ values.each_pair do |k,v|
32
+ result_string.gsub!("%%#{k}%%", v)
33
+ end
34
+ result_string
35
+ end
36
+
37
+ def binding_source
38
+ @xml_body ||= source[:xml_format][:body]
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ module ActiveExport
6
+ class Yaml < ::ActiveExport::Base
7
+ # @return [String] YAML style string
8
+ # @memo output format(i want)
9
+ # -
10
+ # - label: value
11
+ # - label: value
12
+ def export(data)
13
+ [].tap {|o|
14
+ export_data(data, o)
15
+ }.to_yaml
16
+ end
17
+
18
+ def export_file(data, filename)
19
+ File.atomic_write(filename.to_s) do |file|
20
+ file.write export(data)
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/active_export.rb CHANGED
@@ -6,6 +6,8 @@ require 'erb'
6
6
  module ActiveExport
7
7
  autoload :Base, 'active_export/base'
8
8
  autoload :Csv, 'active_export/csv'
9
+ autoload :Yaml, 'active_export/yaml'
10
+ autoload :Xml, 'active_export/xml'
9
11
 
10
12
  class << self
11
13
  # @example
@@ -74,6 +74,43 @@ describe ActiveExport::Base do
74
74
  end
75
75
  end
76
76
 
77
+ describe "#export_data" do
78
+ let(:csv_exporter) { ActiveExport::Base.new(:default, :book_1) }
79
+ let!(:book_1) { Book.create!(name: 'book_1', author: nil, price: 58) }
80
+ let!(:book_2) { Book.create!(name: 'book_2', author: nil, price: 58) }
81
+ let!(:book_3) { Book.create!(name: 'book_2', author: nil, price: 58) }
82
+
83
+ it "should not call find_in_batches when has order" do
84
+ obj = Book.order('id ASC')
85
+ obj.should_not_receive(:find_in_batches)
86
+ obj.should_receive(:each)
87
+ csv_exporter.send(:export_data, obj, [])
88
+ end
89
+
90
+
91
+ it "should not call find_in_batches when has limit" do
92
+ obj = Book.limit(1)
93
+ obj.should_not_receive(:find_in_batches)
94
+ obj.should_receive(:each)
95
+ csv_exporter.send(:export_data, obj, [])
96
+ end
97
+
98
+ it "should not call find_in_batches when specified obj is not ActiveRecord::Relation" do
99
+ obj = [Book.first]
100
+ obj.should_not_receive(:find_in_batches)
101
+ obj.should_receive(:each)
102
+ csv_exporter.send(:export_data, obj, [])
103
+ end
104
+
105
+ it "should call find_in_batches" do
106
+ obj = Book.scoped
107
+ obj.should_receive(:find_in_batches).with({batch_size: 1})
108
+ obj.should_not_receive(:each)
109
+ csv_exporter.stub(:find_in_batches_options).and_return({batch_size: 1})
110
+ csv_exporter.send(:export_data, obj, [])
111
+ end
112
+ end
113
+
77
114
  describe ".translate" do
78
115
  let(:i18n_key) { 'author.name' }
79
116
  subject { ActiveExport::Base.translate('author.name', [:default, :book]) }
@@ -71,43 +71,6 @@ book_2:author_2:38
71
71
  it { File.read(filename).split("\n").first.should eql %Q("Book name","Author name","Book price") }
72
72
  end
73
73
 
74
- describe "#export_data" do
75
- let(:csv_exporter) { ActiveExport::Csv.new(:default, :book_1) }
76
- let!(:book_1) { Book.create!(name: 'book_1', author: nil, price: 58) }
77
- let!(:book_2) { Book.create!(name: 'book_2', author: nil, price: 58) }
78
- let!(:book_3) { Book.create!(name: 'book_2', author: nil, price: 58) }
79
-
80
- it "should not call find_in_batches when has order" do
81
- obj = Book.order('id ASC')
82
- obj.should_not_receive(:find_in_batches)
83
- obj.should_receive(:each)
84
- csv_exporter.send(:export_data, obj, [])
85
- end
86
-
87
-
88
- it "should not call find_in_batches when has limit" do
89
- obj = Book.limit(1)
90
- obj.should_not_receive(:find_in_batches)
91
- obj.should_receive(:each)
92
- csv_exporter.send(:export_data, obj, [])
93
- end
94
-
95
- it "should not call find_in_batches when specified obj is not ActiveRecord::Relation" do
96
- obj = [Book.first]
97
- obj.should_not_receive(:find_in_batches)
98
- obj.should_receive(:each)
99
- csv_exporter.send(:export_data, obj, [])
100
- end
101
-
102
- it "should call find_in_batches" do
103
- obj = Book.scoped
104
- obj.should_receive(:find_in_batches).with({batch_size: 1})
105
- obj.should_not_receive(:each)
106
- csv_exporter.stub(:find_in_batches_options).and_return({batch_size: 1})
107
- csv_exporter.send(:export_data, obj, [])
108
- end
109
- end
110
-
111
74
  describe ".generate_value" do
112
75
  let(:author_1) { Author.create!(name: 'author_1') }
113
76
  let!(:book_1) { Book.create!(name: 'book_1', author: author_1, price: 1000) }
@@ -0,0 +1,50 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActiveExport::Xml do
6
+ before {
7
+ ActiveExport.configure do |config|
8
+ config.sources = { xml: fixture_file('xml.yml') }
9
+ end
10
+ }
11
+
12
+ let(:author_1) { Author.create!(name: 'author_1') }
13
+ let(:author_2) { Author.create!(name: 'author_2') }
14
+ let!(:book_1) { Book.create!(name: 'book_1', author: author_1, price: 58) }
15
+ let!(:book_2) { Book.create!(name: 'book_2', author: author_2, price: 38) }
16
+
17
+ let(:expect_string) {
18
+ <<-EOS
19
+ <?xml version="1.0" encoding="UTF-8"?>
20
+ <records>
21
+ <book>
22
+ <name>book_1</name>
23
+ <author_name>author_1</author_name>
24
+ <price>63.51</price>
25
+ </book>
26
+ <book>
27
+ <name>book_2</name>
28
+ <author_name>author_2</author_name>
29
+ <price>41.61</price>
30
+ </book>
31
+ </records>
32
+ EOS
33
+ }
34
+ describe ".export" do
35
+ subject { ActiveExport::Xml.export(Book.scoped, :xml, :book_1) }
36
+ it { should == expect_string }
37
+ end
38
+
39
+ describe ".export_file" do
40
+ let(:xml_file) { Rails.root.join('tmp', 'test.xml') }
41
+ before {
42
+ FileUtils.rm yaml_file if FileTest.exist?(xml_file)
43
+ ActiveExport::Xml.export_file(Book.scoped, :xml, :book_1, xml_file)
44
+ }
45
+ after {
46
+ FileUtils.rm xml_file if FileTest.exist?(xml_file)
47
+ }
48
+ it { File.read(xml_file).should == expect_string }
49
+ end
50
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActiveExport::Yaml do
6
+ before {
7
+ ActiveExport.configure do |config|
8
+ config.sources = { default: fixture_file('csv_1.yml') }
9
+ end
10
+ }
11
+
12
+ describe ".export" do
13
+ let(:author_1) { Author.create!(name: 'author_1') }
14
+ let(:author_2) { Author.create!(name: 'author_2') }
15
+ let!(:book_1) { Book.create!(name: 'book_1', author: author_1, price: 58) }
16
+ let!(:book_2) { Book.create!(name: 'book_2', author: author_2, price: 38) }
17
+
18
+ let(:yaml_string) { ActiveExport::Yaml.export(Book.order('id DESC').all, :default, :book_2) }
19
+ subject { YAML.load(yaml_string) }
20
+ its([0]) { should == ["book_2", "author_2", "42"] }
21
+ its([1]) { should == ["book_1", "author_1", "64"] }
22
+ end
23
+
24
+ describe ".export_file" do
25
+ let(:author_1) { Author.create!(name: 'author_1') }
26
+ let(:author_2) { Author.create!(name: 'author_2') }
27
+ let!(:book_1) { Book.create!(name: 'book_1', author: author_1, price: 58) }
28
+ let!(:book_2) { Book.create!(name: 'book_2', author: author_2, price: 38) }
29
+ let(:yaml_file) { Rails.root.join('tmp', 'test.yml') }
30
+ before {
31
+ FileUtils.rm yaml_file if FileTest.exist?(yaml_file)
32
+ ActiveExport::Yaml.export_file(Book.scoped, :default, :book_2, yaml_file)
33
+ }
34
+ after {
35
+ FileUtils.rm yaml_file if FileTest.exist?(yaml_file)
36
+ }
37
+ subject { YAML.load(File.read(yaml_file)) }
38
+ its([0]) { should == ["book_1", "author_1", "64"] }
39
+ its([1]) { should == ["book_2", "author_2", "42"] }
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ book_1:
2
+ label_prefix: 'book'
3
+ methods:
4
+ - name
5
+ - author.name
6
+ - price: 'price * 1.095'
7
+ xml_format:
8
+ encoding: 'UTF-8'
9
+ header: |
10
+ <?xml version="1.0" encoding="UTF-8"?>
11
+ <records>
12
+ footer: |
13
+ </records>
14
+ body: |
15
+ <book>
16
+ <name>%%name%%</name>
17
+ <author_name>%%author.name%%</author_name>
18
+ <price>%%price%%</price>
19
+ </book>
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'rails', "3.0.16"
5
+
6
+ gem 'sqlite3'
7
+ gem 'rspec-rails'
8
+ gem 'factory_girl_rails'
9
+ gem 'database_cleaner'
10
+ end
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'rails', "3.1.7"
5
+
6
+ gem 'sqlite3'
7
+ gem 'rspec-rails'
8
+ gem 'factory_girl_rails'
9
+ gem 'database_cleaner'
10
+ end
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ group :test do
4
+ gem 'rails', "3.2.8"
5
+
6
+ gem 'sqlite3'
7
+ gem 'rspec-rails'
8
+ gem 'factory_girl_rails'
9
+ gem 'database_cleaner'
10
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,8 @@
1
- require 'tapp'
1
+ begin
2
+ require 'tapp'
3
+ rescue Exception
4
+ end
5
+
2
6
  require 'rails/rails_support'
3
7
  require 'rspec'
4
8
  require 'rspec/rails'
data/tasks/yard.rake CHANGED
@@ -1,6 +1,11 @@
1
- require 'yard'
2
- require 'yard/rake/yardoc_task'
1
+ begin
3
2
 
4
- YARD::Rake::YardocTask.new do |t|
5
- t.files = ['lib/**/*.rb']
3
+ require 'yard'
4
+ require 'yard/rake/yardoc_task'
5
+
6
+ YARD::Rake::YardocTask.new do |t|
7
+ t.files = ['lib/**/*.rb']
8
+ end
9
+
10
+ rescue Exception
6
11
  end
data/tmp/.gitkeep ADDED
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_export
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-19 00:00:00.000000000 Z
12
+ date: 2012-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -35,6 +35,7 @@ extensions: []
35
35
  extra_rdoc_files: []
36
36
  files:
37
37
  - .gitignore
38
+ - .travis.yml
38
39
  - .yardopts
39
40
  - Gemfile
40
41
  - Guardfile
@@ -47,12 +48,20 @@ files:
47
48
  - lib/active_export/configuration.rb
48
49
  - lib/active_export/csv.rb
49
50
  - lib/active_export/version.rb
51
+ - lib/active_export/xml.rb
52
+ - lib/active_export/yaml.rb
50
53
  - spec/active_export/base_spec.rb
51
54
  - spec/active_export/csv_spec.rb
52
55
  - spec/active_export/rails_support_spec.rb
56
+ - spec/active_export/xml_spec.rb
57
+ - spec/active_export/yaml_spec.rb
53
58
  - spec/active_export_spec.rb
54
59
  - spec/factories/book.rb
55
60
  - spec/fixtures/csv_1.yml
61
+ - spec/fixtures/xml.yml
62
+ - spec/gemfiles/Gemfile.rails.3.0
63
+ - spec/gemfiles/Gemfile.rails.3.1
64
+ - spec/gemfiles/Gemfile.rails.3.2
56
65
  - spec/rails/model/author.rb
57
66
  - spec/rails/model/book.rb
58
67
  - spec/rails/model/book_category.rb
@@ -61,6 +70,7 @@ files:
61
70
  - spec/rails/schema.rb
62
71
  - spec/spec_helper.rb
63
72
  - tasks/yard.rake
73
+ - tmp/.gitkeep
64
74
  homepage: https://github.com/kengos/active_export
65
75
  licenses: []
66
76
  post_install_message:
@@ -89,9 +99,15 @@ test_files:
89
99
  - spec/active_export/base_spec.rb
90
100
  - spec/active_export/csv_spec.rb
91
101
  - spec/active_export/rails_support_spec.rb
102
+ - spec/active_export/xml_spec.rb
103
+ - spec/active_export/yaml_spec.rb
92
104
  - spec/active_export_spec.rb
93
105
  - spec/factories/book.rb
94
106
  - spec/fixtures/csv_1.yml
107
+ - spec/fixtures/xml.yml
108
+ - spec/gemfiles/Gemfile.rails.3.0
109
+ - spec/gemfiles/Gemfile.rails.3.1
110
+ - spec/gemfiles/Gemfile.rails.3.2
95
111
  - spec/rails/model/author.rb
96
112
  - spec/rails/model/book.rb
97
113
  - spec/rails/model/book_category.rb