rexport 0.5.4 → 1.0.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.
- checksums.yaml +5 -5
- data/Rakefile +6 -34
- data/app/views/export_filters/_export_filter.html.erb +2 -2
- data/app/views/export_items/_export_item.html.erb +2 -2
- data/app/views/exports/_edit.html.erb +2 -2
- data/app/views/exports/_filters.html.erb +1 -1
- data/app/views/exports/_form.html.erb +6 -6
- data/app/views/exports/_rexport_model.html.erb +1 -1
- data/app/views/exports/_show.html.erb +6 -6
- data/app/views/exports/edit.html.erb +1 -1
- data/app/views/exports/index.html.erb +5 -5
- data/app/views/exports/new.html.erb +2 -2
- data/app/views/exports/show.html.erb +1 -1
- data/config/routes.rb +6 -6
- data/db/migrate/20091105182959_create_export_tables.rb +3 -3
- data/lib/rexport.rb +3 -1
- data/lib/rexport/data_field.rb +17 -0
- data/lib/rexport/data_fields.rb +25 -56
- data/lib/rexport/export_filter_methods.rb +46 -24
- data/lib/rexport/export_item_methods.rb +29 -34
- data/lib/rexport/export_methods.rb +161 -208
- data/lib/rexport/exports_controller_methods.rb +22 -28
- data/lib/rexport/rexport_model.rb +33 -0
- data/lib/rexport/tree_node.rb +13 -16
- data/lib/rexport/version.rb +1 -1
- data/test/factories.rb +58 -53
- data/test/test_helper.rb +29 -33
- data/test/unit/data_field_test.rb +11 -11
- data/test/unit/data_fields_test.rb +137 -95
- data/test/unit/export_filter_methods_test.rb +37 -0
- data/test/unit/export_item_methods_test.rb +21 -0
- data/test/unit/export_methods_test.rb +185 -59
- data/test/unit/rexport_model_test.rb +12 -12
- data/test/unit/tree_node_test.rb +20 -20
- metadata +14 -26
- data/test/jenkins.bash +0 -3
- data/test/log/test.log +0 -3891
@@ -3,73 +3,67 @@ module Rexport
|
|
3
3
|
def index
|
4
4
|
@exports = Export.categorical.alphabetical
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
def show
|
8
8
|
@export = Export.find(params[:id])
|
9
|
-
|
9
|
+
|
10
10
|
respond_to do |format|
|
11
11
|
format.html # show.html.erb
|
12
|
-
format.csv { send_data(@export.to_csv, :
|
12
|
+
format.csv { send_data(@export.to_csv, type: export_content_type, filename: filename) }
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def new
|
17
17
|
@export = Export.new(export_params)
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def edit
|
21
21
|
@export = Export.find(params[:id])
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def create
|
25
25
|
@export = params[:original_export_id] ? Export.find(params[:original_export_id]).copy : Export.new(export_params)
|
26
|
-
|
26
|
+
|
27
27
|
if @export.save
|
28
28
|
redirect_to @export, notice: 'Export was successfully created.'
|
29
29
|
else
|
30
30
|
render :new
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def update
|
35
35
|
@export = Export.find(params[:id])
|
36
|
-
|
36
|
+
|
37
37
|
if @export.update_attributes(export_params)
|
38
38
|
redirect_to @export, notice: 'Export was successfully updated.'
|
39
39
|
else
|
40
40
|
render :edit
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
def destroy
|
45
45
|
@export = Export.find(params[:id])
|
46
46
|
@export.destroy
|
47
|
-
|
47
|
+
|
48
48
|
redirect_to exports_url
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
private
|
52
|
-
|
52
|
+
|
53
53
|
def export_params
|
54
|
-
params.require(:export).permit(
|
54
|
+
params.require(:export).permit(
|
55
|
+
:name,
|
56
|
+
:model_class_name,
|
57
|
+
:description,
|
58
|
+
rexport_fields: {},
|
59
|
+
export_filter_attributes: {}
|
60
|
+
)
|
55
61
|
end
|
56
|
-
|
57
|
-
def rexport_fields
|
58
|
-
permit_all params[:export][:rexport_fields]
|
59
|
-
end
|
60
|
-
|
61
|
-
def export_filter_attributes
|
62
|
-
permit_all params[:export][:export_filter_attributes]
|
63
|
-
end
|
64
|
-
|
65
|
-
def permit_all(params)
|
66
|
-
params ? params.permit! : []
|
67
|
-
end
|
68
|
-
|
62
|
+
|
69
63
|
def export_content_type
|
70
64
|
request.user_agent =~ /windows/i ? 'application/vnd.ms-excel' : 'text/csv'
|
71
65
|
end
|
72
|
-
|
66
|
+
|
73
67
|
def filename
|
74
68
|
"#{@export.model_class_name}_#{@export.name.gsub(/ /, '_')}_#{Time.now.strftime('%Y%m%d')}.csv"
|
75
69
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rexport #:nodoc:
|
2
|
+
class RexportModel
|
3
|
+
attr_accessor :klass, :path
|
4
|
+
|
5
|
+
def initialize(klass, path = nil)
|
6
|
+
self.klass = klass
|
7
|
+
self.path = path.to_s unless path.blank?
|
8
|
+
end
|
9
|
+
|
10
|
+
def rexport_fields_array
|
11
|
+
klass.rexport_fields_array
|
12
|
+
end
|
13
|
+
|
14
|
+
def field_path(field_name)
|
15
|
+
[path, field_name].compact * '.'
|
16
|
+
end
|
17
|
+
|
18
|
+
def collection_from_association(association)
|
19
|
+
return klass.send("find_#{association}_for_rexport") if klass.respond_to?("find_#{association}_for_rexport")
|
20
|
+
klass.reflect_on_association(association.to_sym).klass.all
|
21
|
+
end
|
22
|
+
|
23
|
+
def filter_column(field)
|
24
|
+
return field.method unless field.method.include?('.')
|
25
|
+
association = field.method.split('.').first
|
26
|
+
klass.reflect_on_association(association.to_sym).foreign_key
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
klass.name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/rexport/tree_node.rb
CHANGED
@@ -2,44 +2,41 @@ module Rexport #:nodoc:
|
|
2
2
|
# A basic tree for building up ActiveRecord find :include parameters
|
3
3
|
class TreeNode
|
4
4
|
attr_accessor :name, :children
|
5
|
-
|
5
|
+
|
6
6
|
# Initialize a tree node setting name and adding a child if one was passed
|
7
7
|
def initialize(name, *names)
|
8
8
|
self.name = name
|
9
9
|
self.children = []
|
10
10
|
add_child(names)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# Add one or more children to the tree
|
14
14
|
def add_child(*names)
|
15
15
|
names.flatten!
|
16
16
|
return unless name = names.shift
|
17
|
-
|
18
|
-
|
19
|
-
else
|
20
|
-
children << TreeNode.new(name, names)
|
21
|
-
end
|
17
|
+
node = children.find { |c| c.name == name }
|
18
|
+
node ? node.add_child(names) : (children << TreeNode.new(name, names))
|
22
19
|
end
|
23
|
-
|
20
|
+
|
24
21
|
# Return an array representation of the tree
|
25
22
|
def to_a
|
26
|
-
[name, children.map
|
23
|
+
[name, children.map(&:to_a)]
|
27
24
|
end
|
28
|
-
|
25
|
+
|
29
26
|
# Return a :include comptatible statement from the tree
|
30
27
|
def to_include
|
31
|
-
children.map
|
28
|
+
children.map(&:build_include)
|
32
29
|
end
|
33
|
-
|
30
|
+
|
34
31
|
# Return the include parameters for a child
|
35
32
|
def build_include
|
36
|
-
leaf_node? ? name.to_sym : { name.to_sym => children.map
|
33
|
+
leaf_node? ? name.to_sym : { name.to_sym => children.map(&:build_include) }
|
37
34
|
end
|
38
|
-
|
35
|
+
|
39
36
|
private
|
40
|
-
|
37
|
+
|
41
38
|
def leaf_node?
|
42
39
|
children.blank?
|
43
40
|
end
|
44
41
|
end
|
45
|
-
end
|
42
|
+
end
|
data/lib/rexport/version.rb
CHANGED
data/test/factories.rb
CHANGED
@@ -1,86 +1,91 @@
|
|
1
1
|
module Rexport
|
2
2
|
module Factories
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
|
4
|
+
FactoryBot.define do
|
5
|
+
|
6
6
|
factory :status do
|
7
|
-
name 'active'
|
7
|
+
name { 'active' }
|
8
8
|
end
|
9
9
|
|
10
10
|
factory :family do
|
11
|
-
name 'The Sample Family'
|
11
|
+
name { 'The Sample Family' }
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
factory :student do
|
15
|
-
family {|
|
16
|
-
name 'Sammy Sample'
|
17
|
-
date_of_birth Date.parse('2008-12-08')
|
15
|
+
family { |family| family.association(:family) }
|
16
|
+
name { 'Sammy Sample' }
|
17
|
+
date_of_birth { Date.parse('2008-12-08') }
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
factory :enrollment do
|
21
|
-
status
|
22
|
-
student
|
23
|
-
grade
|
21
|
+
status { |status| status.association(:status) }
|
22
|
+
student { |student| student.association(:student) }
|
23
|
+
grade { 1 }
|
24
|
+
updated_at { Time.now }
|
24
25
|
end
|
25
|
-
|
26
|
-
factory :second_grade_enrollment, :
|
27
|
-
status
|
28
|
-
grade 2
|
26
|
+
|
27
|
+
factory :second_grade_enrollment, class: 'Enrollment' do
|
28
|
+
status { |status| status.association(:status) }
|
29
|
+
grade { 2 }
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
factory :export do
|
32
|
-
name 'Enrollment Export'
|
33
|
-
model_class_name 'Enrollment'
|
33
|
+
name { 'Enrollment Export' }
|
34
|
+
model_class_name { 'Enrollment' }
|
34
35
|
export_items do |items|
|
35
36
|
%w(family_name_export_item grade_export_item status_name_export_item bogus_export_item).map do |item|
|
36
37
|
items.association(item)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
40
|
-
|
41
|
-
factory :filtered_export, :
|
42
|
-
name 'Filtered Enrollment Export'
|
43
|
-
model_class_name 'Enrollment'
|
41
|
+
|
42
|
+
factory :filtered_export, class: 'Export' do
|
43
|
+
name { 'Filtered Enrollment Export' }
|
44
|
+
model_class_name { 'Enrollment' }
|
45
|
+
export_items do |items|
|
46
|
+
%w(grade_export_item status_name_export_item).map do |item|
|
47
|
+
items.association(item)
|
48
|
+
end
|
49
|
+
end
|
44
50
|
export_filters do |filters|
|
45
51
|
%w(grade_filter status_filter).map do |filter|
|
46
52
|
filters.association(filter)
|
47
53
|
end
|
48
54
|
end
|
49
55
|
end
|
50
|
-
|
51
|
-
factory :family_name_export_item, :
|
52
|
-
position 1
|
53
|
-
name 'Family Name'
|
54
|
-
rexport_field 'student.family.name'
|
56
|
+
|
57
|
+
factory :family_name_export_item, class: 'ExportItem' do
|
58
|
+
position { 1 }
|
59
|
+
name { 'Family Name' }
|
60
|
+
rexport_field { 'student.family.name' }
|
55
61
|
end
|
56
|
-
|
57
|
-
factory :grade_export_item, :
|
58
|
-
position 2
|
59
|
-
|
60
|
-
rexport_field 'grade'
|
62
|
+
|
63
|
+
factory :grade_export_item, class: 'ExportItem' do
|
64
|
+
position { 2 }
|
65
|
+
rexport_field { 'grade' }
|
61
66
|
end
|
62
|
-
|
63
|
-
factory :status_name_export_item, :
|
64
|
-
position 3
|
65
|
-
name 'Status'
|
66
|
-
rexport_field 'status_name'
|
67
|
+
|
68
|
+
factory :status_name_export_item, class: 'ExportItem' do
|
69
|
+
position { 3 }
|
70
|
+
name { 'Status' }
|
71
|
+
rexport_field { 'status_name' }
|
67
72
|
end
|
68
|
-
|
69
|
-
factory :bogus_export_item, :
|
70
|
-
position 4
|
71
|
-
name 'Bogus Item'
|
72
|
-
rexport_field 'bogus_field'
|
73
|
+
|
74
|
+
factory :bogus_export_item, class: 'ExportItem' do
|
75
|
+
position { 4 }
|
76
|
+
name { 'Bogus Item' }
|
77
|
+
rexport_field { 'bogus_field' }
|
73
78
|
end
|
74
|
-
|
75
|
-
factory :grade_filter, :
|
76
|
-
filter_field 'grade'
|
77
|
-
value '1'
|
79
|
+
|
80
|
+
factory :grade_filter, class: 'ExportFilter' do
|
81
|
+
filter_field { 'grade' }
|
82
|
+
value { '1' }
|
78
83
|
end
|
79
|
-
|
80
|
-
factory :status_filter, :
|
81
|
-
filter_field 'status.name'
|
82
|
-
value 'active'
|
84
|
+
|
85
|
+
factory :status_filter, class: 'ExportFilter' do
|
86
|
+
filter_field { 'status.name' }
|
87
|
+
value { 'active' }
|
83
88
|
end
|
84
89
|
end
|
85
90
|
end
|
86
|
-
end
|
91
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,29 +1,26 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter '/test/'
|
4
|
+
end
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
7
|
+
require "rails"
|
3
8
|
require 'active_record'
|
4
|
-
require
|
5
|
-
require 'logger'
|
6
|
-
require 'factory_girl'
|
7
|
-
require 'mocha/mini_test'
|
8
|
-
require File.dirname(__FILE__) + '/factories'
|
9
|
-
require File.dirname(__FILE__) + '/../lib/rexport/data_fields'
|
10
|
-
require File.dirname(__FILE__) + '/../lib/rexport/export_methods'
|
11
|
-
require File.dirname(__FILE__) + '/../lib/rexport/export_item_methods'
|
12
|
-
require File.dirname(__FILE__) + '/../lib/rexport/export_filter_methods'
|
13
|
-
require File.dirname(__FILE__) + '/../lib/rexport/tree_node'
|
9
|
+
require "rexport"
|
14
10
|
|
15
|
-
|
11
|
+
require 'minitest/autorun'
|
12
|
+
require 'factory_bot'
|
13
|
+
require 'mocha/minitest'
|
14
|
+
require File.dirname(__FILE__) + '/factories'
|
16
15
|
|
17
|
-
|
18
|
-
RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
|
19
|
-
ActiveRecord::Base.logger = RAILS_DEFAULT_LOGGER
|
16
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
20
17
|
|
21
18
|
class ActiveSupport::TestCase
|
22
|
-
include
|
19
|
+
include FactoryBot::Syntax::Methods
|
23
20
|
include Rexport::Factories
|
24
21
|
|
25
22
|
def setup
|
26
|
-
setup_db
|
23
|
+
suppress_output { setup_db }
|
27
24
|
Enrollment.instance_variable_set('@rexport_fields', nil)
|
28
25
|
Student.instance_variable_set('@rexport_fields', nil)
|
29
26
|
end
|
@@ -32,17 +29,10 @@ class ActiveSupport::TestCase
|
|
32
29
|
teardown_db
|
33
30
|
end
|
34
31
|
|
35
|
-
# Placeholder so test/unit ignores test cases without any tests.
|
36
|
-
def default_test
|
37
|
-
end
|
38
|
-
|
39
32
|
private
|
40
33
|
|
41
34
|
def setup_db
|
42
|
-
|
43
|
-
$stdout = StringIO.new
|
44
|
-
|
45
|
-
ActiveRecord::Schema.define(:version => 1) do
|
35
|
+
ActiveRecord::Schema.define(version: 1) do
|
46
36
|
create_table :enrollments do |t|
|
47
37
|
t.integer :student_id, :status_id, :grade
|
48
38
|
t.boolean :active
|
@@ -85,8 +75,6 @@ class ActiveSupport::TestCase
|
|
85
75
|
create_table :self_referential_checks do |t|
|
86
76
|
end
|
87
77
|
end
|
88
|
-
|
89
|
-
$stdout = old_stdout
|
90
78
|
end
|
91
79
|
|
92
80
|
def teardown_db
|
@@ -94,6 +82,14 @@ class ActiveSupport::TestCase
|
|
94
82
|
ActiveRecord::Base.connection.drop_table(table)
|
95
83
|
end
|
96
84
|
end
|
85
|
+
|
86
|
+
def suppress_output
|
87
|
+
original_stdout = $stdout.clone
|
88
|
+
$stdout.reopen File.new('/dev/null', 'w')
|
89
|
+
yield
|
90
|
+
ensure
|
91
|
+
$stdout.reopen original_stdout
|
92
|
+
end
|
97
93
|
end
|
98
94
|
|
99
95
|
class ActiveRecord::Base
|
@@ -107,7 +103,7 @@ class Enrollment < ActiveRecord::Base
|
|
107
103
|
include Rexport::DataFields
|
108
104
|
belongs_to :student
|
109
105
|
belongs_to :status
|
110
|
-
belongs_to :ilp_status, :
|
106
|
+
belongs_to :ilp_status, class_name: 'Status', foreign_key: 'ilp_status_id'
|
111
107
|
belongs_to :self_referential_check
|
112
108
|
|
113
109
|
def foo
|
@@ -117,9 +113,9 @@ class Enrollment < ActiveRecord::Base
|
|
117
113
|
private
|
118
114
|
|
119
115
|
def Enrollment.initialize_local_rexport_fields
|
120
|
-
add_rexport_field(:foo_method, :
|
121
|
-
add_rexport_field(:bad_method, :
|
122
|
-
add_association_methods(:
|
116
|
+
add_rexport_field(:foo_method, method: :foo)
|
117
|
+
add_rexport_field(:bad_method, method: 'bad_method')
|
118
|
+
add_association_methods(associations: %w(status ilp_status))
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
@@ -140,7 +136,7 @@ class Family < ActiveRecord::Base
|
|
140
136
|
private
|
141
137
|
|
142
138
|
def Family.initialize_local_rexport_fields
|
143
|
-
add_rexport_field(:foo_method, :
|
139
|
+
add_rexport_field(:foo_method, method: :foo)
|
144
140
|
end
|
145
141
|
end
|
146
142
|
|