coupler 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
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,13 @@
1
+ Sequel.migration do
2
+ up do
3
+ [:projects, :projects_versions, :connections, :transformers, :transformers_versions].each do |name|
4
+ alter_table(name) { add_column(:last_accessed_at, Time) }
5
+ end
6
+ end
7
+
8
+ down do
9
+ [:projects, :projects_versions, :connections, :transformers, :transformers_versions].each do |name|
10
+ alter_table(name) { drop_column(:last_accessed_at) }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table(:results) do
4
+ drop_column(:score_set_id)
5
+ add_column(:run_number, Integer)
6
+ end
7
+ end
8
+
9
+ down do
10
+ alter_table(:results) do
11
+ drop_column(:run_number)
12
+ add_column(:score_set_id, Integer)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ Sequel.migration do
2
+ up do
3
+ # Fix scenario run_count
4
+ scenarios = self[:scenarios]
5
+ ds = scenarios.join(:results, :scenario_id => :id)
6
+ run_counts = ds.group_and_count(:scenario_id).all
7
+ run_counts.each do |row|
8
+ run_count = row[:count] > 1 ? 1 : 0
9
+ scenarios.filter(:id => row[:scenario_id]).update(:run_count => run_count)
10
+ end
11
+
12
+ # Delete all but the last result, since the other ones were overwritten
13
+ last_scenario_id = nil
14
+ results = self[:results]
15
+ results.order(:scenario_id, :id.desc).each do |result|
16
+ if result[:scenario_id] != last_scenario_id
17
+ last_scenario_id = result[:scenario_id]
18
+ results.filter(:id => result[:id]).update(:run_number => 1)
19
+ else
20
+ results.filter(:id => result[:id]).delete
21
+ end
22
+ end
23
+ end
24
+
25
+ down do
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table(:comparisons) do
4
+ rename_column :lhs_value, :raw_lhs_value
5
+ rename_column :rhs_value, :raw_rhs_value
6
+ end
7
+ end
8
+ down do
9
+ alter_table(:comparisons) do
10
+ rename_column :raw_lhs_value, :lhs_value
11
+ rename_column :raw_rhs_value, :rhs_value
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ Sequel.migration do
2
+ up do
3
+ Coupler::Models::Scenario.each do |scenario|
4
+ scenario.set_linkage_type
5
+ scenario.save
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,24 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table(:imports) do
4
+ add_column :field_names, String, :text => true
5
+ add_column :primary_key_name, String
6
+ add_column :has_headers, TrueClass
7
+ add_column :has_duplicate_keys, TrueClass
8
+ add_column :occurred_at, DateTime
9
+ rename_column :fields, :field_types
10
+ rename_column :data, :file_name
11
+ end
12
+ end
13
+ down do
14
+ alter_table(:imports) do
15
+ rename_column :file_name, :data
16
+ rename_column :field_types, :fields
17
+ drop_column :field_names
18
+ drop_column :primary_key_name
19
+ drop_column :has_headers
20
+ drop_column :has_duplicate_keys
21
+ drop_column :occurred_at
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table(:imports) do
4
+ rename_column :file_name, :data
5
+ end
6
+ end
7
+ down do
8
+ alter_table(:imports) do
9
+ rename_column :data, :file_name
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table(:connections) do
4
+ add_column :path, String
5
+ add_column :database_name, String
6
+ end
7
+ end
8
+
9
+ down do
10
+ alter_table(:connections) do
11
+ drop_column :path
12
+ drop_column :database_name
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ Sequel.migration do
2
+ up do
3
+ alter_table(:resources) { drop_column(:database_name) }
4
+ alter_table(:resources_versions) { drop_column(:database_name) }
5
+ end
6
+
7
+ down do
8
+ alter_table(:resources) { add_column(:database_name, String) }
9
+ alter_table(:resources_versions) { add_column(:database_name, String) }
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ Feature: managing connections
2
+
3
+ Scenario: creating a connection
4
+ When I go to the connections page
5
+ And I click the "New Connection" link
6
+ And I fill in the form:
7
+ | Name | Fake data |
8
+ | Type | MySQL |
9
+ | Host | localhost |
10
+ | Port | 12345 |
11
+ | Username | coupler |
12
+ | Password | cupla |
13
+ And I click the "Submit" button
14
+ Then it should show me a confirmation notice
15
+
16
+ Scenario: editing a connection
17
+ Given that I have created a connection called "My Connection"
18
+ When I go to the connections page
19
+ And I click the "Edit" link
20
+ And I change "Name" to "Server X"
21
+ And I click the "Submit" button
22
+ Then it should take me back to the connections page
23
+
24
+ Scenario: changing a connection that orphans resources
25
+
26
+ Scenario: deleting a connection
27
+
28
+ Scenario: deleting a connection that orphans resources
@@ -0,0 +1,35 @@
1
+ Feature: managing matchers
2
+
3
+ Background:
4
+ Given that I have created a connection called "My Connection"
5
+ And that I have created a project called "My Project"
6
+ And that I have added the "People" resource
7
+
8
+ Scenario: creating a matcher for a self-linkage scenario
9
+ Given that I have created a self-linkage scenario called "Link by Last name"
10
+ When I go to the scenario page
11
+ And I click the "Add matcher" link
12
+ And I click the "Add comparison" link
13
+ And I select "Field" as the first type
14
+ And I select "last_name" for "People [1]" as the first value
15
+ And I select "Field" as the second type
16
+ And I select "last_name" for "People [2]" as the second value
17
+ And I click the "Add" button
18
+ And I click the "Submit" button
19
+ Then it should take me back to the scenario page
20
+ And it should show me a confirmation notice
21
+
22
+ Scenario: creating a matcher for a dual-join scenario
23
+ Given that I have added the "Pets" resource
24
+ And that I have created a dual-linkage scenario called "Link by Last name"
25
+ When I go to the scenario page
26
+ And I click the "Add matcher" link
27
+ And I click the "Add comparison" link
28
+ And I select "Field" as the first type
29
+ And I select "last_name" for "People" as the first value
30
+ And I select "Field" as the second type
31
+ And I select "owner_last_name" for "Pets" as the second value
32
+ And I click the "Add" button
33
+ And I click the "Submit" button
34
+ Then it should take me back to the scenario page
35
+ And it should show me a confirmation notice
@@ -0,0 +1,11 @@
1
+ Feature: managing projects
2
+
3
+ Scenario: creating a project
4
+ When I go to the projects page
5
+ And I click the "New Project" link
6
+ And I fill in the form:
7
+ | Name | My Project |
8
+ | Description | This is a test project |
9
+ And I click the "Submit" button
10
+ Then it should show me a confirmation notice
11
+ And ask me to add a resource
@@ -0,0 +1,62 @@
1
+ Feature: managing resources
2
+ Background:
3
+ Given that I have created a project called "My Project"
4
+ And that I have created a transformer called "My Transformer"
5
+
6
+ Scenario: adding a resource
7
+ Given that I have created a connection called "My Connection"
8
+ When I go to the project page
9
+ And I click the "Add resource" link
10
+ And I choose a "Database" resource
11
+ And I fill in the form:
12
+ | Name | People |
13
+ | Connection | My Connection |
14
+ | Database (2) | fake_data |
15
+ | Table | people |
16
+ And I click the "Submit" button
17
+ Then it should show me a confirmation notice
18
+ And ask me to choose which fields I wish to select
19
+
20
+ Scenario: adding a resource and connection at the same time
21
+ When I go to the project page
22
+ And I click the "Add resource" link
23
+ And I choose a "Database" resource
24
+ And I fill in the form:
25
+ | Name (1) | Fake data |
26
+ | Type | MySQL |
27
+ | Host | localhost |
28
+ | Port | 12345 |
29
+ | Username | coupler |
30
+ | Password | cupla |
31
+ | Name (2) | People |
32
+ | Database (2) | fake_data |
33
+ | Table | people |
34
+ And I click the "Submit" button
35
+ Then it should show me a confirmation notice
36
+
37
+ Scenario: adding a transformation
38
+ Given that I have created a connection called "My Connection"
39
+ And that I have added the "People" resource
40
+ When I go to the resource page
41
+ And I click on the hammer icon next to the "first_name" field
42
+ And I fill in the form:
43
+ | Transformer | My Transformer |
44
+ And I click the "Finish" button
45
+ Then it should show me a confirmation notice
46
+
47
+ Scenario: deleting a transformation
48
+ Given that I have created a connection called "My Connection"
49
+ And that I have added the "People" resource
50
+ And that I have added a transformation for "first_name"
51
+ When I go to the resource page
52
+ And I click on the cog icon next to the "first_name" field
53
+ And I click the "Delete" link
54
+ Then there should be no more transformations
55
+
56
+ Scenario: transforming a resource
57
+ Given that I have created a connection called "My Connection"
58
+ And that I have added the "People" resource
59
+ And that I have added a transformation for "first_name"
60
+ When I go to the resource page
61
+ And I click the "Transform now" button with confirmation
62
+ Then it should start transforming
@@ -0,0 +1,45 @@
1
+ Feature: managing scenarios
2
+ Background:
3
+ Given that I have created a connection called "My Connection"
4
+ And that I have created a project called "My Project"
5
+ And that I have added the "People" resource
6
+
7
+ Scenario: creating a self-linkage scenario
8
+ When I go to the project page
9
+ And I click the "Create scenario" link
10
+ And I fill in the form:
11
+ | Name | Link by Last name |
12
+ And I click the "People" resource
13
+ And I click the "Submit" button
14
+ Then it should show me a confirmation notice
15
+ And ask me to add matchers
16
+
17
+ Scenario: creating a dual-linkage scenario
18
+ Given that I have added the "Pets" resource
19
+ When I go to the project page
20
+ And I click the "Create scenario" link
21
+ And I fill in the form:
22
+ | Name | Link by name |
23
+ And I click the "People" resource
24
+ And I click the "Pets" resource
25
+ And I click the "Submit" button
26
+ Then it should show me a confirmation notice
27
+ And ask me to add matchers
28
+
29
+ Scenario: running a self-linkage scenario
30
+ Given that I have created a self-linkage scenario called "Link by Last name"
31
+ And that I have added a matcher with these options:
32
+ | Type 1 | Value 1 | Operator | Type 2 | Value 2 |
33
+ | field | last_name | equals | field | last_name |
34
+ When I go to the scenario page
35
+ And I click the "Run now" button with confirmation
36
+ Then it should start the linkage process
37
+
38
+ Scenario: running a scenario with a non-equality matcher
39
+ Given that I have created a self-linkage scenario called "Link by Last name"
40
+ And that I have added a matcher with these options:
41
+ | Type 1 | Value 1 | Operator | Type 2 | Value 2 |
42
+ | field | last_name | does_not_equal | field | last_name |
43
+ When I go to the scenario page
44
+ And I click the "Run now" button with confirmation
45
+ Then it should start the linkage process
@@ -0,0 +1,145 @@
1
+ Given /^that I have created a connection called "(.+?)"$/ do |connection_name|
2
+ @connection_name = connection_name
3
+ @connection = Factory(:connection, :name => connection_name)
4
+ end
5
+
6
+ Given /^that I have created a project called "(.+?)"$/ do |project_name|
7
+ @project_name = project_name
8
+ @project = Factory(:project, :name => project_name)
9
+ end
10
+
11
+ Given /^that I have created a transformer called "(.+?)"$/ do |transformer_name|
12
+ @transformer_name = transformer_name
13
+ @transformer = Factory(:transformer, :name => transformer_name)
14
+ end
15
+
16
+ Given /^that I have added the "(.+?)" resource$/ do |resource_name|
17
+ @resource_name = resource_name
18
+ options = case resource_name
19
+ when "People"
20
+ { :table_name => "people" }
21
+ when "Pets"
22
+ { :table_name => "pets" }
23
+ end
24
+ @resources ||= []
25
+ @resources << Factory(:resource, {:name => resource_name, :project => @project, :connection => @connection}.merge(options))
26
+ end
27
+
28
+ Given /^that I have added a transformation for "([^\"]*)"$/ do |field|
29
+ resource = @resources[0]
30
+ @transformation = Factory(:transformation, {
31
+ :resource => resource, :transformer => @transformer,
32
+ :source_field => resource.fields_dataset[:name => field]
33
+ })
34
+ end
35
+
36
+ Given /^that I have created a self-linkage scenario called "([^"]*)"$/ do |scenario_name|
37
+ @scenario = Factory(:scenario, {
38
+ :name => scenario_name, :resource_1_id => @resources[0].id,
39
+ :project => @project
40
+ })
41
+ end
42
+
43
+ Given /^that I have created a dual-linkage scenario called "([^"]*)"$/ do |scenario_name|
44
+ @scenario = Factory(:scenario, {
45
+ :name => scenario_name, :project => @project,
46
+ :resource_1_id => @resources[0].id, :resource_2_id => @resources[1].id
47
+ })
48
+ end
49
+
50
+ Given /^that I have added a matcher with these options:$/ do |table|
51
+ comparisons_attributes = []
52
+ resources = @scenario.resources
53
+ table.hashes.each do |hash|
54
+ lhs_value = hash["Type 1"] == "field" ? resources[0].fields_dataset[:name => hash["Value 1"]].id : hash["Value 1"]
55
+ rhs_value = hash["Type 2"] == "field" ? resources[-1].fields_dataset[:name => hash["Value 2"]].id : hash["Value 2"]
56
+ comparisons_attributes << {
57
+ "lhs_type" => hash["Type 1"], "lhs_value" => lhs_value,
58
+ "rhs_type" => hash["Type 2"], "rhs_value" => rhs_value,
59
+ "operator" => hash["Operator"]
60
+ }
61
+ end
62
+ @matcher = Factory(:matcher, {
63
+ :comparisons_attributes => comparisons_attributes,
64
+ :scenario => @scenario
65
+ })
66
+ end
67
+
68
+ When /^I go to the (.+?) page$/ do |page_name|
69
+ @page_name = page_name
70
+ path = case page_name
71
+ when "front"
72
+ "/"
73
+ when "connections"
74
+ "/connections"
75
+ when "projects"
76
+ "/projects"
77
+ when "project"
78
+ "/projects/#{@project.id}"
79
+ when "resource"
80
+ "/projects/#{@project.id}/resources/#{@resources[0].id}"
81
+ when "transformations"
82
+ "/projects/#{@project.id}/resources/#{@resources[0].id}/transformations"
83
+ when "scenario"
84
+ "/projects/#{@project.id}/scenarios/#{@scenario.id}"
85
+ end
86
+ visit("http://localhost:4567#{path}")
87
+ end
88
+
89
+ When /^I click the "(.+?)" link$/ do |link_name|
90
+ link = browser.link(:text, link_name)
91
+ assert link.exist?, "can't find the '#{link_name}' link"
92
+ link.click
93
+ end
94
+
95
+ When /^I fill in the form:$/ do |table|
96
+ form = browser.forms.first
97
+ table.raw.each do |(label_or_name, value)|
98
+ md = label_or_name.match(/\s*\((\d+)\)\s*$/)
99
+ args = md ? [md.pre_match, md[1].to_i - 1] : [label_or_name]
100
+ elt = find_visible_element_by_label_or_id(*args)
101
+ if elt.nil?
102
+ puts current_page_source
103
+ end
104
+ assert elt && elt.exist?, "can't find element with label or name of '#{label_or_name}'"
105
+
106
+ case elt
107
+ when Celerity::TextField
108
+ elt.value = value
109
+ when Celerity::SelectList
110
+ value.split("/").each do |v|
111
+ elt.object.get_options.find do |option|
112
+ option.text_content == v || option.value_attribute == v
113
+ end.click
114
+ end
115
+ else
116
+ raise "unknown field type: #{elt.to_xml}"
117
+ end
118
+ end
119
+ end
120
+
121
+ When /^I click the "(.+?)" button$/ do |button_name|
122
+ click_button(button_name)
123
+ end
124
+
125
+ When /^I click the "(.+?)" button with confirmation$/ do |button_name|
126
+ browser.confirm(true) do
127
+ click_button(button_name)
128
+ end
129
+ end
130
+
131
+ Then /^(?:it should )?show me a confirmation notice$/ do
132
+ assert_match /successfully created|created successfully/, current_page_source
133
+ end
134
+
135
+ Then /^ask me to (.+)$/ do |question|
136
+ question = question.sub(/\bI\b/, "you")
137
+ assert current_page_source.include?(question)
138
+ end
139
+
140
+ Then /^it should take me back to the (\w+) page$/ do |page_name|
141
+ case page_name
142
+ when 'resource'
143
+ assert_match %r{/projects/#{@project.id}/resources/#{@resources[0].id}$}, current_url
144
+ end
145
+ end
@@ -0,0 +1,26 @@
1
+ When /^I select "([^\"]*)" as the (first|second) type$/ do |type, which|
2
+ name = case which
3
+ when "first" then "lhs"
4
+ when "second" then "rhs"
5
+ else raise "bad which"
6
+ end
7
+ browser.select_list(:id => "#{name}_type").select(type)
8
+ end
9
+
10
+ When /^I select "([^\"]*)" for "([^\"]*)" as the (first|second) value$/ do |field, resource, which|
11
+ name = case which
12
+ when "first" then "lhs"
13
+ when "second" then "rhs"
14
+ else raise "bad which"
15
+ end
16
+ s = browser.select_list(:id => "#{name}_value_select")
17
+ optgroup = s.object.child_nodes.detect do |node|
18
+ Java::ComGargoylesoftwareHtmlunitHtml::HtmlOptionGroup === node &&
19
+ node.label_attribute == resource
20
+ end
21
+ option = optgroup.child_nodes.detect do |node|
22
+ Java::ComGargoylesoftwareHtmlunitHtml::HtmlOption === node &&
23
+ node.text == field
24
+ end
25
+ s.object.set_selected_attribute(option, true)
26
+ end
@@ -0,0 +1,12 @@
1
+ When /I click on the (\w+) icon next to the "([^"]+)" field/ do |icon, field|
2
+ image = browser.cell(:text => field).parent.image(:src => /#{icon}/)
3
+ image.parent.click
4
+ end
5
+
6
+ When /I choose a "([^"]+)" resource/ do |name|
7
+ browser.execute_script(%{$('#resource-#{name.downcase}').show();})
8
+ end
9
+
10
+ Then /^it should start transforming$/ do
11
+ assert_match /running/, current_page_source
12
+ end
@@ -0,0 +1,7 @@
1
+ When /^I click the "([^"]+)" resource/ do |resource_name|
2
+ browser.li(:text, resource_name).click
3
+ end
4
+
5
+ Then /^it should start the linkage process$/ do
6
+ assert_match /running/, current_page_source
7
+ end
@@ -0,0 +1,3 @@
1
+ Then /^there should be no more transformations$/ do
2
+ assert_equal 0, @resources.last.transformations_dataset.count
3
+ end
@@ -0,0 +1,128 @@
1
+ require File.dirname(__FILE__) + "/../../test/helper"
2
+ require 'test/unit/assertions'
3
+ require 'celerity'
4
+
5
+ module CouplerWorld
6
+ include Test::Unit::Assertions
7
+
8
+ def app
9
+ Coupler::Base.set :environment, :test
10
+ Coupler::Base
11
+ end
12
+
13
+ def browser
14
+ unless @browser
15
+ @browser = Celerity::Browser.new({
16
+ :javascript_exceptions => true, :viewer => "127.0.0.1:6429",
17
+ :resynchronize => true, :css => true
18
+ })
19
+ end
20
+ @browser
21
+ end
22
+
23
+ def visit(url)
24
+ browser.goto(url)
25
+ end
26
+
27
+ def current_url
28
+ browser.page.web_response.request_url.to_string
29
+ end
30
+
31
+ def current_page_source
32
+ return nil unless browser.page
33
+
34
+ string_writer = java.io.StringWriter.new
35
+ print_writer = java.io.PrintWriter.new(string_writer)
36
+
37
+ root = browser.page.document_element
38
+ node_to_xml(root, print_writer)
39
+ print_writer.close
40
+ string_writer.to_string
41
+ end
42
+
43
+ # Fill in a text field with a value
44
+ def fill_in(label_or_name, options = {})
45
+ elt = find_element_by_label_or_name(:text_field, label_or_name)
46
+ if elt.exist?
47
+ elt.value = options[:with]
48
+ end
49
+ end
50
+
51
+ def select(option_text, options = {})
52
+ elt = find_element_by_label_or_name(:select_list, options[:from])
53
+ if elt.exist?
54
+ begin
55
+ elt.select(option_text)
56
+ rescue Celerity::Exception::CelerityException
57
+ elt.select_value(option_text)
58
+ end
59
+ end
60
+ end
61
+
62
+ def click_button(button_value)
63
+ browser.button(button_value).click
64
+ end
65
+
66
+ def find_visible_element_by_label_or_id(label_or_id, which = 0)
67
+ labels = browser.labels.select do |label|
68
+ object = label.object
69
+ object.textContent == label_or_id && object.displayed?
70
+ end
71
+ id = labels.empty? ? label_or_id : labels[which].for
72
+ browser.elements_by_xpath("id('#{id}')")[0]
73
+ end
74
+
75
+ private
76
+ # NOTE: I have to do this because HtmlUnit's asXml likes to put spaces
77
+ # and newlines in the middle of whitespace-sensitive tags (like
78
+ # <a> and <textarea>). Fail.
79
+ def node_to_xml(node, print_writer)
80
+ closing_tag = false
81
+
82
+ case node
83
+ when HtmlUnit::Html::DomText
84
+ # just print out the text
85
+ print_writer.write(HtmlUnit::Util::StringUtils.escape_xml_chars(node.data))
86
+ when HtmlUnit::Html::DomCDataSection, HtmlUnit::Html::DomProcessingInstruction
87
+ # use default printXml here
88
+ node.print_xml("", print_writer)
89
+ when HtmlUnit::Html::DomComment
90
+ print_writer.write("<!-- #{node.data} -->")
91
+ when HtmlUnit::Html::HtmlTextArea
92
+ node_print_opening_tag(node, print_writer)
93
+ print_writer.write(node.text)
94
+ closing_tag = true
95
+ else
96
+ node_print_opening_tag(node, print_writer)
97
+ closing_tag = true
98
+ end
99
+
100
+ child = node.first_child
101
+ while child
102
+ node_to_xml(child, print_writer)
103
+ child = child.next_sibling
104
+ end
105
+
106
+ node_print_closing_tag(node, print_writer) if closing_tag
107
+ end
108
+
109
+ def node_print_opening_tag(node, print_writer)
110
+ print_writer.write("<")
111
+ node.print_opening_tag_content_as_xml(print_writer)
112
+ print_writer.write(">")
113
+ end
114
+
115
+ def node_print_closing_tag(node, print_writer)
116
+ print_writer.write("</#{node.tag_name}>")
117
+ end
118
+ end
119
+
120
+ Before do
121
+ database = Coupler::Database.instance
122
+ database.tables.each do |name|
123
+ next if name == :schema_info
124
+ database[name].delete
125
+ end
126
+ end
127
+
128
+ World(CouplerWorld)