uchi 0.1.3 → 0.1.5

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 (283) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +222 -0
  3. data/app/assets/config/uchi_manifest.js +2 -0
  4. data/app/assets/javascripts/uchi/application.js +6095 -0
  5. data/app/assets/javascripts/uchi.js +4 -0
  6. data/app/assets/stylesheets/uchi/application.css +3971 -0
  7. data/app/assets/stylesheets/uchi/uchi.css +17 -0
  8. data/app/assets/tailwind/uchi.css +21 -0
  9. data/app/components/flowbite/breadcrumb.rb +33 -0
  10. data/app/components/flowbite/breadcrumb_home.rb +26 -0
  11. data/app/components/flowbite/breadcrumb_item/current.rb +33 -0
  12. data/app/components/flowbite/breadcrumb_item/first.rb +35 -0
  13. data/app/components/flowbite/breadcrumb_item.rb +48 -0
  14. data/app/components/flowbite/breadcrumb_separator.rb +30 -0
  15. data/app/components/flowbite/button/outline.rb +22 -0
  16. data/app/components/flowbite/button/pill.rb +40 -0
  17. data/app/components/flowbite/button.rb +92 -0
  18. data/app/components/flowbite/card.rb +45 -0
  19. data/app/components/flowbite/input/checkbox.rb +73 -0
  20. data/app/components/flowbite/input/date.rb +11 -0
  21. data/app/components/flowbite/input/date_time.rb +11 -0
  22. data/app/components/flowbite/input/email.rb +12 -0
  23. data/app/components/flowbite/input/field.rb +117 -0
  24. data/app/components/flowbite/input/file.rb +30 -0
  25. data/app/components/flowbite/input/hint.rb +57 -0
  26. data/app/components/flowbite/input/label.rb +82 -0
  27. data/app/components/flowbite/input/number.rb +11 -0
  28. data/app/components/flowbite/input/password.rb +11 -0
  29. data/app/components/flowbite/input/phone.rb +11 -0
  30. data/app/components/flowbite/input/radio_button.rb +50 -0
  31. data/app/components/flowbite/input/select.rb +49 -0
  32. data/app/components/flowbite/input/textarea.rb +42 -0
  33. data/app/components/flowbite/input/url.rb +12 -0
  34. data/app/components/flowbite/input/validation_error.rb +11 -0
  35. data/app/components/flowbite/input_field/checkbox.html.erb +14 -0
  36. data/app/components/flowbite/input_field/checkbox.rb +54 -0
  37. data/app/components/flowbite/input_field/date.rb +13 -0
  38. data/app/components/flowbite/input_field/date_time.rb +13 -0
  39. data/app/components/flowbite/input_field/email.rb +13 -0
  40. data/app/components/flowbite/input_field/file.rb +13 -0
  41. data/app/components/flowbite/input_field/input_field.html.erb +8 -0
  42. data/app/components/flowbite/input_field/number.rb +13 -0
  43. data/app/components/flowbite/input_field/password.rb +13 -0
  44. data/app/components/flowbite/input_field/phone.rb +13 -0
  45. data/app/components/flowbite/input_field/radio_button.html.erb +14 -0
  46. data/app/components/flowbite/input_field/radio_button.rb +86 -0
  47. data/app/components/flowbite/input_field/select.rb +31 -0
  48. data/app/components/flowbite/input_field/text.rb +8 -0
  49. data/app/components/flowbite/input_field/textarea.rb +13 -0
  50. data/app/components/flowbite/input_field/url.rb +13 -0
  51. data/app/components/flowbite/input_field.rb +192 -0
  52. data/app/components/flowbite/link.rb +21 -0
  53. data/app/components/flowbite/style.rb +13 -0
  54. data/app/components/flowbite/toast/icon.html.erb +5 -0
  55. data/app/components/flowbite/toast/icon.rb +57 -0
  56. data/app/components/flowbite/toast/toast.html.erb +11 -0
  57. data/app/components/flowbite/toast.rb +34 -0
  58. data/app/components/uchi/field/base.rb +57 -0
  59. data/app/components/uchi/field/belongs_to/edit.html.erb +1 -0
  60. data/app/components/uchi/field/belongs_to/index.html.erb +1 -0
  61. data/app/components/uchi/field/belongs_to/show.html.erb +5 -0
  62. data/app/components/uchi/field/belongs_to.rb +112 -0
  63. data/app/components/uchi/field/blank/edit.html.erb +1 -0
  64. data/app/components/uchi/field/blank/index.html.erb +1 -0
  65. data/app/components/uchi/field/blank/show.html.erb +1 -0
  66. data/app/components/uchi/field/blank.rb +16 -0
  67. data/app/components/uchi/field/boolean/edit.html.erb +1 -0
  68. data/app/components/uchi/field/boolean/index.html.erb +9 -0
  69. data/app/components/uchi/field/boolean/show.html.erb +9 -0
  70. data/app/components/uchi/field/boolean.rb +27 -0
  71. data/app/components/uchi/field/date/edit.html.erb +1 -0
  72. data/app/components/uchi/field/date/index.html.erb +1 -0
  73. data/app/components/uchi/field/date/show.html.erb +1 -0
  74. data/app/components/uchi/field/date.rb +27 -0
  75. data/app/components/uchi/field/date_time/edit.html.erb +1 -0
  76. data/app/components/uchi/field/date_time/index.html.erb +1 -0
  77. data/app/components/uchi/field/date_time/show.html.erb +1 -0
  78. data/app/components/uchi/field/date_time.rb +27 -0
  79. data/app/components/uchi/field/file/edit.html.erb +1 -0
  80. data/app/components/uchi/field/file/index.html.erb +6 -0
  81. data/app/components/uchi/field/file/show.html.erb +8 -0
  82. data/app/components/uchi/field/file.rb +37 -0
  83. data/app/components/uchi/field/has_and_belongs_to_many/edit.html.erb +9 -0
  84. data/app/components/uchi/field/has_and_belongs_to_many/index.html.erb +1 -0
  85. data/app/components/uchi/field/has_and_belongs_to_many/show.html.erb +28 -0
  86. data/app/components/uchi/field/has_and_belongs_to_many.rb +131 -0
  87. data/app/components/uchi/field/has_many/edit.html.erb +1 -0
  88. data/app/components/uchi/field/has_many/index.html.erb +1 -0
  89. data/app/components/uchi/field/has_many/show.html.erb +28 -0
  90. data/app/components/uchi/field/has_many.rb +107 -0
  91. data/app/components/uchi/field/id/index.html.erb +4 -0
  92. data/app/components/uchi/field/id/show.html.erb +4 -0
  93. data/app/components/uchi/field/id.rb +26 -0
  94. data/app/components/uchi/field/image/edit.html.erb +1 -0
  95. data/app/components/uchi/field/image/index.html.erb +6 -0
  96. data/app/components/uchi/field/image/show.html.erb +6 -0
  97. data/app/components/uchi/field/image.rb +38 -0
  98. data/app/components/uchi/field/number/edit.html.erb +1 -0
  99. data/app/components/uchi/field/number/index.html.erb +1 -0
  100. data/app/components/uchi/field/number/show.html.erb +1 -0
  101. data/app/components/uchi/field/number.rb +32 -0
  102. data/app/components/uchi/field/string/edit.html.erb +1 -0
  103. data/app/components/uchi/field/string/index.html.erb +1 -0
  104. data/app/components/uchi/field/string/show.html.erb +1 -0
  105. data/app/components/uchi/field/string.rb +33 -0
  106. data/app/components/uchi/field/text/edit.html.erb +1 -0
  107. data/app/components/uchi/field/text/index.html.erb +1 -0
  108. data/app/components/uchi/field/text/show.html.erb +1 -0
  109. data/app/components/uchi/field/text.rb +38 -0
  110. data/app/components/uchi/ui/breadcrumb/breadcrumb.html.erb +13 -0
  111. data/app/components/uchi/ui/breadcrumb.rb +14 -0
  112. data/app/components/uchi/ui/form/footer/footer.html.erb +5 -0
  113. data/app/components/uchi/ui/form/footer.rb +15 -0
  114. data/app/components/uchi/ui/form/input/collection_checkboxes.html.erb +32 -0
  115. data/app/components/uchi/ui/form/input/collection_checkboxes.rb +125 -0
  116. data/app/components/uchi/ui/frame/frame.html.erb +3 -0
  117. data/app/components/uchi/ui/frame.rb +10 -0
  118. data/app/components/uchi/ui/index/records_table/records_table.html.erb +67 -0
  119. data/app/components/uchi/ui/index/records_table/search_form/search_form.html.erb +21 -0
  120. data/app/components/uchi/ui/index/records_table/search_form.rb +49 -0
  121. data/app/components/uchi/ui/index/records_table.rb +29 -0
  122. data/app/components/uchi/ui/index/turbo_frame.rb +50 -0
  123. data/app/components/uchi/ui/page_header/page_header.html.erb +24 -0
  124. data/app/components/uchi/ui/page_header.rb +18 -0
  125. data/app/components/uchi/ui/pagination/current_link.html.erb +3 -0
  126. data/app/components/uchi/ui/pagination/current_link.rb +10 -0
  127. data/app/components/uchi/ui/pagination/gap.html.erb +3 -0
  128. data/app/components/uchi/ui/pagination/gap.rb +10 -0
  129. data/app/components/uchi/ui/pagination/item.rb +24 -0
  130. data/app/components/uchi/ui/pagination/link.html.erb +3 -0
  131. data/app/components/uchi/ui/pagination/link.rb +10 -0
  132. data/app/components/uchi/ui/pagination/next_link.html.erb +8 -0
  133. data/app/components/uchi/ui/pagination/next_link.rb +22 -0
  134. data/app/components/uchi/ui/pagination/pagination.html.erb +15 -0
  135. data/app/components/uchi/ui/pagination/previous_link.html.erb +8 -0
  136. data/app/components/uchi/ui/pagination/previous_link.rb +22 -0
  137. data/app/components/uchi/ui/pagination.rb +48 -0
  138. data/app/components/uchi/ui/show/attribute_fields/attribute_fields.html.erb +14 -0
  139. data/app/components/uchi/ui/show/attribute_fields.rb +18 -0
  140. data/app/components/uchi/ui/spinner/spinner.html.erb +7 -0
  141. data/app/components/uchi/ui/spinner.rb +15 -0
  142. data/app/controllers/uchi/application_controller.rb +4 -0
  143. data/app/controllers/uchi/controller.rb +13 -0
  144. data/app/controllers/uchi/repository_controller.rb +166 -0
  145. data/app/helpers/uchi/application_helper.rb +17 -0
  146. data/app/jobs/uchi/application_job.rb +4 -0
  147. data/app/mailers/uchi/application_mailer.rb +6 -0
  148. data/app/views/layouts/uchi/_flash_messages.html.erb +10 -0
  149. data/app/views/layouts/uchi/application.html.erb +33 -0
  150. data/app/views/uchi/repository/edit.html.erb +40 -0
  151. data/app/views/uchi/repository/index.html.erb +49 -0
  152. data/app/views/uchi/repository/new.html.erb +37 -0
  153. data/app/views/uchi/repository/show.html.erb +41 -0
  154. data/lib/generators/uchi/controller/controller_generator.rb +16 -0
  155. data/lib/generators/uchi/controller/templates/controller.rb.tt +11 -0
  156. data/lib/generators/uchi/install/install_generator.rb +13 -0
  157. data/lib/generators/uchi/repository/repository_generator.rb +16 -0
  158. data/lib/generators/uchi/repository/templates/repository.rb.tt +11 -0
  159. data/lib/tasks/uchi_tasks.rake +4 -0
  160. data/lib/uchi/application_record.rb +5 -0
  161. data/lib/uchi/engine.rb +24 -0
  162. data/lib/uchi/field/configuration.rb +142 -0
  163. data/lib/uchi/field.rb +80 -0
  164. data/lib/uchi/i18n.rb +13 -0
  165. data/lib/uchi/pagination/controller.rb +26 -0
  166. data/lib/uchi/pagination/page.rb +20 -0
  167. data/lib/uchi/pagy/LICENSE.txt +21 -0
  168. data/lib/uchi/pagy/classes/exceptions.rb +35 -0
  169. data/lib/uchi/pagy/classes/offset/offset.rb +56 -0
  170. data/lib/uchi/pagy/classes/request.rb +38 -0
  171. data/lib/uchi/pagy/modules/abilities/configurable.rb +38 -0
  172. data/lib/uchi/pagy/modules/abilities/linkable.rb +62 -0
  173. data/lib/uchi/pagy/modules/abilities/rangeable.rb +17 -0
  174. data/lib/uchi/pagy/modules/abilities/shiftable.rb +14 -0
  175. data/lib/uchi/pagy/modules/console.rb +40 -0
  176. data/lib/uchi/pagy/toolbox/helpers/loader.rb +19 -0
  177. data/lib/uchi/pagy/toolbox/helpers/page_url.rb +25 -0
  178. data/lib/uchi/pagy/toolbox/paginators/method.rb +21 -0
  179. data/lib/uchi/pagy/toolbox/paginators/offset.rb +35 -0
  180. data/lib/uchi/pagy.rb +60 -0
  181. data/lib/uchi/repository/routes.rb +62 -0
  182. data/lib/uchi/repository/translate.rb +368 -0
  183. data/lib/uchi/repository.rb +156 -0
  184. data/lib/uchi/sort_order.rb +35 -0
  185. data/lib/uchi/version.rb +5 -0
  186. data/lib/uchi.rb +18 -0
  187. data/uchi.gemspec +35 -0
  188. metadata +189 -97
  189. data/.github/dependabot.yml +0 -17
  190. data/.github/workflows/build.yml +0 -23
  191. data/.github/workflows/lint.yml +0 -30
  192. data/CHANGELOG.md +0 -29
  193. data/docs/fields.md +0 -82
  194. data/docs/repositories.md +0 -63
  195. data/package.json +0 -31
  196. data/sig/uchi.rbs +0 -4
  197. data/test/components/uchi/field/belongs_to_test.rb +0 -134
  198. data/test/components/uchi/field/blank_test.rb +0 -119
  199. data/test/components/uchi/field/boolean_test.rb +0 -163
  200. data/test/components/uchi/field/date_test.rb +0 -163
  201. data/test/components/uchi/field/date_time_test.rb +0 -152
  202. data/test/components/uchi/field/has_and_belongs_to_many_test.rb +0 -144
  203. data/test/components/uchi/field/has_many_test.rb +0 -138
  204. data/test/components/uchi/field/id_test.rb +0 -113
  205. data/test/components/uchi/field/number_test.rb +0 -163
  206. data/test/components/uchi/field/string_test.rb +0 -159
  207. data/test/components/uchi/field/text_test.rb +0 -160
  208. data/test/components/uchi/ui/form/input/collection_checkboxes_test.rb +0 -171
  209. data/test/controllers/uchi/authors_controller_test.rb +0 -120
  210. data/test/controllers/uchi/repository_controller_test.rb +0 -93
  211. data/test/controllers/uchi/scoped_repository_controller_test.rb +0 -73
  212. data/test/dummy/Rakefile +0 -6
  213. data/test/dummy/app/assets/images/.keep +0 -0
  214. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  215. data/test/dummy/app/controllers/application_controller.rb +0 -4
  216. data/test/dummy/app/controllers/concerns/.keep +0 -0
  217. data/test/dummy/app/controllers/uchi/authors_controller.rb +0 -7
  218. data/test/dummy/app/controllers/uchi/books_controller.rb +0 -7
  219. data/test/dummy/app/controllers/uchi/titles_controller.rb +0 -7
  220. data/test/dummy/app/helpers/application_helper.rb +0 -2
  221. data/test/dummy/app/jobs/application_job.rb +0 -7
  222. data/test/dummy/app/mailers/application_mailer.rb +0 -4
  223. data/test/dummy/app/models/application_record.rb +0 -3
  224. data/test/dummy/app/models/author.rb +0 -5
  225. data/test/dummy/app/models/book.rb +0 -4
  226. data/test/dummy/app/models/concerns/.keep +0 -0
  227. data/test/dummy/app/models/title.rb +0 -3
  228. data/test/dummy/app/uchi/repositories/author.rb +0 -20
  229. data/test/dummy/app/uchi/repositories/book.rb +0 -16
  230. data/test/dummy/app/uchi/repositories/title.rb +0 -17
  231. data/test/dummy/app/views/layouts/application.html.erb +0 -27
  232. data/test/dummy/app/views/layouts/mailer.html.erb +0 -13
  233. data/test/dummy/app/views/layouts/mailer.text.erb +0 -1
  234. data/test/dummy/app/views/pwa/manifest.json.erb +0 -22
  235. data/test/dummy/app/views/pwa/service-worker.js +0 -26
  236. data/test/dummy/bin/dev +0 -2
  237. data/test/dummy/bin/rails +0 -4
  238. data/test/dummy/bin/rake +0 -4
  239. data/test/dummy/bin/setup +0 -34
  240. data/test/dummy/config/application.rb +0 -29
  241. data/test/dummy/config/boot.rb +0 -5
  242. data/test/dummy/config/cable.yml +0 -10
  243. data/test/dummy/config/database.yml +0 -32
  244. data/test/dummy/config/environment.rb +0 -5
  245. data/test/dummy/config/environments/development.rb +0 -69
  246. data/test/dummy/config/environments/production.rb +0 -89
  247. data/test/dummy/config/environments/test.rb +0 -53
  248. data/test/dummy/config/initializers/content_security_policy.rb +0 -25
  249. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -8
  250. data/test/dummy/config/initializers/inflections.rb +0 -16
  251. data/test/dummy/config/locales/da.yml +0 -52
  252. data/test/dummy/config/locales/en.yml +0 -31
  253. data/test/dummy/config/puma.rb +0 -38
  254. data/test/dummy/config/routes.rb +0 -9
  255. data/test/dummy/config/storage.yml +0 -34
  256. data/test/dummy/config.ru +0 -6
  257. data/test/dummy/db/migrate/20251002183635_create_authors.rb +0 -11
  258. data/test/dummy/db/migrate/20251005131726_create_books.rb +0 -9
  259. data/test/dummy/db/migrate/20251005131811_create_titles.rb +0 -11
  260. data/test/dummy/db/migrate/20251031140958_add_author_books_join_table.rb +0 -9
  261. data/test/dummy/db/schema.rb +0 -44
  262. data/test/dummy/log/.keep +0 -0
  263. data/test/dummy/public/400.html +0 -114
  264. data/test/dummy/public/404.html +0 -114
  265. data/test/dummy/public/406-unsupported-browser.html +0 -114
  266. data/test/dummy/public/422.html +0 -114
  267. data/test/dummy/public/500.html +0 -114
  268. data/test/dummy/public/icon.png +0 -0
  269. data/test/dummy/public/icon.svg +0 -3
  270. data/test/dummy/storage/.keep +0 -0
  271. data/test/dummy/test/fixtures/authors.yml +0 -11
  272. data/test/dummy/test/models/author_test.rb +0 -7
  273. data/test/dummy/tmp/.keep +0 -0
  274. data/test/dummy/tmp/pids/.keep +0 -0
  275. data/test/dummy/tmp/storage/.keep +0 -0
  276. data/test/test_helper.rb +0 -15
  277. data/test/uchi/field_test.rb +0 -77
  278. data/test/uchi/i18n_test.rb +0 -18
  279. data/test/uchi/repository/routes_test.rb +0 -49
  280. data/test/uchi/repository/translate_test.rb +0 -272
  281. data/test/uchi/repository_test.rb +0 -137
  282. data/test/uchi/sort_order_test.rb +0 -47
  283. data/test/uchi_test.rb +0 -7
@@ -1,152 +0,0 @@
1
- require "test_helper"
2
- require "ostruct"
3
-
4
- module Uchi
5
- class Field
6
- class DateTimeTest < ActiveSupport::TestCase
7
- def setup
8
- @field = Uchi::Field::DateTime.new(:created_at)
9
- @form = OpenStruct.new(object: OpenStruct.new(created_at: ::DateTime.new(2024, 1, 1, 12, 0, 0)))
10
- @repository = Uchi::Repositories::Author.new
11
- end
12
-
13
- test "inherits from Uchi::Field" do
14
- assert_kind_of Uchi::Field, @field
15
- end
16
-
17
- test "has default options" do
18
- assert_equal [:edit, :index, :show], @field.on
19
- assert_not @field.searchable?
20
- assert @field.sortable?
21
- end
22
-
23
- test "#edit_component returns an instance of Edit component" do
24
- component = @field.edit_component(form: @form, hint: "Custom hint", label: "Custom label", repository: @repository)
25
- assert_equal "Custom hint", component.hint
26
- assert_equal "Custom label", component.label
27
- assert_equal @field, component.field
28
- assert_equal @form, component.form
29
- assert_equal @repository, component.repository
30
- assert_kind_of Uchi::Field::DateTime::Edit, component
31
- end
32
-
33
- test "#index_component returns an instance of Index component" do
34
- component = @field.index_component(record: @form.object, repository: @repository)
35
- assert_equal @field, component.field
36
- assert_equal @form.object, component.record
37
- assert_equal @repository, component.repository
38
- assert_kind_of Uchi::Field::DateTime::Index, component
39
- end
40
-
41
- test "#searchable? returns false when explicitly set" do
42
- field = Uchi::Field::DateTime.new(:created_at).searchable(false)
43
- assert_not field.searchable?
44
- end
45
-
46
- test "#show_component returns an instance of Show component" do
47
- component = @field.show_component(record: @form.object, repository: @repository)
48
- assert_equal @field, component.field
49
- assert_equal @form.object, component.record
50
- assert_equal @repository, component.repository
51
- assert_kind_of Uchi::Field::DateTime::Show, component
52
- end
53
-
54
- test "#sortable? returns false when explicitly set" do
55
- field = Uchi::Field::DateTime.new(:created_at).sortable(false)
56
- assert_not field.sortable?
57
- end
58
- end
59
-
60
- class DateTimeEditTest < ViewComponent::TestCase
61
- def setup
62
- @field = Uchi::Field::DateTime.new(:created_at)
63
- @record = Author.new(name: "Test Author")
64
- @record.define_singleton_method(:created_at) { ::DateTime.new(2024, 1, 1, 12, 0, 0) }
65
- @record.define_singleton_method(:created_at=) { |val| @created_at = val }
66
- @repository = Uchi::Repositories::Author.new
67
- @view_context = ActionController::Base.new.view_context
68
-
69
- @form = ActionView::Helpers::FormBuilder.new(:author, @record, @view_context, {})
70
-
71
- @component = Uchi::Field::DateTime::Edit.new(
72
- field: @field,
73
- form: @form,
74
- hint: "Custom hint",
75
- label: "Custom label",
76
- repository: @repository
77
- )
78
- end
79
-
80
- test "inherits from Base component" do
81
- assert_kind_of Uchi::Field::Base::Edit, @component
82
- end
83
-
84
- test "can be rendered without errors" do
85
- # Skip rendering tests due to missing Flowbite::InputField::DateTime dependency
86
- assert_nothing_raised do
87
- @component
88
- end
89
- end
90
-
91
- test "initializes the input component with the correct options" do
92
- expected_options = {
93
- attribute: :created_at,
94
- form: @form,
95
- label: {content: "Custom label"},
96
- hint: {content: "Custom hint"}
97
- }
98
- assert_equal expected_options, @component.send(:options)
99
- end
100
- end
101
-
102
- class DateTimeIndexTest < ViewComponent::TestCase
103
- def setup
104
- @field = Uchi::Field::DateTime.new(:created_at)
105
- @record = Author.new(name: "Test Author")
106
- @record.define_singleton_method(:created_at) { ::DateTime.new(2024, 1, 1, 12, 0, 0) }
107
- @repository = Uchi::Repositories::Author.new
108
-
109
- @component = Uchi::Field::DateTime::Index.new(
110
- field: @field,
111
- record: @record,
112
- repository: @repository
113
- )
114
- end
115
-
116
- test "inherits from Base component" do
117
- assert_kind_of Uchi::Field::Base::Index, @component
118
- end
119
-
120
- test "renders the field content" do
121
- result = render_inline(@component)
122
-
123
- assert_includes result.to_html, "2024-01-01T12:00:00+00:00"
124
- end
125
- end
126
-
127
- class DateTimeShowTest < ViewComponent::TestCase
128
- def setup
129
- @field = Uchi::Field::DateTime.new(:created_at)
130
- @record = Author.new(name: "Test Author")
131
- @record.define_singleton_method(:created_at) { ::DateTime.new(2024, 1, 1, 12, 0, 0) }
132
- @repository = Uchi::Repositories::Author.new
133
-
134
- @component = Uchi::Field::DateTime::Show.new(
135
- field: @field,
136
- record: @record,
137
- repository: @repository
138
- )
139
- end
140
-
141
- test "inherits from Base component" do
142
- assert_kind_of Uchi::Field::Base::Show, @component
143
- end
144
-
145
- test "renders the field content" do
146
- result = render_inline(@component)
147
-
148
- assert_includes result.to_html, "2024-01-01T12:00:00+00:00"
149
- end
150
- end
151
- end
152
- end
@@ -1,144 +0,0 @@
1
- require "test_helper"
2
- require "ostruct"
3
-
4
- module Uchi
5
- class Field
6
- class HasAndBelongsToManyTest < ActiveSupport::TestCase
7
- def setup
8
- @record = Book.new
9
- @form = OpenStruct.new(object: @record)
10
-
11
- @repository = Uchi::Repositories::Book.new
12
- @field = Uchi::Field::HasAndBelongsToMany.new(:authors)
13
- @field.repository = @repository
14
- end
15
-
16
- test "inherits from Uchi::Field" do
17
- assert_kind_of Uchi::Field, @field
18
- end
19
-
20
- test "has default options specific to HasAndBelongsToMany field" do
21
- assert_not @field.searchable?
22
- assert @field.sortable?
23
- end
24
-
25
- test "has custom collection_query" do
26
- custom_query = ->(query) { query.where(published: true) }
27
- field = Uchi::Field::HasAndBelongsToMany.new(:categories).collection_query(custom_query)
28
- assert_equal custom_query, field.collection_query
29
- end
30
-
31
- test "uses default collection_query" do
32
- assert_equal Uchi::Field::HasAndBelongsToMany::DEFAULT_COLLECTION_QUERY, @field.collection_query
33
- end
34
-
35
- test "#param_key returns foreign key name" do
36
- assert_equal :author_ids, @field.param_key
37
- end
38
-
39
- test "#permitted_param returns key for strong parameters" do
40
- assert_equal({author_ids: []}, @field.permitted_param)
41
- end
42
-
43
- test "#group_as returns :associations" do
44
- assert_equal :associations, @field.group_as(:show)
45
- assert_equal :associations, @field.group_as(:edit)
46
- end
47
-
48
- test "#edit_component returns an instance of Edit component" do
49
- component = @field.edit_component(form: @form, hint: "Custom hint", label: "Custom label", repository: @repository)
50
- assert_equal "Custom hint", component.hint
51
- assert_equal "Custom label", component.label
52
- assert_equal @field, component.field
53
- assert_equal @form, component.form
54
- assert_equal @repository, component.repository
55
- assert_kind_of Uchi::Field::HasAndBelongsToMany::Edit, component
56
- end
57
-
58
- test "#index_component returns an instance of Index component" do
59
- component = @field.index_component(record: @form.object, repository: @repository)
60
- assert_equal @field, component.field
61
- assert_equal @form.object, component.record
62
- assert_equal @repository, component.repository
63
- assert_kind_of Uchi::Field::HasAndBelongsToMany::Index, component
64
- end
65
-
66
- test "#show_component returns an instance of Show component" do
67
- component = @field.show_component(record: @form.object, repository: @repository)
68
- assert_equal @field, component.field
69
- assert_equal @form.object, component.record
70
- assert_equal @repository, component.repository
71
- assert_kind_of Uchi::Field::HasAndBelongsToMany::Show, component
72
- end
73
-
74
- test "#searchable? returns false when explicitly set" do
75
- field = Uchi::Field::HasAndBelongsToMany.new(:categories).searchable(false)
76
- assert_not field.searchable?
77
- end
78
-
79
- test "#sortable? returns false when explicitly set" do
80
- field = Uchi::Field::HasAndBelongsToMany.new(:categories).sortable(false)
81
- assert_not field.sortable?
82
- end
83
- end
84
-
85
- class HasAndBelongsToManyEditTest < ViewComponent::TestCase
86
- def setup
87
- @field = Uchi::Field::HasAndBelongsToMany.new(:categories)
88
- @book = Book.new(original_title: "The Hobbit")
89
- @repository = Uchi::Repositories::Book.new
90
- @view_context = ActionController::Base.new.view_context
91
-
92
- @form = ActionView::Helpers::FormBuilder.new(:book, @book, @view_context, {})
93
-
94
- @component = Uchi::Field::HasAndBelongsToMany::Edit.new(
95
- field: @field,
96
- form: @form,
97
- hint: "Custom hint",
98
- label: "Custom label",
99
- repository: @repository
100
- )
101
- end
102
-
103
- test "inherits from Base component" do
104
- assert_kind_of Uchi::Field::Base::Edit, @component
105
- end
106
- end
107
-
108
- class HasAndBelongsToManyIndexTest < ViewComponent::TestCase
109
- def setup
110
- @field = Uchi::Field::HasAndBelongsToMany.new(:categories)
111
- @book = Book.new(original_title: "The Hobbit")
112
- @repository = Uchi::Repositories::Book.new
113
-
114
- @component = Uchi::Field::HasAndBelongsToMany::Index.new(
115
- field: @field,
116
- record: @book,
117
- repository: @repository
118
- )
119
- end
120
-
121
- test "inherits from Base component" do
122
- assert_kind_of Uchi::Field::Base::Index, @component
123
- end
124
- end
125
-
126
- class HasAndBelongsToManyShowTest < ViewComponent::TestCase
127
- def setup
128
- @field = Uchi::Field::HasAndBelongsToMany.new(:categories)
129
- @book = Book.new(original_title: "The Hobbit")
130
- @repository = Uchi::Repositories::Book.new
131
-
132
- @component = Uchi::Field::HasAndBelongsToMany::Show.new(
133
- field: @field,
134
- record: @book,
135
- repository: @repository
136
- )
137
- end
138
-
139
- test "inherits from Base component" do
140
- assert_kind_of Uchi::Field::Base::Show, @component
141
- end
142
- end
143
- end
144
- end
@@ -1,138 +0,0 @@
1
- require "test_helper"
2
- require "ostruct"
3
-
4
- module Uchi
5
- class Field
6
- class HasManyTest < ActiveSupport::TestCase
7
- def setup
8
- @field = Uchi::Field::HasMany.new(:titles)
9
- @form = OpenStruct.new(object: Book.new)
10
- @repository = Uchi::Repositories::Book.new
11
- end
12
-
13
- test "inherits from Uchi::Field" do
14
- assert_kind_of Uchi::Field, @field
15
- end
16
-
17
- test "has default options specific to HasMany field" do
18
- assert_equal [:show], @field.on # Different from other fields - only on show
19
- assert_not @field.searchable?
20
- assert @field.sortable?
21
- end
22
-
23
- test "has custom collection_query" do
24
- custom_query = ->(query) { query.where(published: true) }
25
- field = Uchi::Field::HasMany.new(:titles).collection_query(custom_query)
26
- assert_equal custom_query, field.collection_query
27
- end
28
-
29
- test "uses default collection_query" do
30
- assert_equal Uchi::Field::HasMany::DEFAULT_COLLECTION_QUERY, @field.collection_query
31
- end
32
-
33
- test "#param_key returns foreign key name" do
34
- assert_equal :titles_id, @field.param_key
35
- end
36
-
37
- test "#group_as returns :associations" do
38
- assert_equal :associations, @field.group_as(:show)
39
- assert_equal :associations, @field.group_as(:edit)
40
- end
41
-
42
- test "#edit_component returns an instance of Edit component" do
43
- component = @field.edit_component(form: @form, hint: "Custom hint", label: "Custom label", repository: @repository)
44
- assert_equal "Custom hint", component.hint
45
- assert_equal "Custom label", component.label
46
- assert_equal @field, component.field
47
- assert_equal @form, component.form
48
- assert_equal @repository, component.repository
49
- assert_kind_of Uchi::Field::HasMany::Edit, component
50
- end
51
-
52
- test "#index_component returns an instance of Index component" do
53
- component = @field.index_component(record: @form.object, repository: @repository)
54
- assert_equal @field, component.field
55
- assert_equal @form.object, component.record
56
- assert_equal @repository, component.repository
57
- assert_kind_of Uchi::Field::HasMany::Index, component
58
- end
59
-
60
- test "#show_component returns an instance of Show component" do
61
- component = @field.show_component(record: @form.object, repository: @repository)
62
- assert_equal @field, component.field
63
- assert_equal @form.object, component.record
64
- assert_equal @repository, component.repository
65
- assert_kind_of Uchi::Field::HasMany::Show, component
66
- end
67
-
68
- test "#searchable? returns false when explicitly set" do
69
- field = Uchi::Field::HasMany.new(:titles).searchable(false)
70
- assert_not field.searchable?
71
- end
72
-
73
- test "#sortable? returns false when explicitly set" do
74
- field = Uchi::Field::HasMany.new(:titles).sortable(false)
75
- assert_not field.sortable?
76
- end
77
- end
78
-
79
- class HasManyEditTest < ViewComponent::TestCase
80
- def setup
81
- @field = Uchi::Field::HasMany.new(:titles)
82
- @book = Book.new(original_title: "The Hobbit")
83
- @repository = Uchi::Repositories::Book.new
84
- @view_context = ActionController::Base.new.view_context
85
-
86
- @form = ActionView::Helpers::FormBuilder.new(:book, @book, @view_context, {})
87
-
88
- @component = Uchi::Field::HasMany::Edit.new(
89
- field: @field,
90
- form: @form,
91
- hint: "Custom hint",
92
- label: "Custom label",
93
- repository: @repository
94
- )
95
- end
96
-
97
- test "inherits from Base component" do
98
- assert_kind_of Uchi::Field::Base::Edit, @component
99
- end
100
- end
101
-
102
- class HasManyIndexTest < ViewComponent::TestCase
103
- def setup
104
- @field = Uchi::Field::HasMany.new(:titles)
105
- @book = Book.new(original_title: "The Hobbit")
106
- @repository = Uchi::Repositories::Book.new
107
-
108
- @component = Uchi::Field::HasMany::Index.new(
109
- field: @field,
110
- record: @book,
111
- repository: @repository
112
- )
113
- end
114
-
115
- test "inherits from Base component" do
116
- assert_kind_of Uchi::Field::Base::Index, @component
117
- end
118
- end
119
-
120
- class HasManyShowTest < ViewComponent::TestCase
121
- def setup
122
- @field = Uchi::Field::HasMany.new(:titles)
123
- @book = Book.new(original_title: "The Hobbit")
124
- @repository = Uchi::Repositories::Book.new
125
-
126
- @component = Uchi::Field::HasMany::Show.new(
127
- field: @field,
128
- record: @book,
129
- repository: @repository
130
- )
131
- end
132
-
133
- test "inherits from Base component" do
134
- assert_kind_of Uchi::Field::Base::Show, @component
135
- end
136
- end
137
- end
138
- end
@@ -1,113 +0,0 @@
1
- require "test_helper"
2
- require "ostruct"
3
-
4
- module Uchi
5
- class Field
6
- class IdTest < ActiveSupport::TestCase
7
- def setup
8
- @field = Uchi::Field::Id.new(:id)
9
- @form = OpenStruct.new(object: OpenStruct.new(id: 123))
10
- @repository = Uchi::Repositories::Author.new
11
- end
12
-
13
- test "inherits from Uchi::Field::Number" do
14
- assert_kind_of Uchi::Field::Number, @field
15
- assert_kind_of Uchi::Field, @field
16
- end
17
-
18
- test "has default options specific to Id field" do
19
- assert_equal [:index, :show], @field.on # Different from other fields
20
- assert @field.searchable? # Different from other fields
21
- assert @field.sortable?
22
- end
23
-
24
- test "does not have edit_component because not in :edit on list" do
25
- # Since Id field defaults to [:index, :show], it doesn't include :edit
26
- # But we can still create the component if needed
27
- assert_nothing_raised do
28
- @field.edit_component(form: @form, hint: "Custom hint", label: "Custom label", repository: @repository)
29
- end
30
- end
31
-
32
- test "#index_component returns an instance of Index component" do
33
- component = @field.index_component(record: @form.object, repository: @repository)
34
- assert_equal @field, component.field
35
- assert_equal @form.object, component.record
36
- assert_equal @repository, component.repository
37
- assert_kind_of Uchi::Field::Id::Index, component
38
- end
39
-
40
- test "#searchable? returns true by default for Id field" do
41
- assert @field.searchable?
42
- end
43
-
44
- test "#searchable? returns false when explicitly set" do
45
- field = Uchi::Field::Id.new(:id).searchable(false)
46
- assert_not field.searchable?
47
- end
48
-
49
- test "#show_component returns an instance of Show component" do
50
- component = @field.show_component(record: @form.object, repository: @repository)
51
- assert_equal @field, component.field
52
- assert_equal @form.object, component.record
53
- assert_equal @repository, component.repository
54
- assert_kind_of Uchi::Field::Id::Show, component
55
- end
56
-
57
- test "#sortable? returns false when explicitly set" do
58
- field = Uchi::Field::Id.new(:id).sortable(false)
59
- assert_not field.sortable?
60
- end
61
- end
62
-
63
- class IdIndexTest < ViewComponent::TestCase
64
- def setup
65
- @field = Uchi::Field::Id.new(:id)
66
- @record = Author.new(name: "Test Author")
67
- @record.define_singleton_method(:id) { 123 }
68
- @repository = Uchi::Repositories::Author.new
69
-
70
- @component = Uchi::Field::Id::Index.new(
71
- field: @field,
72
- record: @record,
73
- repository: @repository
74
- )
75
- end
76
-
77
- test "inherits from Base component" do
78
- assert_kind_of Uchi::Field::Base::Index, @component
79
- end
80
-
81
- test "renders the field content" do
82
- result = render_inline(@component)
83
-
84
- assert_includes result.to_html, "123"
85
- end
86
- end
87
-
88
- class IdShowTest < ViewComponent::TestCase
89
- def setup
90
- @field = Uchi::Field::Id.new(:id)
91
- @record = Author.new(name: "Test Author")
92
- @record.define_singleton_method(:id) { 123 }
93
- @repository = Uchi::Repositories::Author.new
94
-
95
- @component = Uchi::Field::Id::Show.new(
96
- field: @field,
97
- record: @record,
98
- repository: @repository
99
- )
100
- end
101
-
102
- test "inherits from Base component" do
103
- assert_kind_of Uchi::Field::Base::Show, @component
104
- end
105
-
106
- test "renders the field content" do
107
- result = render_inline(@component)
108
-
109
- assert_includes result.to_html, "123"
110
- end
111
- end
112
- end
113
- end