active_cached_resource 0.0.1.pre

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 (340) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +22 -0
  4. data/.standard.yml +2 -0
  5. data/CHANGELOG.md +5 -0
  6. data/README.md +45 -0
  7. data/Rakefile +21 -0
  8. data/example/consumer/.dockerignore +41 -0
  9. data/example/consumer/.gitattributes +9 -0
  10. data/example/consumer/.gitignore +36 -0
  11. data/example/consumer/.kamal/hooks/docker-setup.sample +3 -0
  12. data/example/consumer/.kamal/hooks/post-deploy.sample +14 -0
  13. data/example/consumer/.kamal/hooks/post-proxy-reboot.sample +3 -0
  14. data/example/consumer/.kamal/hooks/pre-build.sample +51 -0
  15. data/example/consumer/.kamal/hooks/pre-connect.sample +47 -0
  16. data/example/consumer/.kamal/hooks/pre-deploy.sample +109 -0
  17. data/example/consumer/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  18. data/example/consumer/.kamal/secrets +17 -0
  19. data/example/consumer/Dockerfile +65 -0
  20. data/example/consumer/Gemfile +17 -0
  21. data/example/consumer/Rakefile +6 -0
  22. data/example/consumer/app/controllers/application_controller.rb +2 -0
  23. data/example/consumer/app/controllers/concerns/.keep +0 -0
  24. data/example/consumer/app/jobs/application_job.rb +7 -0
  25. data/example/consumer/app/mailers/application_mailer.rb +4 -0
  26. data/example/consumer/app/models/application_record.rb +3 -0
  27. data/example/consumer/app/models/concerns/.keep +0 -0
  28. data/example/consumer/app/models/person.rb +9 -0
  29. data/example/consumer/app/views/layouts/mailer.html.erb +13 -0
  30. data/example/consumer/app/views/layouts/mailer.text.erb +1 -0
  31. data/example/consumer/bin/brakeman +7 -0
  32. data/example/consumer/bin/bundle +109 -0
  33. data/example/consumer/bin/dev +2 -0
  34. data/example/consumer/bin/docker-entrypoint +14 -0
  35. data/example/consumer/bin/jobs +6 -0
  36. data/example/consumer/bin/kamal +27 -0
  37. data/example/consumer/bin/rails +4 -0
  38. data/example/consumer/bin/rake +4 -0
  39. data/example/consumer/bin/rubocop +8 -0
  40. data/example/consumer/bin/setup +34 -0
  41. data/example/consumer/bin/thrust +5 -0
  42. data/example/consumer/config/application.rb +20 -0
  43. data/example/consumer/config/boot.rb +3 -0
  44. data/example/consumer/config/cache.yml +16 -0
  45. data/example/consumer/config/credentials.yml.enc +1 -0
  46. data/example/consumer/config/database.yml +14 -0
  47. data/example/consumer/config/deploy.yml +116 -0
  48. data/example/consumer/config/environment.rb +5 -0
  49. data/example/consumer/config/environments/development.rb +64 -0
  50. data/example/consumer/config/environments/production.rb +85 -0
  51. data/example/consumer/config/environments/test.rb +50 -0
  52. data/example/consumer/config/initializers/cors.rb +16 -0
  53. data/example/consumer/config/initializers/filter_parameter_logging.rb +8 -0
  54. data/example/consumer/config/initializers/inflections.rb +16 -0
  55. data/example/consumer/config/locales/en.yml +31 -0
  56. data/example/consumer/config/puma.rb +41 -0
  57. data/example/consumer/config/queue.yml +18 -0
  58. data/example/consumer/config/recurring.yml +10 -0
  59. data/example/consumer/config/routes.rb +10 -0
  60. data/example/consumer/config.ru +6 -0
  61. data/example/consumer/db/cache_schema.rb +14 -0
  62. data/example/consumer/db/queue_schema.rb +129 -0
  63. data/example/consumer/db/seeds.rb +0 -0
  64. data/example/consumer/lib/tasks/.keep +0 -0
  65. data/example/consumer/log/.keep +0 -0
  66. data/example/consumer/public/robots.txt +1 -0
  67. data/example/consumer/script/.keep +0 -0
  68. data/example/consumer/storage/.keep +0 -0
  69. data/example/consumer/tmp/.keep +0 -0
  70. data/example/consumer/tmp/cache/.keep +0 -0
  71. data/example/consumer/tmp/pids/.keep +0 -0
  72. data/example/consumer/tmp/storage/.keep +0 -0
  73. data/example/consumer/vendor/.keep +0 -0
  74. data/example/provider/.dockerignore +41 -0
  75. data/example/provider/.gitattributes +9 -0
  76. data/example/provider/.gitignore +32 -0
  77. data/example/provider/.kamal/hooks/docker-setup.sample +3 -0
  78. data/example/provider/.kamal/hooks/post-deploy.sample +14 -0
  79. data/example/provider/.kamal/hooks/post-proxy-reboot.sample +3 -0
  80. data/example/provider/.kamal/hooks/pre-build.sample +51 -0
  81. data/example/provider/.kamal/hooks/pre-connect.sample +47 -0
  82. data/example/provider/.kamal/hooks/pre-deploy.sample +109 -0
  83. data/example/provider/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  84. data/example/provider/.kamal/secrets +17 -0
  85. data/example/provider/Dockerfile +65 -0
  86. data/example/provider/Gemfile +14 -0
  87. data/example/provider/Rakefile +6 -0
  88. data/example/provider/app/controllers/application_controller.rb +2 -0
  89. data/example/provider/app/controllers/concerns/.keep +0 -0
  90. data/example/provider/app/controllers/people_controller.rb +68 -0
  91. data/example/provider/app/jobs/application_job.rb +7 -0
  92. data/example/provider/app/mailers/application_mailer.rb +4 -0
  93. data/example/provider/app/models/address.rb +3 -0
  94. data/example/provider/app/models/application_record.rb +3 -0
  95. data/example/provider/app/models/company.rb +3 -0
  96. data/example/provider/app/models/concerns/.keep +0 -0
  97. data/example/provider/app/models/person.rb +6 -0
  98. data/example/provider/app/views/layouts/mailer.html.erb +13 -0
  99. data/example/provider/app/views/layouts/mailer.text.erb +1 -0
  100. data/example/provider/bin/brakeman +7 -0
  101. data/example/provider/bin/bundle +109 -0
  102. data/example/provider/bin/dev +2 -0
  103. data/example/provider/bin/docker-entrypoint +14 -0
  104. data/example/provider/bin/jobs +6 -0
  105. data/example/provider/bin/kamal +27 -0
  106. data/example/provider/bin/rails +4 -0
  107. data/example/provider/bin/rake +4 -0
  108. data/example/provider/bin/rubocop +8 -0
  109. data/example/provider/bin/setup +34 -0
  110. data/example/provider/bin/thrust +5 -0
  111. data/example/provider/config/application.rb +44 -0
  112. data/example/provider/config/boot.rb +3 -0
  113. data/example/provider/config/cache.yml +16 -0
  114. data/example/provider/config/credentials.yml.enc +1 -0
  115. data/example/provider/config/database.yml +20 -0
  116. data/example/provider/config/deploy.yml +116 -0
  117. data/example/provider/config/environment.rb +5 -0
  118. data/example/provider/config/environments/development.rb +64 -0
  119. data/example/provider/config/environments/production.rb +85 -0
  120. data/example/provider/config/environments/test.rb +50 -0
  121. data/example/provider/config/initializers/cors.rb +16 -0
  122. data/example/provider/config/initializers/filter_parameter_logging.rb +8 -0
  123. data/example/provider/config/initializers/inflections.rb +16 -0
  124. data/example/provider/config/locales/en.yml +31 -0
  125. data/example/provider/config/puma.rb +41 -0
  126. data/example/provider/config/queue.yml +18 -0
  127. data/example/provider/config/recurring.yml +10 -0
  128. data/example/provider/config/routes.rb +4 -0
  129. data/example/provider/config.ru +6 -0
  130. data/example/provider/db/cache_schema.rb +14 -0
  131. data/example/provider/db/migrate/20241202183937_create_people.rb +11 -0
  132. data/example/provider/db/migrate/20241202183955_create_addresses.rb +13 -0
  133. data/example/provider/db/migrate/20241202184017_create_companies.rb +14 -0
  134. data/example/provider/db/queue_schema.rb +129 -0
  135. data/example/provider/db/schema.rb +47 -0
  136. data/example/provider/db/seeds.rb +18 -0
  137. data/example/provider/lib/tasks/.keep +0 -0
  138. data/example/provider/log/.keep +0 -0
  139. data/example/provider/public/robots.txt +1 -0
  140. data/example/provider/script/.keep +0 -0
  141. data/example/provider/storage/.keep +0 -0
  142. data/example/provider/tmp/.keep +0 -0
  143. data/example/provider/tmp/pids/.keep +0 -0
  144. data/example/provider/tmp/storage/.keep +0 -0
  145. data/example/provider/vendor/.keep +0 -0
  146. data/lib/active_cached_resource/caching.rb +176 -0
  147. data/lib/active_cached_resource/caching_strategies/active_support_cache.rb +31 -0
  148. data/lib/active_cached_resource/caching_strategies/base.rb +114 -0
  149. data/lib/active_cached_resource/caching_strategies/sql_cache.rb +32 -0
  150. data/lib/active_cached_resource/configuration.rb +50 -0
  151. data/lib/active_cached_resource/logger.rb +22 -0
  152. data/lib/active_cached_resource/model.rb +33 -0
  153. data/lib/active_cached_resource/version.rb +12 -0
  154. data/lib/active_cached_resource.rb +64 -0
  155. data/lib/activeresource/.gitignore +15 -0
  156. data/lib/activeresource/README.md +283 -0
  157. data/lib/activeresource/examples/performance.rb +72 -0
  158. data/lib/activeresource/lib/active_resource/active_job_serializer.rb +26 -0
  159. data/lib/activeresource/lib/active_resource/associations/builder/association.rb +32 -0
  160. data/lib/activeresource/lib/active_resource/associations/builder/belongs_to.rb +16 -0
  161. data/lib/activeresource/lib/active_resource/associations/builder/has_many.rb +14 -0
  162. data/lib/activeresource/lib/active_resource/associations/builder/has_one.rb +14 -0
  163. data/lib/activeresource/lib/active_resource/associations.rb +175 -0
  164. data/lib/activeresource/lib/active_resource/base.rb +1741 -0
  165. data/lib/activeresource/lib/active_resource/callbacks.rb +22 -0
  166. data/lib/activeresource/lib/active_resource/collection.rb +214 -0
  167. data/lib/activeresource/lib/active_resource/connection.rb +298 -0
  168. data/lib/activeresource/lib/active_resource/custom_methods.rb +129 -0
  169. data/lib/activeresource/lib/active_resource/exceptions.rb +98 -0
  170. data/lib/activeresource/lib/active_resource/formats/json_format.rb +28 -0
  171. data/lib/activeresource/lib/active_resource/formats/xml_format.rb +27 -0
  172. data/lib/activeresource/lib/active_resource/formats.rb +24 -0
  173. data/lib/activeresource/lib/active_resource/http_mock.rb +386 -0
  174. data/lib/activeresource/lib/active_resource/inheriting_hash.rb +34 -0
  175. data/lib/activeresource/lib/active_resource/log_subscriber.rb +26 -0
  176. data/lib/activeresource/lib/active_resource/railtie.rb +31 -0
  177. data/lib/activeresource/lib/active_resource/reflection.rb +78 -0
  178. data/lib/activeresource/lib/active_resource/schema.rb +60 -0
  179. data/lib/activeresource/lib/active_resource/singleton.rb +111 -0
  180. data/lib/activeresource/lib/active_resource/threadsafe_attributes.rb +65 -0
  181. data/lib/activeresource/lib/active_resource/validations.rb +176 -0
  182. data/lib/activeresource/lib/active_resource.rb +49 -0
  183. data/lib/activeresource/lib/activeresource.rb +3 -0
  184. data/lib/activeresource/test/abstract_unit.rb +153 -0
  185. data/lib/activeresource/test/cases/active_job_serializer_test.rb +53 -0
  186. data/lib/activeresource/test/cases/association_test.rb +104 -0
  187. data/lib/activeresource/test/cases/associations/builder/belongs_to_test.rb +42 -0
  188. data/lib/activeresource/test/cases/associations/builder/has_many_test.rb +28 -0
  189. data/lib/activeresource/test/cases/associations/builder/has_one_test.rb +28 -0
  190. data/lib/activeresource/test/cases/authorization_test.rb +276 -0
  191. data/lib/activeresource/test/cases/base/custom_methods_test.rb +155 -0
  192. data/lib/activeresource/test/cases/base/equality_test.rb +53 -0
  193. data/lib/activeresource/test/cases/base/load_test.rb +249 -0
  194. data/lib/activeresource/test/cases/base/schema_test.rb +428 -0
  195. data/lib/activeresource/test/cases/base_errors_test.rb +129 -0
  196. data/lib/activeresource/test/cases/base_test.rb +1622 -0
  197. data/lib/activeresource/test/cases/callbacks_test.rb +155 -0
  198. data/lib/activeresource/test/cases/collection_test.rb +172 -0
  199. data/lib/activeresource/test/cases/connection_test.rb +357 -0
  200. data/lib/activeresource/test/cases/finder_test.rb +217 -0
  201. data/lib/activeresource/test/cases/format_test.rb +137 -0
  202. data/lib/activeresource/test/cases/http_mock_test.rb +213 -0
  203. data/lib/activeresource/test/cases/inheritence_test.rb +19 -0
  204. data/lib/activeresource/test/cases/inheriting_hash_test.rb +25 -0
  205. data/lib/activeresource/test/cases/log_subscriber_test.rb +63 -0
  206. data/lib/activeresource/test/cases/reflection_test.rb +65 -0
  207. data/lib/activeresource/test/cases/validations_test.rb +78 -0
  208. data/lib/activeresource/test/fixtures/address.rb +20 -0
  209. data/lib/activeresource/test/fixtures/beast.rb +16 -0
  210. data/lib/activeresource/test/fixtures/comment.rb +5 -0
  211. data/lib/activeresource/test/fixtures/customer.rb +5 -0
  212. data/lib/activeresource/test/fixtures/inventory.rb +14 -0
  213. data/lib/activeresource/test/fixtures/person.rb +15 -0
  214. data/lib/activeresource/test/fixtures/pet.rb +6 -0
  215. data/lib/activeresource/test/fixtures/post.rb +5 -0
  216. data/lib/activeresource/test/fixtures/product.rb +11 -0
  217. data/lib/activeresource/test/fixtures/project.rb +19 -0
  218. data/lib/activeresource/test/fixtures/proxy.rb +6 -0
  219. data/lib/activeresource/test/fixtures/sound.rb +11 -0
  220. data/lib/activeresource/test/fixtures/street_address.rb +6 -0
  221. data/lib/activeresource/test/fixtures/subscription_plan.rb +7 -0
  222. data/lib/activeresource/test/fixtures/weather.rb +21 -0
  223. data/lib/activeresource/test/setter_trap.rb +28 -0
  224. data/lib/activeresource/test/singleton_test.rb +138 -0
  225. data/lib/activeresource/test/threadsafe_attributes_test.rb +91 -0
  226. data/lib/generators/active_cached_resource/install_generator.rb +31 -0
  227. data/lib/generators/active_cached_resource/templates/migration.erb +16 -0
  228. data/sorbet/config +4 -0
  229. data/sorbet/rbi/annotations/.gitattributes +1 -0
  230. data/sorbet/rbi/annotations/activemodel.rbi +89 -0
  231. data/sorbet/rbi/annotations/activesupport.rbi +457 -0
  232. data/sorbet/rbi/annotations/minitest.rbi +119 -0
  233. data/sorbet/rbi/annotations/rainbow.rbi +269 -0
  234. data/sorbet/rbi/dsl/.gitattributes +1 -0
  235. data/sorbet/rbi/dsl/active_support/callbacks.rbi +21 -0
  236. data/sorbet/rbi/gems/.gitattributes +1 -0
  237. data/sorbet/rbi/gems/actioncable@8.0.0.rbi +252 -0
  238. data/sorbet/rbi/gems/actionmailbox@8.0.0.rbi +9 -0
  239. data/sorbet/rbi/gems/actionmailer@8.0.0.rbi +9 -0
  240. data/sorbet/rbi/gems/actionpack@8.0.0.rbi +20909 -0
  241. data/sorbet/rbi/gems/actiontext@8.0.0.rbi +9 -0
  242. data/sorbet/rbi/gems/actionview@8.0.0.rbi +16207 -0
  243. data/sorbet/rbi/gems/activejob@8.0.0.rbi +9 -0
  244. data/sorbet/rbi/gems/activemodel-serializers-xml@1.0.3.rbi +166 -0
  245. data/sorbet/rbi/gems/activemodel@8.0.0.rbi +6857 -0
  246. data/sorbet/rbi/gems/activerecord@8.0.0.rbi +42896 -0
  247. data/sorbet/rbi/gems/activeresource@6.1.4.rbi +3944 -0
  248. data/sorbet/rbi/gems/activestorage@8.0.0.rbi +9 -0
  249. data/sorbet/rbi/gems/activesupport@8.0.0.rbi +21251 -0
  250. data/sorbet/rbi/gems/ast@2.4.2.rbi +585 -0
  251. data/sorbet/rbi/gems/base64@0.2.0.rbi +509 -0
  252. data/sorbet/rbi/gems/benchmark@0.4.0.rbi +618 -0
  253. data/sorbet/rbi/gems/bigdecimal@3.1.8.rbi +78 -0
  254. data/sorbet/rbi/gems/builder@3.3.0.rbi +9 -0
  255. data/sorbet/rbi/gems/bump@0.10.0.rbi +169 -0
  256. data/sorbet/rbi/gems/byebug@11.1.3.rbi +3607 -0
  257. data/sorbet/rbi/gems/coderay@1.1.3.rbi +3427 -0
  258. data/sorbet/rbi/gems/concurrent-ruby@1.3.4.rbi +11645 -0
  259. data/sorbet/rbi/gems/connection_pool@2.4.1.rbi +9 -0
  260. data/sorbet/rbi/gems/crass@1.0.6.rbi +623 -0
  261. data/sorbet/rbi/gems/date@3.4.0.rbi +75 -0
  262. data/sorbet/rbi/gems/diff-lcs@1.5.1.rbi +1131 -0
  263. data/sorbet/rbi/gems/docile@1.4.1.rbi +377 -0
  264. data/sorbet/rbi/gems/drb@2.2.1.rbi +1347 -0
  265. data/sorbet/rbi/gems/erubi@1.13.0.rbi +150 -0
  266. data/sorbet/rbi/gems/globalid@1.2.1.rbi +9 -0
  267. data/sorbet/rbi/gems/i18n@1.14.6.rbi +2359 -0
  268. data/sorbet/rbi/gems/io-console@0.7.2.rbi +9 -0
  269. data/sorbet/rbi/gems/json@2.8.2.rbi +1901 -0
  270. data/sorbet/rbi/gems/language_server-protocol@3.17.0.3.rbi +14238 -0
  271. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +240 -0
  272. data/sorbet/rbi/gems/logger@1.6.1.rbi +920 -0
  273. data/sorbet/rbi/gems/loofah@2.23.1.rbi +1081 -0
  274. data/sorbet/rbi/gems/mail@2.8.1.rbi +9 -0
  275. data/sorbet/rbi/gems/marcel@1.0.4.rbi +9 -0
  276. data/sorbet/rbi/gems/method_source@1.1.0.rbi +304 -0
  277. data/sorbet/rbi/gems/mini_mime@1.1.5.rbi +9 -0
  278. data/sorbet/rbi/gems/minitest@5.25.2.rbi +1547 -0
  279. data/sorbet/rbi/gems/net-imap@0.5.1.rbi +9 -0
  280. data/sorbet/rbi/gems/net-pop@0.1.2.rbi +9 -0
  281. data/sorbet/rbi/gems/net-protocol@0.2.2.rbi +292 -0
  282. data/sorbet/rbi/gems/net-smtp@0.5.0.rbi +9 -0
  283. data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
  284. data/sorbet/rbi/gems/nio4r@2.7.4.rbi +9 -0
  285. data/sorbet/rbi/gems/nokogiri@1.16.7.rbi +7311 -0
  286. data/sorbet/rbi/gems/parallel@1.26.3.rbi +291 -0
  287. data/sorbet/rbi/gems/parser@3.3.6.0.rbi +5519 -0
  288. data/sorbet/rbi/gems/prism@1.2.0.rbi +39085 -0
  289. data/sorbet/rbi/gems/pry-byebug@3.10.1.rbi +1151 -0
  290. data/sorbet/rbi/gems/pry@0.14.2.rbi +10076 -0
  291. data/sorbet/rbi/gems/psych@5.2.0.rbi +1785 -0
  292. data/sorbet/rbi/gems/racc@1.8.1.rbi +162 -0
  293. data/sorbet/rbi/gems/rack-session@2.0.0.rbi +727 -0
  294. data/sorbet/rbi/gems/rack-test@2.1.0.rbi +747 -0
  295. data/sorbet/rbi/gems/rack@3.1.8.rbi +4905 -0
  296. data/sorbet/rbi/gems/rackup@2.2.1.rbi +230 -0
  297. data/sorbet/rbi/gems/rails-dom-testing@2.2.0.rbi +758 -0
  298. data/sorbet/rbi/gems/rails-html-sanitizer@1.6.0.rbi +785 -0
  299. data/sorbet/rbi/gems/rails@8.0.0.rbi +9 -0
  300. data/sorbet/rbi/gems/railties@8.0.0.rbi +6287 -0
  301. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +403 -0
  302. data/sorbet/rbi/gems/rake@13.2.1.rbi +3091 -0
  303. data/sorbet/rbi/gems/rbi@0.2.1.rbi +4535 -0
  304. data/sorbet/rbi/gems/rdoc@6.8.1.rbi +12572 -0
  305. data/sorbet/rbi/gems/regexp_parser@2.9.2.rbi +3772 -0
  306. data/sorbet/rbi/gems/reline@0.5.12.rbi +2416 -0
  307. data/sorbet/rbi/gems/rexml@3.3.9.rbi +4858 -0
  308. data/sorbet/rbi/gems/rspec-core@3.13.2.rbi +11287 -0
  309. data/sorbet/rbi/gems/rspec-expectations@3.13.3.rbi +8183 -0
  310. data/sorbet/rbi/gems/rspec-mocks@3.13.2.rbi +5341 -0
  311. data/sorbet/rbi/gems/rspec-support@3.13.1.rbi +1630 -0
  312. data/sorbet/rbi/gems/rspec@3.13.0.rbi +83 -0
  313. data/sorbet/rbi/gems/rubocop-ast@1.36.1.rbi +7303 -0
  314. data/sorbet/rbi/gems/rubocop-performance@1.21.1.rbi +9 -0
  315. data/sorbet/rbi/gems/rubocop@1.65.1.rbi +58170 -0
  316. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1318 -0
  317. data/sorbet/rbi/gems/securerandom@0.3.2.rbi +395 -0
  318. data/sorbet/rbi/gems/simplecov-html@0.13.1.rbi +225 -0
  319. data/sorbet/rbi/gems/simplecov@0.22.0.rbi +2149 -0
  320. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +9 -0
  321. data/sorbet/rbi/gems/spoom@1.5.0.rbi +4932 -0
  322. data/sorbet/rbi/gems/standard-custom@1.0.2.rbi +9 -0
  323. data/sorbet/rbi/gems/standard-performance@1.4.0.rbi +9 -0
  324. data/sorbet/rbi/gems/standard@1.40.0.rbi +929 -0
  325. data/sorbet/rbi/gems/stringio@3.1.2.rbi +9 -0
  326. data/sorbet/rbi/gems/tapioca@0.16.4.rbi +3597 -0
  327. data/sorbet/rbi/gems/thor@1.3.2.rbi +4378 -0
  328. data/sorbet/rbi/gems/timeout@0.4.2.rbi +151 -0
  329. data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5918 -0
  330. data/sorbet/rbi/gems/unicode-display_width@2.6.0.rbi +66 -0
  331. data/sorbet/rbi/gems/uri@1.0.2.rbi +2377 -0
  332. data/sorbet/rbi/gems/useragent@0.16.10.rbi +9 -0
  333. data/sorbet/rbi/gems/websocket-driver@0.7.6.rbi +9 -0
  334. data/sorbet/rbi/gems/websocket-extensions@0.1.5.rbi +9 -0
  335. data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
  336. data/sorbet/rbi/gems/yard@0.9.37.rbi +18504 -0
  337. data/sorbet/rbi/gems/zeitwerk@2.7.1.rbi +9 -0
  338. data/sorbet/tapioca/config.yml +13 -0
  339. data/sorbet/tapioca/require.rb +12 -0
  340. metadata +543 -0
@@ -0,0 +1,249 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "abstract_unit"
4
+ require "fixtures/person"
5
+ require "fixtures/street_address"
6
+ require "active_support/core_ext/hash/conversions"
7
+
8
+ module Highrise
9
+ class Note < ActiveResource::Base
10
+ self.site = "http://37s.sunrise.i:3000"
11
+ end
12
+
13
+ class Comment < ActiveResource::Base
14
+ self.site = "http://37s.sunrise.i:3000"
15
+ end
16
+
17
+ module Deeply
18
+ module Nested
19
+ class Note < ActiveResource::Base
20
+ self.site = "http://37s.sunrise.i:3000"
21
+ end
22
+
23
+ class Comment < ActiveResource::Base
24
+ self.site = "http://37s.sunrise.i:3000"
25
+ end
26
+
27
+ module TestDifferentLevels
28
+ class Note < ActiveResource::Base
29
+ self.site = "http://37s.sunrise.i:3000"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ class BaseLoadTest < ActiveSupport::TestCase
38
+ class FakeParameters
39
+ def initialize(attributes)
40
+ @attributes = attributes
41
+ end
42
+
43
+ def to_hash
44
+ @attributes
45
+ end
46
+ end
47
+
48
+ def setup
49
+ @matz = { id: 1, name: "Matz" }
50
+
51
+ @first_address = { address: { id: 1, street: "12345 Street" } }
52
+ @addresses = [@first_address, { address: { id: 2, street: "67890 Street" } }]
53
+ @addresses_from_json = { street_addresses: @addresses }
54
+ @addresses_from_json_single = { street_addresses: [ @first_address ] }
55
+
56
+ @deep = { id: 1, street: {
57
+ id: 1, state: { id: 1, name: "Oregon",
58
+ notable_rivers: [
59
+ { id: 1, name: "Willamette" },
60
+ { id: 2, name: "Columbia", rafted_by: @matz }],
61
+ postal_codes: [ 97018, 1234567890 ],
62
+ dates: [ Time.now ],
63
+ votes: [ true, false, true ],
64
+ places: [ "Columbia City", "Unknown" ] } } }
65
+
66
+
67
+ # List of books formatted as [{timestamp_of_publication => name}, ...]
68
+ @books = { books: [
69
+ { 1009839600 => "Ruby in a Nutshell" },
70
+ { 1199142000 => "The Ruby Programming Language" }
71
+ ] }
72
+
73
+ @books_date = { books: [
74
+ { Time.at(1009839600) => "Ruby in a Nutshell" },
75
+ { Time.at(1199142000) => "The Ruby Programming Language" }
76
+ ] }
77
+
78
+ @complex_books = {
79
+ books: {
80
+ "Complex.String&-Character*|=_+()!~": {
81
+ isbn: 1009839690,
82
+ author: "Frank Smith"
83
+ },
84
+ "16Candles": {
85
+ isbn: 1199142400,
86
+ author: "John Hughes"
87
+ }
88
+ }
89
+ }
90
+
91
+ @person = Person.new
92
+ end
93
+
94
+ def test_load_hash_with_integers_as_keys_creates_stringified_attributes
95
+ Person.__send__(:remove_const, :Book) if Person.const_defined?(:Book)
96
+ assert_not Person.const_defined?(:Book), "Books shouldn't exist until autocreated"
97
+ assert_nothing_raised { @person.load(@books) }
98
+ assert_equal @books[:books].map { |book| book.stringify_keys }, @person.books.map(&:attributes)
99
+ end
100
+
101
+ def test_load_hash_with_dates_as_keys_creates_stringified_attributes
102
+ Person.__send__(:remove_const, :Book) if Person.const_defined?(:Book)
103
+ assert_not Person.const_defined?(:Book), "Books shouldn't exist until autocreated"
104
+ assert_nothing_raised { @person.load(@books_date) }
105
+ assert_equal @books_date[:books].map { |book| book.stringify_keys }, @person.books.map(&:attributes)
106
+ end
107
+
108
+ def test_load_hash_with_unacceptable_constant_characters_creates_unknown_resource
109
+ Person.__send__(:remove_const, :Books) if Person.const_defined?(:Books)
110
+ assert_not Person.const_defined?(:Books), "Books shouldn't exist until autocreated"
111
+ assert_nothing_raised { @person.load(@complex_books) }
112
+ assert Person::Books.const_defined?(:UnnamedResource), "UnnamedResource should have been autocreated"
113
+ @person.books.attributes.keys.each { |key| assert_kind_of Person::Books::UnnamedResource, @person.books.attributes[key] }
114
+ end
115
+
116
+ def test_load_expects_hash
117
+ assert_raise(ArgumentError) { @person.load nil }
118
+ assert_raise(ArgumentError) { @person.load '<person id="1"/>' }
119
+ end
120
+
121
+ def test_load_simple_hash
122
+ assert_equal Hash.new, @person.attributes
123
+ assert_equal @matz.stringify_keys, @person.load(@matz).attributes
124
+ end
125
+
126
+ def test_load_object_with_implicit_conversion_to_hash
127
+ assert_equal @matz.stringify_keys, @person.load(FakeParameters.new(@matz)).attributes
128
+ end
129
+
130
+ def test_after_load_attributes_are_accessible
131
+ assert_equal Hash.new, @person.attributes
132
+ assert_equal @matz.stringify_keys, @person.load(@matz).attributes
133
+ assert_equal @matz[:name], @person.attributes["name"]
134
+ end
135
+
136
+ def test_after_load_attributes_are_accessible_via_indifferent_access
137
+ assert_equal Hash.new, @person.attributes
138
+ assert_equal @matz.stringify_keys, @person.load(@matz).attributes
139
+ assert_equal @matz[:name], @person.attributes["name"]
140
+ assert_equal @matz[:name], @person.attributes[:name]
141
+ end
142
+
143
+ def test_load_one_with_existing_resource
144
+ address = @person.load(street_address: @first_address.values.first).street_address
145
+ assert_kind_of StreetAddress, address
146
+ assert_equal @first_address.values.first.stringify_keys, address.attributes
147
+ end
148
+
149
+ def test_load_one_with_unknown_resource
150
+ address = silence_warnings { @person.load(@first_address).address }
151
+ assert_kind_of Person::Address, address
152
+ assert_equal @first_address.values.first.stringify_keys, address.attributes
153
+ end
154
+
155
+ def test_load_one_with_unknown_resource_from_anonymous_subclass
156
+ subclass = Class.new(Person).tap { |c| c.element_name = "person" }
157
+ address = silence_warnings { subclass.new.load(@first_address).address }
158
+ assert_kind_of subclass::Address, address
159
+ end
160
+
161
+ def test_load_collection_with_existing_resource
162
+ addresses = @person.load(@addresses_from_json).street_addresses
163
+ assert_kind_of Array, addresses
164
+ addresses.each { |address| assert_kind_of StreetAddress, address }
165
+ assert_equal @addresses.map { |a| a[:address].stringify_keys }, addresses.map(&:attributes)
166
+ end
167
+
168
+ def test_load_collection_with_unknown_resource
169
+ Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
170
+ assert_not Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
171
+ addresses = silence_warnings { @person.load(addresses: @addresses).addresses }
172
+ assert Person.const_defined?(:Address), "Address should have been autocreated"
173
+ addresses.each { |address| assert_kind_of Person::Address, address }
174
+ assert_equal @addresses.map { |a| a[:address].stringify_keys }, addresses.map(&:attributes)
175
+ end
176
+
177
+ def test_load_collection_with_single_existing_resource
178
+ addresses = @person.load(@addresses_from_json_single).street_addresses
179
+ assert_kind_of Array, addresses
180
+ addresses.each { |address| assert_kind_of StreetAddress, address }
181
+ assert_equal [ @first_address.values.first ].map(&:stringify_keys), addresses.map(&:attributes)
182
+ end
183
+
184
+ def test_load_collection_with_single_unknown_resource
185
+ Person.__send__(:remove_const, :Address) if Person.const_defined?(:Address)
186
+ assert_not Person.const_defined?(:Address), "Address shouldn't exist until autocreated"
187
+ addresses = silence_warnings { @person.load(addresses: [ @first_address ]).addresses }
188
+ assert Person.const_defined?(:Address), "Address should have been autocreated"
189
+ addresses.each { |address| assert_kind_of Person::Address, address }
190
+ assert_equal [ @first_address.values.first ].map(&:stringify_keys), addresses.map(&:attributes)
191
+ end
192
+
193
+ def test_recursively_loaded_collections
194
+ person = @person.load(@deep)
195
+ assert_equal @deep[:id], person.id
196
+
197
+ street = person.street
198
+ assert_kind_of Person::Street, street
199
+ assert_equal @deep[:street][:id], street.id
200
+
201
+ state = street.state
202
+ assert_kind_of Person::Street::State, state
203
+ assert_equal @deep[:street][:state][:id], state.id
204
+
205
+ rivers = state.notable_rivers
206
+ assert_kind_of Array, rivers
207
+ assert_kind_of Person::Street::State::NotableRiver, rivers.first
208
+ assert_equal @deep[:street][:state][:notable_rivers].first[:id], rivers.first.id
209
+ assert_equal @matz[:id], rivers.last.rafted_by.id
210
+
211
+ postal_codes = state.postal_codes
212
+ assert_kind_of Array, postal_codes
213
+ assert_equal 2, postal_codes.size
214
+ assert_kind_of Integer, postal_codes.first
215
+ assert_equal @deep[:street][:state][:postal_codes].first, postal_codes.first
216
+ assert_kind_of Numeric, postal_codes.last
217
+ assert_equal @deep[:street][:state][:postal_codes].last, postal_codes.last
218
+
219
+ places = state.places
220
+ assert_kind_of Array, places
221
+ assert_kind_of String, places.first
222
+ assert_equal @deep[:street][:state][:places].first, places.first
223
+
224
+ dates = state.dates
225
+ assert_kind_of Array, dates
226
+ assert_kind_of Time, dates.first
227
+ assert_equal @deep[:street][:state][:dates].first, dates.first
228
+
229
+ votes = state.votes
230
+ assert_kind_of Array, votes
231
+ assert_kind_of TrueClass, votes.first
232
+ assert_equal @deep[:street][:state][:votes].first, votes.first
233
+ end
234
+
235
+ def test_nested_collections_within_the_same_namespace
236
+ n = Highrise::Note.new(comments: [{ comment: { name: "1" } }])
237
+ assert_kind_of Highrise::Comment, n.comments.first
238
+ end
239
+
240
+ def test_nested_collections_within_deeply_nested_namespace
241
+ n = Highrise::Deeply::Nested::Note.new(comments: [{ name: "1" }])
242
+ assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
243
+ end
244
+
245
+ def test_nested_collections_in_different_levels_of_namespaces
246
+ n = Highrise::Deeply::Nested::TestDifferentLevels::Note.new(comments: [{ name: "1" }])
247
+ assert_kind_of Highrise::Deeply::Nested::Comment, n.comments.first
248
+ end
249
+ end
@@ -0,0 +1,428 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "abstract_unit"
4
+ require "active_support/core_ext/hash/conversions"
5
+ require "fixtures/person"
6
+ require "fixtures/street_address"
7
+
8
+ ########################################################################
9
+ # Testing the schema of your Active Resource models
10
+ ########################################################################
11
+ class SchemaTest < ActiveSupport::TestCase
12
+ def setup
13
+ setup_response # find me in abstract_unit
14
+ end
15
+
16
+ def teardown
17
+ Person.schema = nil # hack to stop test bleedthrough...
18
+ end
19
+
20
+
21
+ #####################################################
22
+ # Passing in a schema directly and returning it
23
+ ####
24
+
25
+ test "schema on a new model should be empty" do
26
+ assert Person.schema.blank?, "should have a blank class schema"
27
+ assert Person.new.schema.blank?, "should have a blank instance schema"
28
+ end
29
+
30
+ test "schema should only accept a hash" do
31
+ ["blahblah", ["one", "two"], [:age, :name], Person.new].each do |bad_schema|
32
+ assert_raises(ArgumentError, "should only accept a hash (or nil), but accepted: #{bad_schema.inspect}") do
33
+ Person.schema = bad_schema
34
+ end
35
+ end
36
+ end
37
+
38
+ test "schema should accept a simple hash" do
39
+ new_schema = { "age" => "integer", "name" => "string",
40
+ "height" => "float", "bio" => "text",
41
+ "weight" => "decimal", "photo" => "binary",
42
+ "alive" => "boolean", "created_at" => "timestamp",
43
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
44
+
45
+ assert_nothing_raised { Person.schema = new_schema }
46
+ assert_equal new_schema, Person.schema
47
+ end
48
+
49
+ test "schema should accept a hash with simple values" do
50
+ new_schema = { "age" => "integer", "name" => "string",
51
+ "height" => "float", "bio" => "text",
52
+ "weight" => "decimal", "photo" => "binary",
53
+ "alive" => "boolean", "created_at" => "timestamp",
54
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
55
+
56
+ assert_nothing_raised { Person.schema = new_schema }
57
+ assert_equal new_schema, Person.schema
58
+ end
59
+
60
+ test "schema should accept all known attribute types as values" do
61
+ ActiveResource::Schema::KNOWN_ATTRIBUTE_TYPES.each do |the_type|
62
+ assert_nothing_raised { Person.schema = { "my_key" => the_type } }
63
+ end
64
+ end
65
+
66
+ test "schema should not accept unknown values" do
67
+ bad_values = [ :oogle, :blob, "thing"]
68
+
69
+ bad_values.each do |bad_value|
70
+ assert_raises(ArgumentError, "should only accept a known attribute type, but accepted: #{bad_value.inspect}") do
71
+ Person.schema = { "key" => bad_value }
72
+ end
73
+ end
74
+ end
75
+
76
+ test "schema should accept nil and remove the schema" do
77
+ new_schema = { "age" => "integer", "name" => "string",
78
+ "height" => "float", "bio" => "text",
79
+ "weight" => "decimal", "photo" => "binary",
80
+ "alive" => "boolean", "created_at" => "timestamp",
81
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
82
+
83
+ assert_nothing_raised { Person.schema = new_schema }
84
+ assert_equal new_schema, Person.schema # sanity check
85
+
86
+ assert_nothing_raised { Person.schema = nil }
87
+ assert_nil Person.schema, "should have nulled out the schema, but still had: #{Person.schema.inspect}"
88
+ end
89
+
90
+ test "schema should be with indifferent access" do
91
+ new_schema = { "age" => "integer", "name" => "string",
92
+ "height" => "float", "bio" => "text",
93
+ "weight" => "decimal", "photo" => "binary",
94
+ "alive" => "boolean", "created_at" => "timestamp",
95
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
96
+
97
+ new_schema_syms = new_schema.keys
98
+
99
+ assert_nothing_raised { Person.schema = new_schema }
100
+ new_schema_syms.each do |col|
101
+ assert Person.new.respond_to?(col.to_s), "should respond to the schema's string key, but failed on: #{col}"
102
+ assert Person.new.respond_to?(col.to_sym), "should respond to the schema's symbol key, but failed on: #{col.to_sym}"
103
+ end
104
+ end
105
+
106
+ test "schema on a fetched resource should return all the attributes of that model instance" do
107
+ p = Person.find(1)
108
+ s = p.schema
109
+
110
+ assert s.present?, "should have found a non-empty schema!"
111
+
112
+ p.attributes.each do |the_attr, val|
113
+ assert s.has_key?(the_attr), "should have found attr: #{the_attr} in schema, but only had: #{s.inspect}"
114
+ end
115
+ end
116
+
117
+ test "with two instances, default schema should match the attributes of the individual instances - even if they differ" do
118
+ matz = Person.find(1)
119
+ rick = Person.find(6)
120
+
121
+ m_attrs = matz.attributes.keys.sort
122
+ r_attrs = rick.attributes.keys.sort
123
+
124
+ assert_not_equal m_attrs, r_attrs, "should have different attributes on each model"
125
+
126
+ assert_not_equal matz.schema, rick.schema, "should have had different schemas too"
127
+ end
128
+
129
+ test "defining a schema should return it when asked" do
130
+ assert Person.schema.blank?, "should have a blank class schema"
131
+ new_schema = { "age" => "integer", "name" => "string",
132
+ "height" => "float", "bio" => "text",
133
+ "weight" => "decimal", "photo" => "binary",
134
+ "alive" => "boolean", "created_at" => "timestamp",
135
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
136
+
137
+ assert_nothing_raised {
138
+ Person.schema = new_schema
139
+ assert_equal new_schema, Person.schema, "should have saved the schema on the class"
140
+ assert_equal new_schema, Person.new.schema, "should have made the schema available to every instance"
141
+ }
142
+ end
143
+
144
+ test "defining a schema, then fetching a model should still match the defined schema" do
145
+ # sanity checks
146
+ assert Person.schema.blank?, "should have a blank class schema"
147
+ new_schema = { "age" => "integer", "name" => "string",
148
+ "height" => "float", "bio" => "text",
149
+ "weight" => "decimal", "photo" => "binary",
150
+ "alive" => "boolean", "created_at" => "timestamp",
151
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
152
+
153
+ matz = Person.find(1)
154
+ assert_not matz.schema.blank?, "should have some sort of schema on an instance variable"
155
+ assert_not_equal new_schema, matz.schema, "should not have the class-level schema until it's been added to the class!"
156
+
157
+ assert_nothing_raised {
158
+ Person.schema = new_schema
159
+ assert_equal new_schema, matz.schema, "class-level schema should override instance-level schema"
160
+ }
161
+ end
162
+
163
+
164
+ #####################################################
165
+ # Using the schema syntax
166
+ ####
167
+
168
+ test "should be able to use schema" do
169
+ assert_respond_to Person, :schema, "should at least respond to the schema method"
170
+
171
+ assert_nothing_raised do
172
+ Person.schema { }
173
+ end
174
+ end
175
+
176
+ test "schema definition should store and return attribute set" do
177
+ assert_nothing_raised do
178
+ s = nil
179
+ Person.schema do
180
+ s = self
181
+ attribute :foo, :string
182
+ end
183
+ assert_respond_to s, :attrs, "should return attributes in theory"
184
+ assert_equal({ "foo" => "string" }, s.attrs, "should return attributes in practice")
185
+ end
186
+ end
187
+
188
+ test "should be able to add attributes through schema" do
189
+ assert_nothing_raised do
190
+ s = nil
191
+ Person.schema do
192
+ s = self
193
+ attribute("foo", "string")
194
+ end
195
+ assert s.attrs.has_key?("foo"), "should have saved the attribute name"
196
+ assert_equal "string", s.attrs["foo"], "should have saved the attribute type"
197
+ end
198
+ end
199
+
200
+ test "should convert symbol attributes to strings" do
201
+ assert_nothing_raised do
202
+ s = nil
203
+ Person.schema do
204
+ s = self
205
+ attribute(:foo, :integer)
206
+ end
207
+
208
+ assert s.attrs.has_key?("foo"), "should have saved the attribute name as a string"
209
+ assert_equal "integer", s.attrs["foo"], "should have saved the attribute type as a string"
210
+ end
211
+ end
212
+
213
+ test "should be able to add all known attribute types" do
214
+ assert_nothing_raised do
215
+ ActiveResource::Schema::KNOWN_ATTRIBUTE_TYPES.each do |the_type|
216
+ s = nil
217
+ Person.schema do
218
+ s = self
219
+ attribute("foo", the_type)
220
+ end
221
+ assert s.attrs.has_key?("foo"), "should have saved the attribute name"
222
+ assert_equal the_type.to_s, s.attrs["foo"], "should have saved the attribute type of: #{the_type}"
223
+ end
224
+ end
225
+ end
226
+
227
+ test "attributes should not accept unknown values" do
228
+ bad_values = [ :oogle, :blob, "thing"]
229
+
230
+ bad_values.each do |bad_value|
231
+ assert_raises(ArgumentError, "should only accept a known attribute type, but accepted: #{bad_value.inspect}") do
232
+ Person.schema do
233
+ attribute "key", bad_value
234
+ end
235
+ end
236
+ assert_not self.respond_to?(bad_value), "should only respond to a known attribute type, but accepted: #{bad_value.inspect}"
237
+ assert_raises(NoMethodError, "should only have methods for known attribute types, but accepted: #{bad_value.inspect}") do
238
+ Person.schema do
239
+ send bad_value, "key"
240
+ end
241
+ end
242
+ end
243
+ end
244
+
245
+ test "should accept attribute types as the type's name as the method" do
246
+ ActiveResource::Schema::KNOWN_ATTRIBUTE_TYPES.each do |the_type|
247
+ s = nil
248
+ Person.schema do
249
+ s = self
250
+ send(the_type, "foo")
251
+ end
252
+ assert s.attrs.has_key?("foo"), "should now have saved the attribute name"
253
+ assert_equal the_type.to_s, s.attrs["foo"], "should have saved the attribute type of: #{the_type}"
254
+ end
255
+ end
256
+
257
+ test "should accept multiple attribute names for an attribute method" do
258
+ names = ["foo", "bar", "baz"]
259
+ s = nil
260
+ Person.schema do
261
+ s = self
262
+ string(*names)
263
+ end
264
+ names.each do |the_name|
265
+ assert s.attrs.has_key?(the_name), "should now have saved the attribute name: #{the_name}"
266
+ assert_equal "string", s.attrs[the_name], "should have saved the attribute as a string"
267
+ end
268
+ end
269
+
270
+
271
+ #####################################################
272
+ # What a schema does for us
273
+ ####
274
+
275
+ # respond_to_missing?
276
+
277
+ test "should respond positively to attributes that are only in the schema" do
278
+ new_attr_name = :my_new_schema_attribute
279
+ new_attr_name_two = :another_new_schema_attribute
280
+ assert Person.schema.blank?, "sanity check - should have a blank class schema"
281
+
282
+ assert_not Person.new.respond_to?(new_attr_name), "sanity check - should not respond to the brand-new attribute yet"
283
+ assert_not Person.new.respond_to?(new_attr_name_two), "sanity check - should not respond to the brand-new attribute yet"
284
+
285
+ assert_nothing_raised do
286
+ Person.schema = { new_attr_name.to_s => "string" }
287
+ Person.schema { string new_attr_name_two }
288
+ end
289
+
290
+ assert_respond_to Person.new, new_attr_name, "should respond to the attribute in a passed-in schema, but failed on: #{new_attr_name}"
291
+ assert_respond_to Person.new, new_attr_name_two, "should respond to the attribute from the schema, but failed on: #{new_attr_name_two}"
292
+ end
293
+
294
+ test "should not care about ordering of schema definitions" do
295
+ new_attr_name = :my_new_schema_attribute
296
+ new_attr_name_two = :another_new_schema_attribute
297
+
298
+ assert Person.schema.blank?, "sanity check - should have a blank class schema"
299
+
300
+ assert_not Person.new.respond_to?(new_attr_name), "sanity check - should not respond to the brand-new attribute yet"
301
+ assert_not Person.new.respond_to?(new_attr_name_two), "sanity check - should not respond to the brand-new attribute yet"
302
+
303
+ assert_nothing_raised do
304
+ Person.schema { string new_attr_name_two }
305
+ Person.schema = { new_attr_name.to_s => "string" }
306
+ end
307
+
308
+ assert_respond_to Person.new, new_attr_name, "should respond to the attribute in a passed-in schema, but failed on: #{new_attr_name}"
309
+ assert_respond_to Person.new, new_attr_name_two, "should respond to the attribute from the schema, but failed on: #{new_attr_name_two}"
310
+ end
311
+
312
+ test "should retrieve the `Method` object" do
313
+ new_attr_name = :my_new_schema_attribute
314
+ new_attr_name_two = :another_new_schema_attribute
315
+ assert Person.schema.blank?, "sanity check - should have a blank class schema"
316
+
317
+ assert_not Person.new.respond_to?(new_attr_name), "sanity check - should not respond to the brand-new attribute yet"
318
+ assert_not Person.new.respond_to?(new_attr_name_two), "sanity check - should not respond to the brand-new attribute yet"
319
+
320
+ assert_nothing_raised do
321
+ Person.schema = { new_attr_name.to_s => "string" }
322
+ Person.schema { string new_attr_name_two }
323
+ end
324
+
325
+ assert_instance_of Method, Person.new.method(new_attr_name)
326
+ assert_instance_of Method, Person.new.method(new_attr_name_two)
327
+ end
328
+
329
+ # method_missing effects
330
+
331
+ test "should not give method_missing for attribute only in schema" do
332
+ new_attr_name = :another_new_schema_attribute
333
+ new_attr_name_two = :another_new_schema_attribute
334
+
335
+ assert Person.schema.blank?, "sanity check - should have a blank class schema"
336
+
337
+ assert_raises(NoMethodError, "should not have found the attribute: #{new_attr_name} as a method") do
338
+ Person.new.send(new_attr_name)
339
+ end
340
+ assert_raises(NoMethodError, "should not have found the attribute: #{new_attr_name_two} as a method") do
341
+ Person.new.send(new_attr_name_two)
342
+ end
343
+
344
+ Person.schema = { new_attr_name.to_s => :float }
345
+ Person.schema { string new_attr_name_two }
346
+
347
+ assert_nothing_raised do
348
+ Person.new.send(new_attr_name)
349
+ Person.new.send(new_attr_name_two)
350
+ end
351
+ end
352
+
353
+
354
+ ########
355
+ # Known attributes
356
+ #
357
+ # Attributes can be known to be attributes even if they aren't actually
358
+ # 'set' on a particular instance.
359
+ # This will only differ from 'attributes' if a schema has been set.
360
+
361
+ test "new model should have no known attributes" do
362
+ assert Person.known_attributes.blank?, "should have no known attributes"
363
+ assert Person.new.known_attributes.blank?, "should have no known attributes on a new instance"
364
+ end
365
+
366
+ test "setting schema should set known attributes on class and instance" do
367
+ new_schema = { "age" => "integer", "name" => "string",
368
+ "height" => "float", "bio" => "text",
369
+ "weight" => "decimal", "photo" => "binary",
370
+ "alive" => "boolean", "created_at" => "timestamp",
371
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
372
+
373
+ assert_nothing_raised { Person.schema = new_schema }
374
+
375
+ assert_equal new_schema.keys.sort, Person.known_attributes.sort
376
+ assert_equal new_schema.keys.sort, Person.new.known_attributes.sort
377
+ end
378
+
379
+ test "known attributes on a fetched resource should return all the attributes of the instance" do
380
+ p = Person.find(1)
381
+ attrs = p.known_attributes
382
+
383
+ assert attrs.present?, "should have found some attributes!"
384
+
385
+ p.attributes.each do |the_attr, val|
386
+ assert attrs.include?(the_attr), "should have found attr: #{the_attr} in known attributes, but only had: #{attrs.inspect}"
387
+ end
388
+ end
389
+
390
+ test "with two instances, known attributes should match the attributes of the individual instances - even if they differ" do
391
+ matz = Person.find(1)
392
+ rick = Person.find(6)
393
+
394
+ m_attrs = matz.attributes.keys.sort
395
+ r_attrs = rick.attributes.keys.sort
396
+
397
+ assert_not_equal m_attrs, r_attrs, "should have different attributes on each model"
398
+
399
+ assert_not_equal matz.known_attributes, rick.known_attributes, "should have had different known attributes too"
400
+ end
401
+
402
+ test "setting schema then fetching should add schema attributes to the instance attributes" do
403
+ # an attribute in common with fetched instance and one that isn't
404
+ new_schema = { "age" => "integer", "name" => "string",
405
+ "height" => "float", "bio" => "text",
406
+ "weight" => "decimal", "photo" => "binary",
407
+ "alive" => "boolean", "created_at" => "timestamp",
408
+ "thetime" => "time", "thedate" => "date", "mydatetime" => "datetime" }
409
+
410
+ assert_nothing_raised { Person.schema = new_schema }
411
+
412
+ matz = Person.find(1)
413
+ known_attrs = matz.known_attributes
414
+
415
+ matz.attributes.keys.each do |the_attr|
416
+ assert known_attrs.include?(the_attr), "should have found instance attr: #{the_attr} in known attributes, but only had: #{known_attrs.inspect}"
417
+ end
418
+ new_schema.keys.each do |the_attr|
419
+ assert known_attrs.include?(the_attr), "should have found schema attr: #{the_attr} in known attributes, but only had: #{known_attrs.inspect}"
420
+ end
421
+ end
422
+
423
+ test "known attributes should be unique" do
424
+ new_schema = { "age" => "integer", "name" => "string" }
425
+ Person.schema = new_schema
426
+ assert_equal Person.new(age: 20, name: "Matz").known_attributes, ["age", "name"]
427
+ end
428
+ end