data_active 0.0.1

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 (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