active_cached_resource 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
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