data_active 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. data/.gitignore +35 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +4 -0
  4. data/README.rdoc +275 -0
  5. data/Rakefile +2 -0
  6. data/data_active.gemspec +28 -0
  7. data/features/remove_records_missing_in_xml.feature +30 -0
  8. data/features/step_definitions/remove_records_missing_in_xml.rb +85 -0
  9. data/features/step_definitions/step_helper.rb +15 -0
  10. data/features/step_definitions/sync_books_with_xml.rb +224 -0
  11. data/features/step_definitions/update_database_with_xml.rb +158 -0
  12. data/features/step_definitions/web_steps.rb +211 -0
  13. data/features/support/env.rb +50 -0
  14. data/features/support/fixtures/fresh/book_prices.yml +6 -0
  15. data/features/support/fixtures/fresh/books.yml +7 -0
  16. data/features/support/fixtures/fresh/chapters.yml +35 -0
  17. data/features/support/fixtures/fresh/pages.yml +149 -0
  18. data/features/support/fixtures/no_matching_records/book_prices.yml +6 -0
  19. data/features/support/fixtures/no_matching_records/books.yml +7 -0
  20. data/features/support/fixtures/no_matching_records/chapters.yml +35 -0
  21. data/features/support/fixtures/no_matching_records/pages.yml +149 -0
  22. data/features/support/fixtures/without_chapters/books.yml +7 -0
  23. data/features/support/fixtures/without_one_to_one/books.yml +7 -0
  24. data/features/support/fixtures/without_one_to_one/chapters.yml +35 -0
  25. data/features/support/fixtures/without_one_to_one/pages.yml +149 -0
  26. data/features/support/fixtures/xml/books_changed.xml +173 -0
  27. data/features/support/fixtures/xml/books_fresh.xml +173 -0
  28. data/features/support/fixtures/xml/books_one_to_one_changed.xml +173 -0
  29. data/features/support/fixtures/xml/books_one_to_one_mismatch.xml +173 -0
  30. data/features/support/fixtures/xml/books_one_to_one_removed.xml +167 -0
  31. data/features/support/fixtures/xml/books_simple.xml +15 -0
  32. data/features/support/fixtures/xml/books_with_changed_chapters.xml +40 -0
  33. data/features/support/fixtures/xml/books_with_chapters.xml +45 -0
  34. data/features/support/fixtures/xml/books_with_many_one_to_one_records.xml +179 -0
  35. data/features/support/fixtures/xml/books_with_mismatched_chapters.xml +173 -0
  36. data/features/support/fixtures/xml/books_with_moved_chapters.xml +173 -0
  37. data/features/support/fixtures/xml/books_with_one_to_one.xml +167 -0
  38. data/features/support/fixtures/xml/books_with_removed_chapters.xml +113 -0
  39. data/features/support/fixtures/xml/books_without_chapters.xml +11 -0
  40. data/features/support/fixtures/xml/books_without_one_to_one.xml +167 -0
  41. data/features/support/fixtures/xml/ms_access/book.xml +201 -0
  42. data/features/support/fixtures/xml/ms_access/book.xsd +425 -0
  43. data/features/support/fixtures/xml/ms_access/books_changed.xml +158 -0
  44. data/features/support/fixtures/xml/ms_access/books_fresh.xml +173 -0
  45. data/features/support/fixtures/xml/ms_access/books_one_to_one_changed.xml +173 -0
  46. data/features/support/fixtures/xml/ms_access/books_one_to_one_mismatch.xml +173 -0
  47. data/features/support/fixtures/xml/ms_access/books_one_to_one_removed.xml +167 -0
  48. data/features/support/fixtures/xml/ms_access/books_simple.xml +15 -0
  49. data/features/support/fixtures/xml/ms_access/books_with_changed_chapters.xml +40 -0
  50. data/features/support/fixtures/xml/ms_access/books_with_chapters.xml +45 -0
  51. data/features/support/fixtures/xml/ms_access/books_with_many_one_to_one_records.xml +179 -0
  52. data/features/support/fixtures/xml/ms_access/books_with_mismatched_chapters.xml +173 -0
  53. data/features/support/fixtures/xml/ms_access/books_with_moved_chapters.xml +173 -0
  54. data/features/support/fixtures/xml/ms_access/books_with_one_to_one.xml +167 -0
  55. data/features/support/fixtures/xml/ms_access/books_with_removed_chapters.xml +113 -0
  56. data/features/support/fixtures/xml/ms_access/books_without_chapters.xml +11 -0
  57. data/features/support/fixtures/xml/ms_access/books_without_one_to_one.xml +167 -0
  58. data/features/support/paths.rb +33 -0
  59. data/features/support/selectors.rb +39 -0
  60. data/features/sync_database_with_xml.feature +34 -0
  61. data/features/sync_one_to_many.feature +34 -0
  62. data/features/sync_one_to_one.feature +33 -0
  63. data/features/update_database_with_xml.feature +30 -0
  64. data/lib/data_active.rb +309 -0
  65. data/lib/data_active/version.rb +3 -0
  66. data/test_apps/book_store_rails_31x/.gitignore +15 -0
  67. data/test_apps/book_store_rails_31x/.rvmrc +1 -0
  68. data/test_apps/book_store_rails_31x/Gemfile +53 -0
  69. data/test_apps/book_store_rails_31x/README +261 -0
  70. data/test_apps/book_store_rails_31x/Rakefile +7 -0
  71. data/test_apps/book_store_rails_31x/app/assets/images/rails.png +0 -0
  72. data/test_apps/book_store_rails_31x/app/assets/javascripts/application.js +9 -0
  73. data/test_apps/book_store_rails_31x/app/assets/stylesheets/application.css +7 -0
  74. data/test_apps/book_store_rails_31x/app/controllers/application_controller.rb +3 -0
  75. data/test_apps/book_store_rails_31x/app/helpers/application_helper.rb +2 -0
  76. data/test_apps/book_store_rails_31x/app/mailers/.gitkeep +0 -0
  77. data/test_apps/book_store_rails_31x/app/models/.gitkeep +0 -0
  78. data/test_apps/book_store_rails_31x/app/models/book.rb +4 -0
  79. data/test_apps/book_store_rails_31x/app/models/book_price.rb +3 -0
  80. data/test_apps/book_store_rails_31x/app/models/chapter.rb +4 -0
  81. data/test_apps/book_store_rails_31x/app/models/page.rb +3 -0
  82. data/test_apps/book_store_rails_31x/app/views/layouts/application.html.erb +14 -0
  83. data/test_apps/book_store_rails_31x/config.ru +4 -0
  84. data/test_apps/book_store_rails_31x/config/application.rb +48 -0
  85. data/test_apps/book_store_rails_31x/config/boot.rb +6 -0
  86. data/test_apps/book_store_rails_31x/config/database.yml +28 -0
  87. data/test_apps/book_store_rails_31x/config/environment.rb +5 -0
  88. data/test_apps/book_store_rails_31x/config/environments/development.rb +30 -0
  89. data/test_apps/book_store_rails_31x/config/environments/production.rb +60 -0
  90. data/test_apps/book_store_rails_31x/config/environments/test.rb +39 -0
  91. data/test_apps/book_store_rails_31x/config/initializers/backtrace_silencers.rb +7 -0
  92. data/test_apps/book_store_rails_31x/config/initializers/inflections.rb +10 -0
  93. data/test_apps/book_store_rails_31x/config/initializers/mime_types.rb +5 -0
  94. data/test_apps/book_store_rails_31x/config/initializers/secret_token.rb +7 -0
  95. data/test_apps/book_store_rails_31x/config/initializers/session_store.rb +8 -0
  96. data/test_apps/book_store_rails_31x/config/initializers/wrap_parameters.rb +14 -0
  97. data/test_apps/book_store_rails_31x/config/locales/en.yml +5 -0
  98. data/test_apps/book_store_rails_31x/config/routes.rb +58 -0
  99. data/test_apps/book_store_rails_31x/db/migrate/20120422053943_create_books.rb +9 -0
  100. data/test_apps/book_store_rails_31x/db/migrate/20120422054008_create_chapters.rb +11 -0
  101. data/test_apps/book_store_rails_31x/db/migrate/20120422054033_create_pages.rb +11 -0
  102. data/test_apps/book_store_rails_31x/db/migrate/20120422054123_create_book_prices.rb +12 -0
  103. data/test_apps/book_store_rails_31x/db/schema.rb +47 -0
  104. data/test_apps/book_store_rails_31x/db/seeds.rb +7 -0
  105. data/test_apps/book_store_rails_31x/lib/assets/.gitkeep +0 -0
  106. data/test_apps/book_store_rails_31x/lib/tasks/.gitkeep +0 -0
  107. data/test_apps/book_store_rails_31x/log/.gitkeep +0 -0
  108. data/test_apps/book_store_rails_31x/public/404.html +26 -0
  109. data/test_apps/book_store_rails_31x/public/422.html +26 -0
  110. data/test_apps/book_store_rails_31x/public/500.html +26 -0
  111. data/test_apps/book_store_rails_31x/public/favicon.ico +0 -0
  112. data/test_apps/book_store_rails_31x/public/index.html +241 -0
  113. data/test_apps/book_store_rails_31x/public/robots.txt +5 -0
  114. data/test_apps/book_store_rails_31x/script/rails +6 -0
  115. data/test_apps/book_store_rails_31x/test/fixtures/.gitkeep +0 -0
  116. data/test_apps/book_store_rails_31x/test/functional/.gitkeep +0 -0
  117. data/test_apps/book_store_rails_31x/test/integration/.gitkeep +0 -0
  118. data/test_apps/book_store_rails_31x/test/performance/browsing_test.rb +12 -0
  119. data/test_apps/book_store_rails_31x/test/test_helper.rb +13 -0
  120. data/test_apps/book_store_rails_31x/test/unit/.gitkeep +0 -0
  121. data/test_apps/book_store_rails_31x/vendor/assets/stylesheets/.gitkeep +0 -0
  122. data/test_apps/book_store_rails_31x/vendor/plugins/.gitkeep +0 -0
  123. data/test_apps/book_store_rails_32x/.gitignore +15 -0
  124. data/test_apps/book_store_rails_32x/.rvmrc +1 -0
  125. data/test_apps/book_store_rails_32x/Gemfile +47 -0
  126. data/test_apps/book_store_rails_32x/README.rdoc +261 -0
  127. data/test_apps/book_store_rails_32x/Rakefile +14 -0
  128. data/test_apps/book_store_rails_32x/app/assets/images/rails.png +0 -0
  129. data/test_apps/book_store_rails_32x/app/assets/javascripts/application.js +15 -0
  130. data/test_apps/book_store_rails_32x/app/assets/stylesheets/application.css +13 -0
  131. data/test_apps/book_store_rails_32x/app/controllers/application_controller.rb +3 -0
  132. data/test_apps/book_store_rails_32x/app/helpers/application_helper.rb +2 -0
  133. data/test_apps/book_store_rails_32x/app/mailers/.gitkeep +0 -0
  134. data/test_apps/book_store_rails_32x/app/models/.gitkeep +0 -0
  135. data/test_apps/book_store_rails_32x/app/models/book.rb +4 -0
  136. data/test_apps/book_store_rails_32x/app/models/book_price.rb +3 -0
  137. data/test_apps/book_store_rails_32x/app/models/chapter.rb +4 -0
  138. data/test_apps/book_store_rails_32x/app/models/page.rb +3 -0
  139. data/test_apps/book_store_rails_32x/app/views/layouts/application.html.erb +14 -0
  140. data/test_apps/book_store_rails_32x/config.ru +4 -0
  141. data/test_apps/book_store_rails_32x/config/application.rb +59 -0
  142. data/test_apps/book_store_rails_32x/config/boot.rb +6 -0
  143. data/test_apps/book_store_rails_32x/config/cucumber.yml +8 -0
  144. data/test_apps/book_store_rails_32x/config/database.yml +28 -0
  145. data/test_apps/book_store_rails_32x/config/environment.rb +5 -0
  146. data/test_apps/book_store_rails_32x/config/environments/development.rb +37 -0
  147. data/test_apps/book_store_rails_32x/config/environments/production.rb +67 -0
  148. data/test_apps/book_store_rails_32x/config/environments/test.rb +37 -0
  149. data/test_apps/book_store_rails_32x/config/initializers/backtrace_silencers.rb +7 -0
  150. data/test_apps/book_store_rails_32x/config/initializers/inflections.rb +15 -0
  151. data/test_apps/book_store_rails_32x/config/initializers/mime_types.rb +5 -0
  152. data/test_apps/book_store_rails_32x/config/initializers/secret_token.rb +7 -0
  153. data/test_apps/book_store_rails_32x/config/initializers/session_store.rb +8 -0
  154. data/test_apps/book_store_rails_32x/config/initializers/wrap_parameters.rb +14 -0
  155. data/test_apps/book_store_rails_32x/config/locales/en.yml +5 -0
  156. data/test_apps/book_store_rails_32x/config/routes.rb +58 -0
  157. data/test_apps/book_store_rails_32x/db/migrate/20120422043253_create_books.rb +9 -0
  158. data/test_apps/book_store_rails_32x/db/migrate/20120422043434_create_chapters.rb +11 -0
  159. data/test_apps/book_store_rails_32x/db/migrate/20120422043553_create_pages.rb +11 -0
  160. data/test_apps/book_store_rails_32x/db/migrate/20120422043700_create_book_prices.rb +12 -0
  161. data/test_apps/book_store_rails_32x/db/schema.rb +47 -0
  162. data/test_apps/book_store_rails_32x/db/seeds.rb +7 -0
  163. data/test_apps/book_store_rails_32x/lib/assets/.gitkeep +0 -0
  164. data/test_apps/book_store_rails_32x/lib/tasks/.gitkeep +0 -0
  165. data/test_apps/book_store_rails_32x/lib/tasks/cucumber.rake +65 -0
  166. data/test_apps/book_store_rails_32x/log/.gitkeep +0 -0
  167. data/test_apps/book_store_rails_32x/public/404.html +26 -0
  168. data/test_apps/book_store_rails_32x/public/422.html +26 -0
  169. data/test_apps/book_store_rails_32x/public/500.html +25 -0
  170. data/test_apps/book_store_rails_32x/public/favicon.ico +0 -0
  171. data/test_apps/book_store_rails_32x/public/index.html +241 -0
  172. data/test_apps/book_store_rails_32x/public/robots.txt +5 -0
  173. data/test_apps/book_store_rails_32x/script/cucumber +10 -0
  174. data/test_apps/book_store_rails_32x/script/rails +6 -0
  175. data/test_apps/book_store_rails_32x/test/fixtures/.gitkeep +0 -0
  176. data/test_apps/book_store_rails_32x/test/functional/.gitkeep +0 -0
  177. data/test_apps/book_store_rails_32x/test/integration/.gitkeep +0 -0
  178. data/test_apps/book_store_rails_32x/test/performance/browsing_test.rb +12 -0
  179. data/test_apps/book_store_rails_32x/test/test_helper.rb +13 -0
  180. data/test_apps/book_store_rails_32x/test/unit/.gitkeep +0 -0
  181. data/test_apps/book_store_rails_32x/vendor/assets/javascripts/.gitkeep +0 -0
  182. data/test_apps/book_store_rails_32x/vendor/assets/stylesheets/.gitkeep +0 -0
  183. data/test_apps/book_store_rails_32x/vendor/plugins/.gitkeep +0 -0
  184. metadata +452 -0
@@ -0,0 +1,15 @@
1
+ module StepHelper
2
+ def StepHelper.load_fixtures(path)
3
+ fixtures_folder = path
4
+ fixtures = Dir[File.join(fixtures_folder, '*.yml')].map {|f| File.basename(f, '.yml') }
5
+
6
+ if defined? Fixtures == nil
7
+ Fixtures.reset_cache
8
+ Fixtures.create_fixtures(fixtures_folder, fixtures)
9
+ else
10
+ ActiveRecord::Fixtures.reset_cache
11
+ ActiveRecord::Fixtures.create_fixtures(fixtures_folder, fixtures)
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,224 @@
1
+ require "nokogiri"
2
+ require "data_active"
3
+ require_relative "step_helper"
4
+ require "active_record/fixtures"
5
+
6
+ Given /^I have no books$/ do
7
+ Book.destroy_all
8
+ books_in_database = Book.all
9
+ if books_in_database.count > 0
10
+ fail "Records still exist in the database"
11
+ end
12
+ end
13
+
14
+ When /^I have the "([^"]*)" file$/ do |xml_document_file|
15
+ if File.exists?(xml_document_file)
16
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
17
+ xml_document.children.first.name.downcase.eql?("books") || xml_document.children.first.name.downcase.eql?("book")
18
+ else
19
+ fail "XML File doesn't exist"
20
+ end
21
+ end
22
+
23
+ When /^I synchronise with "([^"]*)"$/ do |xml_document_file|
24
+ Book.many_from_xml(File.open(Rails.root.join(xml_document_file)).read, [:sync]) != nil
25
+ end
26
+
27
+ When /^I synchronise with "([^"]*)" I should get an error$/ do |xml_document_file|
28
+ begin
29
+ Book.many_from_xml(File.open(Rails.root.join(xml_document_file)).read, [:sync]) != nil
30
+ fail "Error was didn't happen"
31
+ rescue Exception => e
32
+ if e.message.exclude? "Too many records for one to one association"
33
+ fail "Wrong exception was raised"
34
+ end
35
+ end
36
+ end
37
+
38
+ When /^I update with "([^"]*)"$/ do |xml_document_file|
39
+ @original_books = Book.all
40
+ @original_chapters = Chapter.all
41
+ @original_pages = Page.all
42
+ Book.many_from_xml(File.open(Rails.root.join(xml_document_file)).read, [:update]) != nil
43
+ end
44
+
45
+ Then /^the books in the database will be identical to those in "([^"]*)"$/ do |xml_document_file|
46
+ books_in_database = Book.all
47
+ if books_in_database.count > 0
48
+ books_xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
49
+
50
+ # Ensure that all books in the xml document have been recorded
51
+ book_elements = books_xml_document.xpath("//book")
52
+ book_elements.each do |book_element|
53
+ book_id = book_element.xpath("//book/id")[0].text
54
+ book_name = book_element.xpath("//book/name")[0].text
55
+ book = Book.find(book_id)
56
+ if book == nil
57
+ fail "Books with id #{book_id} is missing"
58
+ else
59
+ if book_name != book.name
60
+ fail "Book name in database doesn't match book name in xml for book with id #{book_id}, XML: #{book_name}, Database: #{book.name}"
61
+ end
62
+ end
63
+ end
64
+
65
+ # Ensure there are not extra books
66
+ books_in_xml = books_xml_document.xpath("//book")
67
+ if books_in_database.count != books_in_xml.count
68
+ fail "There number of books in the database (#{books_in_database.count}) doesn't match the number of books in the xml document (#{books_in_xml.count})"
69
+ end
70
+
71
+ else
72
+ fail "no books recorded"
73
+ end
74
+ end
75
+
76
+ When /^the book price will be identical to those in "([^"]*)"$/ do |xml_document_file|
77
+ book_prices_in_database = BookPrice.all
78
+ if book_prices_in_database.count > 0
79
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
80
+
81
+ # Ensure that all chapters in the xml document have been recorded
82
+
83
+ xml_document.xpath("//book").each do |book_element|
84
+ book_id = book_element.xpath("id").text
85
+
86
+ xml_document.xpath("//book[id[text()='#{book_id}']]/book_price").each do |book_price_element|
87
+ book_price_id = book_price_element.xpath("id")[0].text
88
+ book_price = BookPrice.find book_price_id
89
+ if book_price.nil?
90
+ fail "BookPrice with id #{book_price_id} is missing"
91
+ else
92
+ book_price_sell = book_price_element.xpath("sell").text
93
+ book_price_educational = book_price_element.xpath("educational").text
94
+ book_price_cost = book_price_element.xpath("cost").text
95
+
96
+ if Float(book_price_sell) != book_price.sell
97
+ fail "BookPrice 'sell' in database doesn't match book price sell in xml for book price with id #{book_price_id}, XML: #{book_price_sell}, Database: #{book_price.sell}"
98
+ end
99
+
100
+ if Float(book_price_cost) != book_price.cost
101
+ fail "BookPrice 'cost' in database doesn't match book price cost in xml for book price with id #{book_price_id}, XML: #{book_price_cost}, Database: #{book_price.cost}"
102
+ end
103
+
104
+ if Float(book_price_educational) != book_price.educational
105
+ fail "BookPrice 'educational' in database doesn't match book price educational in xml for book price with id #{book_price_id}, XML: #{book_price_educational}, Database: #{book_price.educational}"
106
+ end
107
+
108
+ if Integer(book_id) != book_price.book_id
109
+ fail "BookPrice 'book_id' in database doesn't match book_id in xml for book price with id #{book_price_id}, XML: #{book_id}, Database: #{book_price.book_id}"
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ # Ensure there are not extra book prices
116
+ book_prices_in_xml = xml_document.xpath("//book_price")
117
+ if book_prices_in_database.count != book_prices_in_xml.count
118
+ fail "There number of book prices in the database (#{book_prices_in_database.count}) doesn't match the number of book prices in the xml document (#{book_prices_in_xml.count})"
119
+ end
120
+ end
121
+ end
122
+
123
+ When /^the chapters will be identical to those in "([^"]*)"$/ do |xml_document_file|
124
+ chapters_in_database = Chapter.all
125
+ if chapters_in_database.count > 0
126
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
127
+
128
+ # Ensure that all chapters in the xml document have been recorded
129
+ xml_document.xpath("//book").each do |book_element|
130
+ book_id = book_element.xpath("id").text
131
+ xml_document.xpath("//book[id[text()='#{book_id}']]/chapters/chapter").each do |chapter_element|
132
+ chapter_id = chapter_element.xpath("id")[0].text
133
+ chapter_title = chapter_element.xpath("title")[0].text
134
+ chapter_introduction = chapter_element.xpath("introduction")[0].text
135
+ chapter = Chapter.find(chapter_id)
136
+
137
+ if chapter == nil
138
+ fail "Chapters with id #{chapter_id} is missing"
139
+ else
140
+ if chapter_title != chapter.title
141
+ fail "Chapter title in database doesn't match chapter title in xml for chapter with id #{chapter_id}, XML: #{chapter_title}, Database: #{chapter.title}"
142
+ end
143
+ if chapter_introduction != chapter.introduction
144
+ fail "Chapter introduction in database doesn't match chapter introduction in xml for chapter with id #{chapter_id}, XML: #{chapter_introduction}, Database: #{chapter.introduction}"
145
+ end
146
+ if book_id != chapter.book_id.to_s
147
+ fail "Chapter book_id in database doesn't match chapter book_id in xml for chapter with id #{chapter_id}, XML: #{book_id}, Database: #{chapter.book_id}"
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+
154
+ # Ensure there are not extra chapters
155
+ chapters_in_xml = xml_document.xpath("//chapter")
156
+ if chapters_in_database.count != chapters_in_xml.count
157
+ fail "There number of chapters in the database (#{chapters_in_database.count}) doesn't match the number of chapters in the xml document (#{chapters_in_xml.count})"
158
+ end
159
+
160
+ else
161
+ fail "no chapters recorded"
162
+ end
163
+ end
164
+
165
+ When /^the database will contain identical pages for the chapters as those in "([^"]*)"$/ do |xml_document_file|
166
+ chapters_in_database = Chapter.all
167
+ if chapters_in_database.count > 0
168
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
169
+
170
+ # Ensure that all chapters in the xml document have been recorded
171
+ xml_document.xpath("//book").each do |book_element|
172
+ book_id = book_element.xpath("id").text
173
+ xml_document.xpath("//book[id[text()='#{book_id}']]/chapters/chapter").each do |chapter_element|
174
+ chapter_id = chapter_element.xpath("id")[0].text
175
+ pages = Page.where(:chapter_id => chapter_id)
176
+ if (pages.count > 0)
177
+ xml_document.xpath("//chapter[id[text()='#{chapter_id}']]/pages/page").each do |page_element|
178
+ page_id = page_element.xpath("id")[0].text
179
+ page_content = page_element.xpath("content")[0].text
180
+ page_number = page_element.xpath("number")[0].text
181
+ page = Page.find(page_id)
182
+
183
+ if page == nil
184
+ fail "Page with id #{page_id} is missing"
185
+ else
186
+ if page_content != page.content
187
+ file "Page content in database doesn't match page content in xml for page with id #{page_id}, XML: #{page_content}, Database: #{page.content}"
188
+ end
189
+
190
+ if page_number != page.number.to_s
191
+ fail "Page number in database doesn't match page number in xml for page with id #{page_id}, XML: #{page_number}, Database: #{page.number}"
192
+ end
193
+ end
194
+ end
195
+ else
196
+ fail "no pages recorded for chapter with id #{chapter_id}"
197
+ end
198
+ end
199
+ end
200
+
201
+
202
+ # Ensure there are not extra pages
203
+ pages_in_xml = xml_document.xpath("//page")
204
+ pages_in_database = Page.all
205
+ if pages_in_database.count != pages_in_xml.count
206
+ fail "There number of pages in the database (#{pages_in_database.count}) doesn't match the number of pages in the xml document (#{pages_in_xml.count})"
207
+ end
208
+
209
+ else
210
+ fail "no chapters recorded"
211
+ end
212
+ end
213
+
214
+ Given /^I have a fresh set of books$/ do
215
+ StepHelper.load_fixtures File.join(Rails.root, 'features', 'support', 'fixtures', 'fresh')
216
+ end
217
+
218
+ Given /^I have a fresh set of books without the one to one record$/ do
219
+ StepHelper.load_fixtures File.join(Rails.root, 'features', 'support', 'fixtures', 'without_one_to_one')
220
+ end
221
+
222
+ Given /^I have a fresh set of books without any chapters$/ do
223
+ StepHelper.load_fixtures File.join(Rails.root, 'features', 'support', 'fixtures', 'without_chapters')
224
+ end
@@ -0,0 +1,158 @@
1
+ require "active_record/fixtures"
2
+ require_relative "step_helper"
3
+
4
+ Then /^the books with the same identifying features as those in "([^"]*)" will be updated$/ do |xml_document_file|
5
+ books_in_database = Book.all
6
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
7
+
8
+ # Ensure that all books in the xml document have been updated
9
+ book_elements = xml_document.xpath("//book")
10
+ book_elements.each do |book_element|
11
+ book_id = book_element.xpath("//book/id")[0].text
12
+ book_name = book_element.xpath("//book/name")[0].text
13
+ begin
14
+ book = Book.find(book_id)
15
+ rescue
16
+ end
17
+
18
+ if book != nil
19
+ if book_name != book.name
20
+ fail "Book name in database doesn't match book name in xml for book with id #{book_id}, XML: #{book_name}, Database: #{book.name}"
21
+ end
22
+ end
23
+ end
24
+
25
+ # Check the records that don't exist in the XML Document haven't been changed
26
+ @original_books.each do |original_book|
27
+ xml_book = xml_document.xpath("//book[id[text()='#{original_book.id}']]")
28
+ if xml_book.count == 0
29
+ book_in_database = Book.find(original_book.id)
30
+ if book_in_database.name != original_book.name
31
+ fail "Book name in database doesn't match the original book name for book with id #{original_book.id}, Original: #{original_book.name}, Database: #{book_in_database.name}"
32
+ end
33
+ end
34
+ end
35
+
36
+ # Ensure there are no extra books
37
+ if books_in_database.count != @original_books.count
38
+ fail "There number of books in the database (#{books_in_database.count}) doesn't match the original number of books (#{@original_books.count})"
39
+ end
40
+ end
41
+
42
+ Then /^the chapters with the same identifying features as those in "([^"]*)" will be updated$/ do |xml_document_file|
43
+ chapters_in_database = Chapter.all
44
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
45
+
46
+ # Ensure that all chapters in the xml document have been updated
47
+ xml_document.xpath("//book").each do |book_element|
48
+ book_id = book_element.xpath("id").text
49
+ xml_document.xpath("//book[id[text()='#{book_id}']]/chapters/chapter").each do |chapter_element|
50
+ chapter_id = chapter_element.xpath("id")[0].text
51
+ chapter_title = chapter_element.xpath("title")[0].text
52
+ chapter_introduction = chapter_element.xpath("introduction")[0].text
53
+ begin
54
+ chapter = Chapter.find(chapter_id)
55
+ rescue
56
+ end
57
+
58
+ if chapter != nil
59
+ if chapter_title != chapter.title
60
+ fail "Chapter title in database doesn't match chapter title in xml for chapter with id #{chapter_id}, XML: #{chapter_title}, Database: #{chapter.title}"
61
+ end
62
+ if chapter_introduction != chapter.introduction
63
+ fail "Chapter introduction in database doesn't match chapter introduction in xml for chapter with id #{chapter_id}, XML: #{chapter_introduction}, Database: #{chapter.introduction}"
64
+ end
65
+ if book_id != chapter.book_id.to_s
66
+ fail "Chapter book_id in database doesn't match chapter book_id in xml for chapter with id #{chapter_id}, XML: #{book_id}, Database: #{chapter.book_id}"
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ # Check the records that don't exist in the XML Document haven't been changed
73
+ @original_chapters.each do |original_chapter|
74
+ xml_chapter = xml_document.xpath("//chapter[id[text()='#{original_chapter.id}']]")
75
+ if xml_chapter.count == 0
76
+ chapter_in_database = Chapter.find(original_chapter.id)
77
+ if chapter_in_database.title != original_chapter.title
78
+ fail "Chapter title in database doesn't match the original chapter title for chapter with id #{original_chapter.id}, Original: #{original_chapter.title}, Database: #{chapter_in_database.title}"
79
+ end
80
+ if chapter_in_database.introduction != original_chapter.introduction
81
+ fail "Chapter introduction in database doesn't match the original chapter introduction for chapter with id #{original_chapter.id}, Original: #{original_chapter.introduction}, Database: #{chapter_in_database.introduction}"
82
+ end
83
+ if chapter_in_database.book_id != original_chapter.book_id
84
+ fail "Chapter book_id in database doesn't match the original chapter book_id for chapter with id #{original_chapter.id}, Original: #{original_chapter.book_id}, Database: #{chapter_in_database.book_id}"
85
+ end
86
+ end
87
+ end
88
+
89
+ # Ensure there are no extra chapters
90
+ if chapters_in_database.count != @original_chapters.count
91
+ fail "The number of chapters in the database (#{chapters_in_database.count}) doesn't match the original number of chapters (#{@original_chapters.count})"
92
+ end
93
+ end
94
+
95
+ Then /^the pages with the same identifying features as those in "([^"]*)" will be updated$/ do |xml_document_file|
96
+ xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
97
+
98
+ # Ensure that all chapters in the xml document have been updated
99
+ xml_document.xpath("//book").each do |book_element|
100
+ book_id = book_element.xpath("id").text
101
+ xml_document.xpath("//book[id[text()='#{book_id}']]/chapters/chapter").each do |chapter_element|
102
+ chapter_id = chapter_element.xpath("id")[0].text
103
+ begin
104
+ pages = Page.where(:chapter_id => chapter_id)
105
+ rescue
106
+ end
107
+
108
+ if pages.count > 0
109
+ xml_document.xpath("//chapter[id[text()='#{chapter_id}']]/pages/page").each do |page_element|
110
+ page_id = page_element.xpath("id")[0].text
111
+ page_content = page_element.xpath("content")[0].text
112
+ page_number = page_element.xpath("number")[0].text
113
+ begin
114
+ page = Page.find(page_id)
115
+ rescue
116
+ end
117
+
118
+ if page != nil
119
+ if page_content != page.content
120
+ file "Page content in database doesn't match page content in xml for page with id #{page_id}, XML: #{page_content}, Database: #{page.content}"
121
+ end
122
+
123
+ if page_number != page.number.to_s
124
+ fail "Page number in database doesn't match page number in xml for page with id #{page_id}, XML: #{page_number}, Database: #{page.number}"
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # Check the records that don't exist in the XML Document haven't been changed
133
+ @original_pages.each do |original_page|
134
+ xml_page = xml_document.xpath("//page[id[text()='#{original_page.id}']]")
135
+ if xml_page.count == 0
136
+ page_in_database = Page.find(original_page.id)
137
+ if page_in_database.content != original_page.content
138
+ fail "Page content in database doesn't match the original page content for page with id #{original_page.id}, Original: #{original_chapter.content}, Database: #{chapter_in_database.content}"
139
+ end
140
+ if page_in_database.number != original_page.number
141
+ fail "Page number in database doesn't match the original page number for page with id #{original_page.id}, Original: #{original_page.number}, Database: #{page_in_database.number}"
142
+ end
143
+ if page_in_database.chapter_id != original_page.chapter_id
144
+ fail "Page chapter_id in database doesn't match the original page chapter_id for page with id #{original_page.id}, Original: #{original_page.chapter_id}, Database: #{page_in_database.chapter_id}"
145
+ end
146
+ end
147
+ end
148
+
149
+ # Ensure there are no extra pages
150
+ pages_in_database = Page.all
151
+ if pages_in_database.count != @original_pages.count
152
+ fail "There number of pages in the database (#{pages_in_database.count}) doesn't match the original number of pages (#{@original_pages.count})"
153
+ end
154
+ end
155
+ Given /^I have no matching books$/ do
156
+ StepHelper.load_fixtures File.join(Rails.root, 'features', 'support', 'fixtures', 'no_matching_records')
157
+ end
158
+
@@ -0,0 +1,211 @@
1
+ # TL;DR: YOU SHOULD DELETE THIS FILE
2
+ #
3
+ # This file was generated by Cucumber-Rails and is only here to get you a head start
4
+ # These step definitions are thin wrappers around the Capybara/Webrat API that lets you
5
+ # visit pages, interact with widgets and make assertions about page content.
6
+ #
7
+ # If you use these step definitions as basis for your features you will quickly end up
8
+ # with features that are:
9
+ #
10
+ # * Hard to maintain
11
+ # * Verbose to read
12
+ #
13
+ # A much better approach is to write your own higher level step definitions, following
14
+ # the advice in the following blog posts:
15
+ #
16
+ # * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
17
+ # * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
18
+ # * http://elabs.se/blog/15-you-re-cuking-it-wrong
19
+ #
20
+
21
+
22
+ require 'uri'
23
+ require 'cgi'
24
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
25
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
26
+
27
+ module WithinHelpers
28
+ def with_scope(locator)
29
+ locator ? within(*selector_for(locator)) { yield } : yield
30
+ end
31
+ end
32
+ World(WithinHelpers)
33
+
34
+ # Single-line step scoper
35
+ When /^(.*) within (.*[^:])$/ do |step, parent|
36
+ with_scope(parent) { When step }
37
+ end
38
+
39
+ # Multi-line step scoper
40
+ When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string|
41
+ with_scope(parent) { When "#{step}:", table_or_string }
42
+ end
43
+
44
+ Given /^(?:|I )am on (.+)$/ do |page_name|
45
+ visit path_to(page_name)
46
+ end
47
+
48
+ When /^(?:|I )go to (.+)$/ do |page_name|
49
+ visit path_to(page_name)
50
+ end
51
+
52
+ When /^(?:|I )press "([^"]*)"$/ do |button|
53
+ click_button(button)
54
+ end
55
+
56
+ When /^(?:|I )follow "([^"]*)"$/ do |link|
57
+ click_link(link)
58
+ end
59
+
60
+ When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
61
+ fill_in(field, :with => value)
62
+ end
63
+
64
+ When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
65
+ fill_in(field, :with => value)
66
+ end
67
+
68
+ # Use this to fill in an entire form with data from a table. Example:
69
+ #
70
+ # When I fill in the following:
71
+ # | Account Number | 5002 |
72
+ # | Expiry date | 2009-11-01 |
73
+ # | Note | Nice guy |
74
+ # | Wants Email? | |
75
+ #
76
+ # TODO: Add support for checkbox, select og option
77
+ # based on naming conventions.
78
+ #
79
+ When /^(?:|I )fill in the following:$/ do |fields|
80
+ fields.rows_hash.each do |name, value|
81
+ When %{I fill in "#{name}" with "#{value}"}
82
+ end
83
+ end
84
+
85
+ When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
86
+ select(value, :from => field)
87
+ end
88
+
89
+ When /^(?:|I )check "([^"]*)"$/ do |field|
90
+ check(field)
91
+ end
92
+
93
+ When /^(?:|I )uncheck "([^"]*)"$/ do |field|
94
+ uncheck(field)
95
+ end
96
+
97
+ When /^(?:|I )choose "([^"]*)"$/ do |field|
98
+ choose(field)
99
+ end
100
+
101
+ When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
102
+ attach_file(field, File.expand_path(path))
103
+ end
104
+
105
+ Then /^(?:|I )should see "([^"]*)"$/ do |text|
106
+ if page.respond_to? :should
107
+ page.should have_content(text)
108
+ else
109
+ assert page.has_content?(text)
110
+ end
111
+ end
112
+
113
+ Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
114
+ regexp = Regexp.new(regexp)
115
+
116
+ if page.respond_to? :should
117
+ page.should have_xpath('//*', :text => regexp)
118
+ else
119
+ assert page.has_xpath?('//*', :text => regexp)
120
+ end
121
+ end
122
+
123
+ Then /^(?:|I )should not see "([^"]*)"$/ do |text|
124
+ if page.respond_to? :should
125
+ page.should have_no_content(text)
126
+ else
127
+ assert page.has_no_content?(text)
128
+ end
129
+ end
130
+
131
+ Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
132
+ regexp = Regexp.new(regexp)
133
+
134
+ if page.respond_to? :should
135
+ page.should have_no_xpath('//*', :text => regexp)
136
+ else
137
+ assert page.has_no_xpath?('//*', :text => regexp)
138
+ end
139
+ end
140
+
141
+ Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
142
+ with_scope(parent) do
143
+ field = find_field(field)
144
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
145
+ if field_value.respond_to? :should
146
+ field_value.should =~ /#{value}/
147
+ else
148
+ assert_match(/#{value}/, field_value)
149
+ end
150
+ end
151
+ end
152
+
153
+ Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
154
+ with_scope(parent) do
155
+ field = find_field(field)
156
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
157
+ if field_value.respond_to? :should_not
158
+ field_value.should_not =~ /#{value}/
159
+ else
160
+ assert_no_match(/#{value}/, field_value)
161
+ end
162
+ end
163
+ end
164
+
165
+ Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
166
+ with_scope(parent) do
167
+ field_checked = find_field(label)['checked']
168
+ if field_checked.respond_to? :should
169
+ field_checked.should be_true
170
+ else
171
+ assert field_checked
172
+ end
173
+ end
174
+ end
175
+
176
+ Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
177
+ with_scope(parent) do
178
+ field_checked = find_field(label)['checked']
179
+ if field_checked.respond_to? :should
180
+ field_checked.should be_false
181
+ else
182
+ assert !field_checked
183
+ end
184
+ end
185
+ end
186
+
187
+ Then /^(?:|I )should be on (.+)$/ do |page_name|
188
+ current_path = URI.parse(current_url).path
189
+ if current_path.respond_to? :should
190
+ current_path.should == path_to(page_name)
191
+ else
192
+ assert_equal path_to(page_name), current_path
193
+ end
194
+ end
195
+
196
+ Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
197
+ query = URI.parse(current_url).query
198
+ actual_params = query ? CGI.parse(query) : {}
199
+ expected_params = {}
200
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
201
+
202
+ if actual_params.respond_to? :should
203
+ actual_params.should == expected_params
204
+ else
205
+ assert_equal expected_params, actual_params
206
+ end
207
+ end
208
+
209
+ Then /^show me the page$/ do
210
+ save_and_open_page
211
+ end