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,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)