coupler 0.0.1-java

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.
Files changed (258) hide show
  1. data/.document +5 -0
  2. data/.gitmodules +3 -0
  3. data/.rvmrc +1 -0
  4. data/.vimrc +40 -0
  5. data/Gemfile +27 -0
  6. data/Gemfile.lock +71 -0
  7. data/LICENSE +20 -0
  8. data/NOTES +6 -0
  9. data/README.rdoc +18 -0
  10. data/Rakefile +42 -0
  11. data/TODO +11 -0
  12. data/VERSION +1 -0
  13. data/bin/coupler +7 -0
  14. data/db/.gitignore +6 -0
  15. data/db/migrate/001_initial_schema.rb +166 -0
  16. data/db/migrate/002_stub.rb +4 -0
  17. data/db/migrate/003_stub.rb +4 -0
  18. data/db/migrate/004_create_comparisons.rb +28 -0
  19. data/db/migrate/005_move_database_name.rb +19 -0
  20. data/db/migrate/006_upgrade_comparisons.rb +34 -0
  21. data/db/migrate/007_add_which_to_comparisons.rb +23 -0
  22. data/db/migrate/008_add_result_field_to_transformations.rb +33 -0
  23. data/db/migrate/009_add_generated_flag_to_fields.rb +13 -0
  24. data/db/migrate/010_create_imports.rb +24 -0
  25. data/db/migrate/011_add_primary_key_type.rb +13 -0
  26. data/db/migrate/012_add_transformed_with_to_resources.rb +13 -0
  27. data/db/migrate/013_add_run_count_to_scenarios.rb +13 -0
  28. data/db/migrate/014_add_last_accessed_at_to_some_tables.rb +13 -0
  29. data/db/migrate/015_add_run_number_to_results.rb +15 -0
  30. data/db/migrate/016_fix_scenario_run_count.rb +27 -0
  31. data/db/migrate/017_rename_comparison_columns.rb +14 -0
  32. data/db/migrate/018_fix_scenario_linkage_type.rb +8 -0
  33. data/db/migrate/019_add_columns_to_imports.rb +24 -0
  34. data/db/migrate/020_rename_import_columns.rb +12 -0
  35. data/db/migrate/021_add_fields_to_connections.rb +15 -0
  36. data/db/migrate/022_remove_database_name_from_resources.rb +11 -0
  37. data/features/connections.feature +28 -0
  38. data/features/matchers.feature +35 -0
  39. data/features/projects.feature +11 -0
  40. data/features/resources.feature +62 -0
  41. data/features/scenarios.feature +45 -0
  42. data/features/step_definitions/coupler_steps.rb +145 -0
  43. data/features/step_definitions/matchers_steps.rb +26 -0
  44. data/features/step_definitions/resources_steps.rb +12 -0
  45. data/features/step_definitions/scenarios_steps.rb +7 -0
  46. data/features/step_definitions/transformations_steps.rb +3 -0
  47. data/features/support/env.rb +128 -0
  48. data/features/transformations.feature +22 -0
  49. data/features/wizard.feature +10 -0
  50. data/gfx/coupler-header.svg +213 -0
  51. data/gfx/coupler-sidebar.svg +656 -0
  52. data/gfx/coupler.svg +184 -0
  53. data/gfx/icon.svg +75 -0
  54. data/lib/coupler/base.rb +63 -0
  55. data/lib/coupler/config.rb +128 -0
  56. data/lib/coupler/data_uploader.rb +20 -0
  57. data/lib/coupler/database.rb +31 -0
  58. data/lib/coupler/extensions/connections.rb +57 -0
  59. data/lib/coupler/extensions/exceptions.rb +58 -0
  60. data/lib/coupler/extensions/imports.rb +43 -0
  61. data/lib/coupler/extensions/jobs.rb +21 -0
  62. data/lib/coupler/extensions/matchers.rb +64 -0
  63. data/lib/coupler/extensions/projects.rb +62 -0
  64. data/lib/coupler/extensions/resources.rb +89 -0
  65. data/lib/coupler/extensions/results.rb +100 -0
  66. data/lib/coupler/extensions/scenarios.rb +50 -0
  67. data/lib/coupler/extensions/transformations.rb +70 -0
  68. data/lib/coupler/extensions/transformers.rb +58 -0
  69. data/lib/coupler/extensions.rb +16 -0
  70. data/lib/coupler/helpers.rb +121 -0
  71. data/lib/coupler/import_buffer.rb +48 -0
  72. data/lib/coupler/logger.rb +16 -0
  73. data/lib/coupler/models/common_model.rb +104 -0
  74. data/lib/coupler/models/comparison.rb +166 -0
  75. data/lib/coupler/models/connection.rb +59 -0
  76. data/lib/coupler/models/field.rb +55 -0
  77. data/lib/coupler/models/import.rb +238 -0
  78. data/lib/coupler/models/job.rb +42 -0
  79. data/lib/coupler/models/jobify.rb +17 -0
  80. data/lib/coupler/models/matcher.rb +36 -0
  81. data/lib/coupler/models/project.rb +40 -0
  82. data/lib/coupler/models/resource.rb +287 -0
  83. data/lib/coupler/models/result.rb +92 -0
  84. data/lib/coupler/models/scenario/runner.rb +357 -0
  85. data/lib/coupler/models/scenario.rb +115 -0
  86. data/lib/coupler/models/transformation.rb +117 -0
  87. data/lib/coupler/models/transformer/runner.rb +28 -0
  88. data/lib/coupler/models/transformer.rb +110 -0
  89. data/lib/coupler/models.rb +30 -0
  90. data/lib/coupler/runner.rb +76 -0
  91. data/lib/coupler/scheduler.rb +56 -0
  92. data/lib/coupler.rb +34 -0
  93. data/log/.gitignore +1 -0
  94. data/misc/README +5 -0
  95. data/misc/jruby-json.license +57 -0
  96. data/misc/rack-flash.license +22 -0
  97. data/script/dbconsole.rb +5 -0
  98. data/src/edu/vanderbilt/coupler/Main.java +116 -0
  99. data/src/edu/vanderbilt/coupler/jruby.properties +1 -0
  100. data/tasks/annotations.rake +84 -0
  101. data/tasks/db.rake +120 -0
  102. data/tasks/environment.rake +12 -0
  103. data/tasks/jeweler.rake +43 -0
  104. data/tasks/package.rake +58 -0
  105. data/tasks/rdoc.rake +13 -0
  106. data/tasks/test.rake +63 -0
  107. data/tasks/vendor.rake +43 -0
  108. data/test/README.txt +6 -0
  109. data/test/config.yml +9 -0
  110. data/test/coupler/models/test_import.rb +221 -0
  111. data/test/factories.rb +91 -0
  112. data/test/fixtures/duplicate-keys.csv +5 -0
  113. data/test/fixtures/no-headers.csv +50 -0
  114. data/test/fixtures/people.csv +51 -0
  115. data/test/fixtures/varying-row-size.csv +4 -0
  116. data/test/helper.rb +156 -0
  117. data/test/integration/extensions/test_connections.rb +80 -0
  118. data/test/integration/extensions/test_imports.rb +94 -0
  119. data/test/integration/extensions/test_jobs.rb +52 -0
  120. data/test/integration/extensions/test_matchers.rb +134 -0
  121. data/test/integration/extensions/test_projects.rb +82 -0
  122. data/test/integration/extensions/test_resources.rb +150 -0
  123. data/test/integration/extensions/test_results.rb +89 -0
  124. data/test/integration/extensions/test_scenarios.rb +88 -0
  125. data/test/integration/extensions/test_transformations.rb +113 -0
  126. data/test/integration/extensions/test_transformers.rb +80 -0
  127. data/test/integration/test_field.rb +45 -0
  128. data/test/integration/test_import.rb +78 -0
  129. data/test/integration/test_running_scenarios.rb +379 -0
  130. data/test/integration/test_transformation.rb +56 -0
  131. data/test/integration/test_transforming.rb +154 -0
  132. data/test/table_sets.rb +76 -0
  133. data/test/unit/models/test_common_model.rb +130 -0
  134. data/test/unit/models/test_comparison.rb +619 -0
  135. data/test/unit/models/test_connection.rb +115 -0
  136. data/test/unit/models/test_field.rb +99 -0
  137. data/test/unit/models/test_import.rb +130 -0
  138. data/test/unit/models/test_job.rb +115 -0
  139. data/test/unit/models/test_matcher.rb +82 -0
  140. data/test/unit/models/test_project.rb +102 -0
  141. data/test/unit/models/test_resource.rb +564 -0
  142. data/test/unit/models/test_result.rb +90 -0
  143. data/test/unit/models/test_scenario.rb +199 -0
  144. data/test/unit/models/test_transformation.rb +193 -0
  145. data/test/unit/models/test_transformer.rb +188 -0
  146. data/test/unit/test_base.rb +60 -0
  147. data/test/unit/test_data_uploader.rb +27 -0
  148. data/test/unit/test_database.rb +23 -0
  149. data/test/unit/test_helpers.rb +58 -0
  150. data/test/unit/test_logger.rb +10 -0
  151. data/test/unit/test_models.rb +12 -0
  152. data/test/unit/test_runner.rb +76 -0
  153. data/test/unit/test_scheduler.rb +66 -0
  154. data/uploads/.gitignore +2 -0
  155. data/vendor/java/.gitignore +5 -0
  156. data/webroot/public/css/960.css +1 -0
  157. data/webroot/public/css/dataTables.css +1057 -0
  158. data/webroot/public/css/jquery-ui.css +572 -0
  159. data/webroot/public/css/jquery.treeview.css +68 -0
  160. data/webroot/public/css/reset.css +1 -0
  161. data/webroot/public/css/style.css +504 -0
  162. data/webroot/public/css/text.css +1 -0
  163. data/webroot/public/favicon.ico +0 -0
  164. data/webroot/public/images/12_col.gif +0 -0
  165. data/webroot/public/images/16_col.gif +0 -0
  166. data/webroot/public/images/add.png +0 -0
  167. data/webroot/public/images/ajax-loader.gif +0 -0
  168. data/webroot/public/images/cog.png +0 -0
  169. data/webroot/public/images/coupler.png +0 -0
  170. data/webroot/public/images/foo.png +0 -0
  171. data/webroot/public/images/hammer.png +0 -0
  172. data/webroot/public/images/header.png +0 -0
  173. data/webroot/public/images/home.gif +0 -0
  174. data/webroot/public/images/jobs.gif +0 -0
  175. data/webroot/public/images/sidebar-bottom.png +0 -0
  176. data/webroot/public/images/sidebar.png +0 -0
  177. data/webroot/public/images/treeview-default-line.gif +0 -0
  178. data/webroot/public/images/treeview-default.gif +0 -0
  179. data/webroot/public/images/ui-anim_basic_16x16.gif +0 -0
  180. data/webroot/public/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  181. data/webroot/public/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  182. data/webroot/public/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  183. data/webroot/public/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  184. data/webroot/public/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  185. data/webroot/public/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  186. data/webroot/public/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  187. data/webroot/public/images/ui-bg_highlight-hard_30_565356_1x100.png +0 -0
  188. data/webroot/public/images/ui-bg_highlight-hard_75_888588_1x100.png +0 -0
  189. data/webroot/public/images/ui-bg_highlight-soft_30_6e3b3a_1x100.png +0 -0
  190. data/webroot/public/images/ui-bg_highlight-soft_35_8e8b8e_1x100.png +0 -0
  191. data/webroot/public/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  192. data/webroot/public/images/ui-icons_222222_256x240.png +0 -0
  193. data/webroot/public/images/ui-icons_2e83ff_256x240.png +0 -0
  194. data/webroot/public/images/ui-icons_454545_256x240.png +0 -0
  195. data/webroot/public/images/ui-icons_888888_256x240.png +0 -0
  196. data/webroot/public/images/ui-icons_cd0a0a_256x240.png +0 -0
  197. data/webroot/public/images/ui-icons_ffffff_256x240.png +0 -0
  198. data/webroot/public/js/ajaxupload.js +673 -0
  199. data/webroot/public/js/application.js +40 -0
  200. data/webroot/public/js/jquery-ui.combobox.js +98 -0
  201. data/webroot/public/js/jquery-ui.js +9867 -0
  202. data/webroot/public/js/jquery-ui.min.js +559 -0
  203. data/webroot/public/js/jquery.dataTables.min.js +587 -0
  204. data/webroot/public/js/jquery.min.js +154 -0
  205. data/webroot/public/js/jquery.timeago.js +140 -0
  206. data/webroot/public/js/jquery.tooltip.min.js +19 -0
  207. data/webroot/public/js/jquery.treeview.min.js +15 -0
  208. data/webroot/public/js/resource.js +11 -0
  209. data/webroot/public/js/results.js +56 -0
  210. data/webroot/public/js/transformations.js +95 -0
  211. data/webroot/views/connections/index.erb +5 -0
  212. data/webroot/views/connections/list.erb +34 -0
  213. data/webroot/views/connections/new.erb +55 -0
  214. data/webroot/views/connections/show.erb +36 -0
  215. data/webroot/views/imports/edit.erb +60 -0
  216. data/webroot/views/imports/form.erb +81 -0
  217. data/webroot/views/imports/new.erb +89 -0
  218. data/webroot/views/index.erb +12 -0
  219. data/webroot/views/jobs/index.erb +7 -0
  220. data/webroot/views/jobs/list.erb +24 -0
  221. data/webroot/views/layout.erb +38 -0
  222. data/webroot/views/matchers/form.erb +250 -0
  223. data/webroot/views/matchers/list.erb +32 -0
  224. data/webroot/views/projects/form.erb +14 -0
  225. data/webroot/views/projects/index.erb +96 -0
  226. data/webroot/views/projects/show.erb +24 -0
  227. data/webroot/views/resources/edit.erb +88 -0
  228. data/webroot/views/resources/index.erb +5 -0
  229. data/webroot/views/resources/list.erb +27 -0
  230. data/webroot/views/resources/new.erb +121 -0
  231. data/webroot/views/resources/show.erb +86 -0
  232. data/webroot/views/resources/transform.erb +2 -0
  233. data/webroot/views/results/csv.erb +12 -0
  234. data/webroot/views/results/details.erb +15 -0
  235. data/webroot/views/results/index.erb +2 -0
  236. data/webroot/views/results/list.erb +22 -0
  237. data/webroot/views/results/record.erb +24 -0
  238. data/webroot/views/results/show.erb +68 -0
  239. data/webroot/views/scenarios/index.erb +5 -0
  240. data/webroot/views/scenarios/list.erb +20 -0
  241. data/webroot/views/scenarios/new.erb +99 -0
  242. data/webroot/views/scenarios/run.erb +2 -0
  243. data/webroot/views/scenarios/show.erb +50 -0
  244. data/webroot/views/sidebar.erb +106 -0
  245. data/webroot/views/transformations/create.erb +115 -0
  246. data/webroot/views/transformations/for.erb +16 -0
  247. data/webroot/views/transformations/index.erb +2 -0
  248. data/webroot/views/transformations/list.erb +29 -0
  249. data/webroot/views/transformations/new.erb +126 -0
  250. data/webroot/views/transformations/preview.erb +46 -0
  251. data/webroot/views/transformers/edit.erb +6 -0
  252. data/webroot/views/transformers/form.erb +58 -0
  253. data/webroot/views/transformers/index.erb +2 -0
  254. data/webroot/views/transformers/list.erb +25 -0
  255. data/webroot/views/transformers/new.erb +5 -0
  256. data/webroot/views/transformers/preview.erb +23 -0
  257. data/webroot/views/transformers/show.erb +0 -0
  258. metadata +558 -0
@@ -0,0 +1,564 @@
1
+ require 'helper'
2
+
3
+ module Coupler
4
+ module Models
5
+ class TestResource < Coupler::Test::UnitTest
6
+ def setup
7
+ super
8
+ @local_database = stub('project database')
9
+ @project = stub_project
10
+ @project.stubs(:local_database).yields(@local_database)
11
+
12
+ @source_database = stub('source database', {
13
+ :tables => [:foo],
14
+ :schema => [
15
+ [:id, {:primary_key => true, :type => :integer, :db_type => "BIGINT"}],
16
+ [:foo, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}],
17
+ [:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
18
+ ]
19
+ })
20
+ @connection = stub('connection', :pk => 456, :id => 456, :associations => {})
21
+ @connection.stubs(:database).yields(@source_database)
22
+ end
23
+
24
+ def new_resource(attribs = {})
25
+ values = {
26
+ :name => 'Foo bar',
27
+ :table_name => 'foo',
28
+ :project => @project,
29
+ :connection => @connection
30
+ }.update(attribs)
31
+ r = Resource.new(values)
32
+ r.stubs(:project_dataset).returns(stub({:all => [values[:project]]}))
33
+ r.stubs(:connection_dataset).returns(stub({:all => [values[:connection]]}))
34
+ r
35
+ end
36
+
37
+ def stub_project(id = 123, methods = {})
38
+ stub('project', {:pk => id, :id => id, :associations => {}}.update(methods))
39
+ end
40
+
41
+ test "sequel model" do
42
+ assert_equal Sequel::Model, Resource.superclass
43
+ assert_equal :resources, Resource.table_name
44
+ end
45
+
46
+ test "many to one connection" do
47
+ assert_respond_to Resource.new, :connection
48
+ end
49
+
50
+ test "many to one project" do
51
+ assert_respond_to Resource.new, :project
52
+ end
53
+
54
+ test "one to many transformations" do
55
+ assert_respond_to Resource.new, :transformations
56
+ end
57
+
58
+ test "one to many jobs" do
59
+ assert_respond_to Resource.new, :jobs
60
+ end
61
+
62
+ test "one to many fields" do
63
+ assert_respond_to Resource.new, :fields
64
+ end
65
+
66
+ test "one to many selected fields" do
67
+ assert_respond_to Resource.new, :selected_fields
68
+ end
69
+
70
+ test "many to one import" do
71
+ assert_respond_to Resource.new, :import
72
+ end
73
+
74
+ test "one to many running_jobs" do
75
+ assert_respond_to Resource.new, :running_jobs
76
+ end
77
+
78
+ test "one to many scheduled_jobs" do
79
+ assert_respond_to Resource.new, :scheduled_jobs
80
+ end
81
+
82
+ test "nested attributes for connection" do
83
+ assert_respond_to Resource.new, :connection_attributes=
84
+ end
85
+
86
+ #test "invalid nested attributes for connection" do
87
+ #connection_count = Connection.count
88
+ #resource_count = Resource.count
89
+
90
+ #resource = Factory.build(:resource, :connection => nil)
91
+ #resource.connection_attributes = Factory.attributes_for(:connection, :name => nil, :host => nil)
92
+ #resource.save
93
+
94
+ #assert_equal resource_count, Resource.count
95
+ #assert_equal connection_count, Connection.count
96
+ #end
97
+
98
+ test "nested attributes for fields" do
99
+ assert_respond_to Resource.new, :fields_attributes=
100
+ end
101
+
102
+ test "rejects new fields for nested attributes" do
103
+ resource = new_resource
104
+ resource.save!
105
+ resource.fields_attributes = [{:is_selected => 0}]
106
+ resource.expects(:add_field).times(0)
107
+ resource.save!
108
+ end
109
+
110
+ test "requires project" do
111
+ resource = new_resource
112
+ args = []
113
+ resource.expects(:validates_presence).at_least(1).with { |*a| args << a; true }
114
+ resource.save
115
+ args.flatten!
116
+ assert args.include?(:project_id)
117
+ end
118
+
119
+ test "requires name" do
120
+ resource = new_resource
121
+ args = []
122
+ resource.expects(:validates_presence).at_least(1).with { |*a| args << a; true }
123
+ resource.save
124
+ args.flatten!
125
+ assert args.include?(:name)
126
+ end
127
+
128
+ test "requires unique name across projects" do
129
+ resource = new_resource
130
+ resource.expects(:validates_unique).with do |*args|
131
+ args.include?([:name, :project_id])
132
+ end
133
+ resource.save
134
+ end
135
+
136
+ test "requires non empty table_name" do
137
+ resource = new_resource
138
+ args = []
139
+ resource.expects(:validates_presence).at_least(1).with { |*a| args << a; true }
140
+ resource.save
141
+ args.flatten!
142
+ assert args.include?(:table_name)
143
+ end
144
+
145
+ test "requires valid table_name" do
146
+ @source_database.stubs(:tables).returns([])
147
+ resource = new_resource
148
+ assert !resource.valid?, "Resource wasn't invalid"
149
+ end
150
+
151
+ test "sets slug from name" do
152
+ resource = new_resource(:name => 'Foo bar')
153
+ assert_equal "foo_bar", resource.slug
154
+ end
155
+
156
+ test "requires unique slug across projects" do
157
+ resource = new_resource
158
+ resource.expects(:validates_unique).with do |*args|
159
+ args.include?([:slug, :project_id])
160
+ end
161
+ resource.save
162
+ end
163
+
164
+ test "requires table with primary key" do
165
+ @source_database.stubs(:schema).returns([
166
+ [:id, {:primary_key => false, :type => :integer, :db_type => "BIGINT"}],
167
+ [:foo, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}],
168
+ [:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
169
+ ])
170
+ resource = new_resource
171
+ assert !resource.valid?
172
+ end
173
+
174
+ test "requires single primary key" do
175
+ @source_database.stubs(:schema).returns([
176
+ [:id, {:primary_key => true, :type => :integer, :db_type => "BIGINT"}],
177
+ [:foo, {:primary_key => true, :type => :string, :db_type => "VARCHAR"}],
178
+ [:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
179
+ ])
180
+ resource = new_resource
181
+ assert !resource.valid?
182
+ end
183
+
184
+ test "does not requires integer primary key" do
185
+ @source_database.stubs(:schema).returns([
186
+ [:id, {:primary_key => false, :type => :integer, :db_type => "BIGINT"}],
187
+ [:foo, {:primary_key => true, :type => :string, :db_type => "VARCHAR"}],
188
+ [:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
189
+ ])
190
+ resource = new_resource
191
+ assert resource.valid?
192
+ end
193
+
194
+ test "sets primary_key_name" do
195
+ @source_database.stubs(:schema).returns([
196
+ [:my_id, {:primary_key => true, :type => :integer, :db_type => "BIGINT"}],
197
+ [:foo, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}],
198
+ [:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
199
+ ])
200
+ resource = new_resource.save!
201
+ assert_equal 'my_id', resource.primary_key_name
202
+ end
203
+
204
+ test "sets primary_key_type" do
205
+ @source_database.stubs(:schema).returns([
206
+ [:my_id, {:primary_key => true, :type => :integer, :db_type => "BIGINT"}],
207
+ [:foo, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}],
208
+ [:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
209
+ ])
210
+ resource = new_resource.save!
211
+ assert_equal 'integer', resource.primary_key_type
212
+ end
213
+
214
+ test "creates fields" do
215
+ @source_database.stubs(:schema).returns([
216
+ [:id, {:allow_null=>false, :default=>nil, :primary_key=>true, :db_type=>"int(11)", :type=>:integer, :ruby_default=>nil}],
217
+ [:first_name, {:allow_null=>true, :default=>nil, :primary_key=>false, :db_type=>"varchar(255)", :type=>:string, :ruby_default=>nil}],
218
+ [:last_name, {:allow_null=>true, :default=>nil, :primary_key=>false, :db_type=>"varchar(255)", :type=>:string, :ruby_default=>nil}]
219
+ ])
220
+
221
+ resource = new_resource
222
+ resource.expects(:add_field).with do |h|
223
+ h[:name] == :id && h[:type] == :integer &&
224
+ h[:db_type] == 'int(11)' && h[:is_primary_key]
225
+ end
226
+ resource.expects(:add_field).with do |h|
227
+ h[:name] == :first_name && h[:type] == :string &&
228
+ h[:db_type] == 'varchar(255)' && !h[:is_primary_key]
229
+ end
230
+ resource.expects(:add_field).with do |h|
231
+ h[:name] == :last_name && h[:type] == :string &&
232
+ h[:db_type] == 'varchar(255)' && !h[:is_primary_key]
233
+ end
234
+ resource.save!
235
+ end
236
+
237
+ test "source_database with block" do
238
+ resource = new_resource.save!
239
+ @connection.expects(:database).yields(@source_database)
240
+ resource.source_database do |db|
241
+ assert_equal @source_database, db
242
+ end
243
+ end
244
+
245
+ test "source_database without block" do
246
+ resource = new_resource.save!
247
+ @connection.expects(:database).returns(@source_database)
248
+ assert_equal @source_database, resource.source_database
249
+ end
250
+
251
+ test "source_dataset" do
252
+ resource = new_resource.save!
253
+
254
+ # ghetto mock!
255
+ fd = [stub(:name => 'id'), stub(:name => 'foo'), stub(:name => 'bar')]
256
+ fd.expects(:filter).with(:is_selected => true, :is_generated => false).returns(fd)
257
+ resource.stubs(:fields_dataset).returns(fd)
258
+
259
+ dataset = mock('dataset')
260
+ dataset.expects(:select).with(:id, :foo, :bar).returns(dataset)
261
+ @source_database.expects(:[]).with(:foo).returns(dataset)
262
+
263
+ # with block
264
+ resource.source_dataset do |rdataset|
265
+ assert_equal dataset, rdataset
266
+ end
267
+ end
268
+
269
+ test "source_dataset without block" do
270
+ resource = new_resource.save!
271
+
272
+ # ghetto mock!
273
+ fd = [stub(:name => 'id'), stub(:name => 'foo'), stub(:name => 'bar')]
274
+ fd.expects(:filter).with(:is_selected => true, :is_generated => false).returns(fd)
275
+ resource.stubs(:fields_dataset).returns(fd)
276
+
277
+ dataset = mock('dataset')
278
+ dataset.expects(:select).with(:id, :foo, :bar).returns(dataset)
279
+ @connection.expects(:database).returns(@source_database)
280
+ @source_database.expects(:[]).with(:foo).returns(dataset)
281
+
282
+ assert_equal dataset, resource.source_dataset
283
+ end
284
+
285
+ test "source_schema" do
286
+ resource = new_resource.save!
287
+ schema = stub('schema')
288
+ @source_database.expects(:schema).with(:foo).returns(schema)
289
+ assert_equal schema, resource.source_schema
290
+ end
291
+
292
+ test "local_dataset" do
293
+ resource = new_resource.save!
294
+ dataset = mock('dataset')
295
+ @local_database.expects(:[]).with(:"resource_#{resource.id}").returns(dataset)
296
+ resource.local_dataset do |ds|
297
+ assert_equal dataset, ds
298
+ end
299
+ end
300
+
301
+ test "local dataset without block" do
302
+ resource = new_resource.save!
303
+
304
+ @project.expects(:local_database).returns(@local_database)
305
+ dataset = stub('dataset')
306
+ @local_database.expects(:[]).with(:"resource_#{resource.id}").returns(dataset)
307
+ assert_equal dataset, resource.local_dataset
308
+ end
309
+
310
+ test "refresh fields" do
311
+ resource = new_resource.save!
312
+ field_1 = stub("id field", :id => 1)
313
+ field_2 = stub("first_name field", :id => 2)
314
+ field_3 = stub("last_name field", :id => 3)
315
+
316
+ transformation_1 = stub("transformation 1", {
317
+ :source_field_id => 2, :result_field_id => 2,
318
+ :field_changes => {2 => {:type => :integer, :db_type => 'int(11)'}},
319
+ :source_field => field_2
320
+ })
321
+ transformation_2 = stub("transformation 2", {
322
+ :source_field_id => 3, :result_field_id => 3,
323
+ :field_changes => {3 => {:type => :integer, :db_type => 'int(11)'}},
324
+ :source_field => field_3
325
+ })
326
+ transformation_3 = stub("transformation 3", {
327
+ :source_field_id => 3, :result_field_id => 3,
328
+ :field_changes => {3 => {:type => :datetime, :db_type => 'datetime'}},
329
+ :source_field => field_3
330
+ })
331
+
332
+ resource.stubs(:fields_dataset).returns(stub(:update => nil))
333
+ td = [transformation_1, transformation_2, transformation_3]
334
+ td.expects(:order).with(:position).returns(td)
335
+ resource.expects(:transformations_dataset).returns(td)
336
+
337
+ seq = sequence("update")
338
+ field_2.expects(:update).with({
339
+ :local_type => :integer, :local_db_type => 'int(11)'
340
+ }).in_sequence(seq)
341
+ field_3.expects(:update).with({
342
+ :local_type => :integer, :local_db_type => 'int(11)'
343
+ }).in_sequence(seq)
344
+ field_3.expects(:update).with({
345
+ :local_type => :datetime, :local_db_type => 'datetime'
346
+ }).in_sequence(seq)
347
+
348
+ resource.refresh_fields!
349
+ end
350
+
351
+ test "refresh_fields does not change newly created result field" do
352
+ resource = new_resource.save!
353
+ field_1 = stub("id field", :id => 1)
354
+ field_2 = stub("first_name field", :id => 2)
355
+ field_3 = stub("last_name field", :id => 3)
356
+ new_field = stub("new field", :id => 4)
357
+
358
+ transformation = stub("transformation 1", {
359
+ :source_field_id => 2, :result_field_id => 4,
360
+ :field_changes => {2 => {:type => :integer, :db_type => 'int(11)'}},
361
+ :source_field => field_2
362
+ })
363
+
364
+ resource.stubs(:fields_dataset).returns(stub(:update => nil))
365
+ td = [transformation]
366
+ td.expects(:order).with(:position).returns(td)
367
+ resource.expects(:transformations_dataset).returns(td)
368
+
369
+ field_2.expects(:update).never
370
+ new_field.expects(:update).never
371
+
372
+ resource.refresh_fields!
373
+ end
374
+
375
+ test "refresh_fields resets local_type and local_db_type" do
376
+ resource = new_resource.save!
377
+
378
+ resource.expects(:fields_dataset).returns(mock {
379
+ expects(:update).with(:local_type => nil, :local_db_type => nil)
380
+ })
381
+ td = []
382
+ td.expects(:order).with(:position).returns(td)
383
+ resource.expects(:transformations_dataset).returns(td)
384
+
385
+ resource.refresh_fields!
386
+ end
387
+
388
+ test "initial status" do
389
+ resource = new_resource.save!
390
+ assert_equal "ok", resource.status
391
+ end
392
+
393
+ test "status after adding first transformation" do
394
+ resource = new_resource.save!
395
+ resource.stubs(:transformation_ids).returns([1])
396
+ assert_equal "out_of_date", resource.status
397
+ end
398
+
399
+ test "status when new transformation is created since transforming" do
400
+ resource = new_resource(:transformed_with => "1").save!
401
+ resource.stubs(:transformation_ids).returns([1,2])
402
+ assert_equal "out_of_date", resource.status
403
+ end
404
+
405
+ test "status when transformation is updated since transforming" do
406
+ now = Time.now
407
+ resource = new_resource(:transformed_with => "1", :transformed_at => now - 20).save!
408
+ resource.stubs(:transformation_ids).returns([1])
409
+ resource.stubs(:transformations_dataset).returns(stub {
410
+ stubs(:filter).with('updated_at > ?', now - 20).returns(self)
411
+ stubs(:count).returns(1)
412
+ })
413
+ assert_equal "out_of_date", resource.status
414
+ end
415
+
416
+ test "status when transformation is removed since transforming" do
417
+ now = Time.now
418
+ resource = new_resource(:transformed_at => now - 5, :transformed_with => "1").save!
419
+ resource.stubs(:transformation_ids).returns([])
420
+ assert_equal "out_of_date", resource.status
421
+ end
422
+
423
+ test "status when new transformation is removed before transforming" do
424
+ resource = new_resource.save!
425
+ resource.stubs(:transformation_ids).returns([1])
426
+ assert_equal "out_of_date", resource.status
427
+ resource.stubs(:transformation_ids).returns([])
428
+ assert_equal "ok", resource.status
429
+ end
430
+
431
+ test "final_database is source_database without transformations" do
432
+ resource = new_resource.save!
433
+ resource.stubs(:transformations_dataset).returns(stub(:count => 0))
434
+ db = stub('db')
435
+ resource.expects(:source_database).returns(db)
436
+ assert_equal db, resource.final_database
437
+ end
438
+
439
+ test "final_database is local_database with transformations" do
440
+ resource = new_resource.save!
441
+ resource.stubs(:transformations_dataset).returns(stub(:count => 1))
442
+ db = stub('db')
443
+ @project.expects(:local_database).returns(db)
444
+ assert_equal db, resource.final_database
445
+ end
446
+
447
+ test "final_dataset is source_dataset without transformations" do
448
+ resource = new_resource.save!
449
+ resource.stubs(:transformations_dataset).returns(stub(:count => 0))
450
+ ds = stub('dataset')
451
+ resource.expects(:source_dataset).returns(ds)
452
+ assert_equal ds, resource.final_dataset
453
+ end
454
+
455
+ test "final_dataset is local_dataset with transformations" do
456
+ resource = new_resource.save!
457
+ resource.stubs(:transformations_dataset).returns(stub(:count => 1))
458
+ ds = stub('dataset')
459
+ resource.expects(:local_dataset).returns(ds)
460
+ assert_equal ds, resource.final_dataset
461
+ end
462
+
463
+ test "scenarios" do
464
+ resource = new_resource.save!
465
+ scenario = stub('scenario')
466
+ Scenario.expects(:filter).with(['resource_1_id = ? OR resource_2_id = ?', resource.id, resource.id]).returns(stub(:all => [scenario]))
467
+ assert_equal [scenario], resource.scenarios
468
+ end
469
+
470
+ test "deletes dependencies after destroy" do
471
+ resource = new_resource.save!
472
+
473
+ resource.expects(:fields_dataset).returns([
474
+ mock('field 1', :destroy => nil) { expects(:delete_versions_on_destroy=).with { |arg| !arg } },
475
+ mock('field 2', :destroy => nil) { expects(:delete_versions_on_destroy=).with { |arg| !arg } },
476
+ mock('field 3', :destroy => nil) { expects(:delete_versions_on_destroy=).with { |arg| !arg } }
477
+ ])
478
+ resource.expects(:transformations_dataset).returns([
479
+ mock('transformation 1', :destroy => nil) { expects(:delete_versions_on_destroy=).with { |arg| !arg } },
480
+ mock('transformation 2', :destroy => nil) { expects(:delete_versions_on_destroy=).with { |arg| !arg } },
481
+ mock('transformation 3', :destroy => nil) { expects(:delete_versions_on_destroy=).with { |arg| !arg } }
482
+ ])
483
+ resource.destroy
484
+ end
485
+
486
+ test "deletes local dataset after destroy" do
487
+ resource = new_resource(:transformed_at => Time.now).save!
488
+ resource.expects(:transformations_dataset).returns([stub_everything('transformation')])
489
+ @local_database.expects(:drop_table).with(:"resource_#{resource.id}")
490
+ resource.destroy
491
+ end
492
+
493
+ test "forceably deletes versions after destroy" do
494
+ resource = new_resource.save!
495
+ resource.delete_versions_on_destroy = true
496
+ resource.expects(:fields_dataset).returns([
497
+ mock('field 1', :destroy => nil) { expects(:delete_versions_on_destroy=).with(true) },
498
+ mock('field 2', :destroy => nil) { expects(:delete_versions_on_destroy=).with(true) },
499
+ mock('field 3', :destroy => nil) { expects(:delete_versions_on_destroy=).with(true) }
500
+ ])
501
+ resource.expects(:transformations_dataset).returns([
502
+ mock('transformation 1', :destroy => nil) { expects(:delete_versions_on_destroy=).with(true) },
503
+ mock('transformation 2', :destroy => nil) { expects(:delete_versions_on_destroy=).with(true) },
504
+ mock('transformation 3', :destroy => nil) { expects(:delete_versions_on_destroy=).with(true) }
505
+ ])
506
+
507
+ resource.destroy
508
+ end
509
+
510
+ test "creating resource via import" do
511
+ import = stub("import", {
512
+ :id => 123, :pk => 123, :project => @project,
513
+ :name => "People"
514
+ })
515
+ resource = Resource.new(:import => import)
516
+ assert_equal "People", resource.name
517
+ assert_equal @project, resource.project
518
+ assert_equal "import_123", resource.table_name
519
+ assert resource.valid?
520
+
521
+ # import.import! would happen here
522
+ @local_database.stubs({
523
+ :tables => [:import_123],
524
+ :schema => [
525
+ [:id, {:primary_key => true, :type => :integer, :db_type => "BIGINT"}],
526
+ [:foo, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}],
527
+ [:bar, {:primary_key => false, :type => :string, :db_type => "VARCHAR"}]
528
+ ]
529
+ })
530
+ resource.save!
531
+ assert_equal "id", resource.primary_key_name
532
+ assert_equal "integer", resource.primary_key_type
533
+ end
534
+
535
+ test "source_dataset count" do
536
+ resource = new_resource.save!
537
+ dataset = mock('dataset', :count => 12345)
538
+ resource.expects(:source_dataset).yields(dataset)
539
+ assert_equal resource.source_dataset_count, 12345
540
+ end
541
+
542
+ #def test_unselecting_a_generated_field_before_transformation
543
+ #pend
544
+ #end
545
+
546
+ #def test_connection_limit_on_source_database
547
+ #pend
548
+ #end
549
+
550
+ #def test_connection_limit_on_local_database
551
+ #pend
552
+ #end
553
+
554
+ test "count by project" do
555
+ Resource.expects(:dataset).returns(mock {
556
+ expects(:naked).returns(self)
557
+ expects(:group_and_count).returns(self)
558
+ expects(:to_hash).with(:project_id, :count).returns({1 => 123})
559
+ })
560
+ assert_equal({1 => 123}, Resource.count_by_project)
561
+ end
562
+ end
563
+ end
564
+ end
@@ -0,0 +1,90 @@
1
+ require 'helper'
2
+
3
+ module Coupler
4
+ module Models
5
+ class TestResult < Coupler::Test::UnitTest
6
+ def new_result(attribs = {})
7
+ values = {
8
+ :scenario => @scenario
9
+ }.update(attribs)
10
+ r = Result.new(values)
11
+ r.stubs(:scenario_dataset).returns(stub({:all => [values[:scenario]]}))
12
+ r
13
+ end
14
+
15
+ def setup
16
+ super
17
+ @scenario = stub('scenario', :id => 100, :pk => 100, :associations => {}, :version => 42)
18
+ end
19
+
20
+ test "sequel model" do
21
+ assert_equal ::Sequel::Model, Result.superclass
22
+ assert_equal :results, Result.table_name
23
+ end
24
+
25
+ test "many to one scenario" do
26
+ assert_respond_to Result.new, :scenario
27
+ end
28
+
29
+ test "sets scenario version" do
30
+ result = new_result.save!
31
+ assert_equal 42, result.scenario_version
32
+ end
33
+
34
+ test "snapshot gets originating models" do
35
+ time = Time.now - 50
36
+ @scenario.stubs({
37
+ :updated_at => time, :project_id => 123,
38
+ :resource_1_id => 456, :resource_2_id => 789
39
+ })
40
+ result = new_result.save!
41
+
42
+ project = stub('project')
43
+ resource_1 = stub('resource 1')
44
+ resource_2 = stub('resource 2')
45
+ Scenario.expects(:as_of_version).with(100, 42).returns(@scenario)
46
+ Project.expects(:as_of_time).with(123, time).returns(project)
47
+ Resource.expects(:as_of_time).with(456, time).returns(resource_1)
48
+ Resource.expects(:as_of_time).with(789, time).returns(resource_2)
49
+
50
+ expected = {
51
+ :project => project, :scenario => @scenario,
52
+ :resource_1 => resource_1, :resource_2 => resource_2
53
+ }
54
+ assert_equal expected, result.snapshot
55
+ end
56
+
57
+ test "groups dataset" do
58
+ result = new_result(:run_number => 5).save!
59
+ ds = mock('dataset')
60
+ @scenario.expects(:local_database).yields(mock('database') {
61
+ expects(:[]).with(:groups_5).returns(ds)
62
+ })
63
+ result.groups_dataset do |actual|
64
+ assert_equal ds, actual
65
+ end
66
+ end
67
+
68
+ test "groups records dataset" do
69
+ result = new_result(:run_number => 5).save!
70
+ ds = mock('dataset')
71
+ @scenario.expects(:local_database).yields(mock('database') {
72
+ expects(:[]).with(:groups_records_5).returns(ds)
73
+ })
74
+ result.groups_records_dataset do |actual|
75
+ assert_equal ds, actual
76
+ end
77
+ end
78
+
79
+ test "groups table name" do
80
+ result = new_result(:run_number => 5).save!
81
+ assert_equal :groups_5, result.groups_table_name
82
+ end
83
+
84
+ test "groups records table name" do
85
+ result = new_result(:run_number => 5).save!
86
+ assert_equal :groups_records_5, result.groups_records_table_name
87
+ end
88
+ end
89
+ end
90
+ end