uchi 0.1.0 → 0.1.2
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.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/build.yml +23 -0
- data/.github/workflows/lint.yml +30 -0
- data/package.json +31 -0
- data/test/components/uchi/field/belongs_to_test.rb +134 -0
- data/test/components/uchi/field/blank_test.rb +119 -0
- data/test/components/uchi/field/boolean_test.rb +163 -0
- data/test/components/uchi/field/date_test.rb +163 -0
- data/test/components/uchi/field/date_time_test.rb +152 -0
- data/test/components/uchi/field/has_many_test.rb +138 -0
- data/test/components/uchi/field/id_test.rb +113 -0
- data/test/components/uchi/field/number_test.rb +163 -0
- data/test/components/uchi/field/string_test.rb +159 -0
- data/test/controllers/uchi/authors_controller_test.rb +119 -0
- data/test/controllers/uchi/repository_controller_test.rb +93 -0
- data/test/controllers/uchi/scoped_repository_controller_test.rb +73 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +4 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/controllers/uchi/authors_controller.rb +7 -0
- data/test/dummy/app/controllers/uchi/books_controller.rb +7 -0
- data/test/dummy/app/controllers/uchi/titles_controller.rb +7 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +7 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/application_record.rb +3 -0
- data/test/dummy/app/models/author.rb +3 -0
- data/test/dummy/app/models/book.rb +3 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/models/title.rb +3 -0
- data/test/dummy/app/uchi/repositories/author.rb +20 -0
- data/test/dummy/app/uchi/repositories/book.rb +16 -0
- data/test/dummy/app/uchi/repositories/title.rb +17 -0
- data/test/dummy/app/views/layouts/application.html.erb +27 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/app/views/pwa/manifest.json.erb +22 -0
- data/test/dummy/app/views/pwa/service-worker.js +26 -0
- data/test/dummy/bin/dev +2 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +34 -0
- data/test/dummy/config/application.rb +29 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +10 -0
- data/test/dummy/config/database.yml +32 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +69 -0
- data/test/dummy/config/environments/production.rb +89 -0
- data/test/dummy/config/environments/test.rb +53 -0
- data/test/dummy/config/initializers/content_security_policy.rb +25 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +8 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/locales/da.yml +51 -0
- data/test/dummy/config/locales/en.yml +31 -0
- data/test/dummy/config/puma.rb +38 -0
- data/test/dummy/config/routes.rb +9 -0
- data/test/dummy/config/storage.yml +34 -0
- data/test/dummy/config.ru +6 -0
- data/test/dummy/db/migrate/20251002183635_create_authors.rb +11 -0
- data/test/dummy/db/migrate/20251005131726_create_books.rb +9 -0
- data/test/dummy/db/migrate/20251005131811_create_titles.rb +11 -0
- data/test/dummy/db/schema.rb +38 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/400.html +114 -0
- data/test/dummy/public/404.html +114 -0
- data/test/dummy/public/406-unsupported-browser.html +114 -0
- data/test/dummy/public/422.html +114 -0
- data/test/dummy/public/500.html +114 -0
- data/test/dummy/public/icon.png +0 -0
- data/test/dummy/public/icon.svg +3 -0
- data/test/dummy/storage/.keep +0 -0
- data/test/dummy/test/fixtures/authors.yml +11 -0
- data/test/dummy/test/models/author_test.rb +7 -0
- data/test/dummy/tmp/.keep +0 -0
- data/test/dummy/tmp/pids/.keep +0 -0
- data/test/dummy/tmp/storage/.keep +0 -0
- data/test/test_helper.rb +15 -0
- data/test/uchi/field_test.rb +63 -0
- data/test/uchi/i18n_test.rb +18 -0
- data/test/uchi/repository/routes_test.rb +49 -0
- data/test/uchi/repository/translate_test.rb +263 -0
- data/test/uchi/repository_test.rb +137 -0
- data/test/uchi/sort_order_test.rb +47 -0
- data/test/uchi_test.rb +7 -0
- metadata +146 -7
- data/README.md +0 -35
- data/Rakefile +0 -6
- data/lib/uchi/version.rb +0 -5
- data/lib/uchi.rb +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d88ecc3805c99b55a1fa5cc94817732f98378328a34be0dfb429bc99072af17
|
|
4
|
+
data.tar.gz: b56d6050c427211cf45202b60c7d24c5772aabad1242f6cd7a026b25db396142
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 023fb2f1a38c05cd69a4d2f5e6655e7900afb0160dd8972250212dc9503eacdf228cff5e08be6541444108e0aec235e9ec903a43f901f9022287dc81de17acea
|
|
7
|
+
data.tar.gz: e9d190e66e174e78883a423880dfef26bd53c3f753e3d6c6fc66c979b79ae59a7a9e05d94db48d50d01c9fdcb3dd44c0f91c852c876db6e6670252df4ab34cda
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
+
# package ecosystems to update and where the package manifests are located.
|
|
3
|
+
# Please see the documentation for all configuration options:
|
|
4
|
+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
5
|
+
|
|
6
|
+
version: 2
|
|
7
|
+
updates:
|
|
8
|
+
- package-ecosystem: "bundler"
|
|
9
|
+
directory: "/"
|
|
10
|
+
schedule:
|
|
11
|
+
interval: "weekly"
|
|
12
|
+
|
|
13
|
+
- package-ecosystem: "npm"
|
|
14
|
+
directory: "/"
|
|
15
|
+
schedule:
|
|
16
|
+
interval: "weekly"
|
|
17
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: "Build"
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [ "main" ]
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [ "main" ]
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
env:
|
|
11
|
+
RAILS_ENV: test
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout code
|
|
14
|
+
uses: actions/checkout@v5
|
|
15
|
+
- name: Install Ruby and gems
|
|
16
|
+
uses: ruby/setup-ruby@v1
|
|
17
|
+
with:
|
|
18
|
+
bundler-cache: true
|
|
19
|
+
ruby-version: '3.4.5'
|
|
20
|
+
- name: Set up database schema
|
|
21
|
+
run: bundle exec rake app:db:schema:load
|
|
22
|
+
- name: Run tests
|
|
23
|
+
run: bundle exec rake app:test
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: "Lint"
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches: [ "main" ]
|
|
5
|
+
pull_request:
|
|
6
|
+
branches: [ "main" ]
|
|
7
|
+
jobs:
|
|
8
|
+
erb:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout code
|
|
12
|
+
uses: actions/checkout@v5
|
|
13
|
+
- name: Install Node
|
|
14
|
+
uses: actions/setup-node@v5
|
|
15
|
+
- name: Install dependencies
|
|
16
|
+
run: npm install
|
|
17
|
+
- name: Herb
|
|
18
|
+
run: npm run herb:lint
|
|
19
|
+
ruby:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout code
|
|
23
|
+
uses: actions/checkout@v5
|
|
24
|
+
- name: Install Ruby and gems
|
|
25
|
+
uses: ruby/setup-ruby@v1
|
|
26
|
+
with:
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
ruby-version: '3.4.5'
|
|
29
|
+
- name: Standard
|
|
30
|
+
run: bundle exec rake standard
|
data/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "uchi",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "## Installation",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"directories": {
|
|
7
|
+
"lib": "lib",
|
|
8
|
+
"test": "test"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"assets:build": "npm run build:css && npm run build:js",
|
|
12
|
+
"build:css": "node_modules/.bin/tailwindcss -i ./app/assets/tailwind/uchi.css -o ./app/assets/stylesheets/uchi/application.css",
|
|
13
|
+
"build:js": "node_modules/.bin/esbuild --bundle --outfile=app/assets/javascripts/uchi/application.js app/assets/javascripts/uchi.js",
|
|
14
|
+
"herb:lint": "herb-lint '**/*.html.erb'",
|
|
15
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
16
|
+
"watch:css": "node_modules/.bin/tailwindcss --watch -i ./app/assets/tailwind/uchi.css -o ./app/assets/stylesheets/uchi/application.css",
|
|
17
|
+
"watch:js": "node_modules/.bin/esbuild --watch --bundle --outfile=app/assets/javascripts/uchi/application.js app/assets/javascripts/uchi.js"
|
|
18
|
+
},
|
|
19
|
+
"author": "",
|
|
20
|
+
"license": "ISC",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@hotwired/turbo-rails": "^8.0.16",
|
|
23
|
+
"@tailwindcss/cli": "^4.1.13",
|
|
24
|
+
"flowbite": "^3.1.2",
|
|
25
|
+
"tailwindcss": "^4.1.13"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@herb-tools/linter": "^0.7.4",
|
|
29
|
+
"esbuild": "0.25.11"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "ostruct"
|
|
3
|
+
|
|
4
|
+
module Uchi
|
|
5
|
+
class Field
|
|
6
|
+
class BelongsToTest < ActiveSupport::TestCase
|
|
7
|
+
def setup
|
|
8
|
+
@field = Uchi::Field::BelongsTo.new(:book)
|
|
9
|
+
@form = OpenStruct.new(object: Title.new)
|
|
10
|
+
@repository = Uchi::Repositories::Title.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 "has custom collection_query" do
|
|
24
|
+
custom_query = ->(query) { query.where(active: true) }
|
|
25
|
+
field = Uchi::Field::BelongsTo.new(:book, 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::BelongsTo::DEFAULT_COLLECTION_QUERY, @field.collection_query
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test "#param_key returns foreign key name" do
|
|
34
|
+
assert_equal :book_id, @field.param_key
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test "#edit_component returns an instance of Edit component" do
|
|
38
|
+
component = @field.edit_component(form: @form, hint: "Custom hint", label: "Custom label", repository: @repository)
|
|
39
|
+
assert_equal "Custom hint", component.hint
|
|
40
|
+
assert_equal "Custom label", component.label
|
|
41
|
+
assert_equal @field, component.field
|
|
42
|
+
assert_equal @form, component.form
|
|
43
|
+
assert_equal @repository, component.repository
|
|
44
|
+
assert_kind_of Uchi::Field::BelongsTo::Edit, component
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
test "#group_as returns :attributes for :edit" do
|
|
48
|
+
assert_equal :attributes, @field.group_as(:edit)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
test "#group_as returns :attributes for :show" do
|
|
52
|
+
assert_equal :attributes, @field.group_as(:show)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
test "#index_component returns an instance of Index component" do
|
|
56
|
+
component = @field.index_component(record: @form.object, repository: @repository)
|
|
57
|
+
assert_equal @field, component.field
|
|
58
|
+
assert_equal @form.object, component.record
|
|
59
|
+
assert_equal @repository, component.repository
|
|
60
|
+
assert_kind_of Uchi::Field::BelongsTo::Index, component
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
test "#searchable? returns false when explicitly set" do
|
|
64
|
+
field = Uchi::Field::BelongsTo.new(:book, searchable: false)
|
|
65
|
+
assert_not field.searchable?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
test "#show_component returns an instance of Show component" do
|
|
69
|
+
component = @field.show_component(record: @form.object, repository: @repository)
|
|
70
|
+
assert_equal @field, component.field
|
|
71
|
+
assert_equal @form.object, component.record
|
|
72
|
+
assert_equal @repository, component.repository
|
|
73
|
+
assert_kind_of Uchi::Field::BelongsTo::Show, component
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
test "#sortable? returns false when explicitly set" do
|
|
77
|
+
field = Uchi::Field::BelongsTo.new(:book, sortable: false)
|
|
78
|
+
assert_not field.sortable?
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class BelongsToIndexTest < ViewComponent::TestCase
|
|
83
|
+
def setup
|
|
84
|
+
@book = Book.create!(original_title: "The Hobbit")
|
|
85
|
+
@title = Title.new(book: @book, locale: "da-DK", title: "Hobbitten")
|
|
86
|
+
@field = Uchi::Field::BelongsTo.new(:book)
|
|
87
|
+
@repository = Uchi::Repositories::Title.new
|
|
88
|
+
|
|
89
|
+
@component = Uchi::Field::BelongsTo::Index.new(
|
|
90
|
+
field: @field,
|
|
91
|
+
record: @title,
|
|
92
|
+
repository: @repository
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
test "inherits from Base component" do
|
|
97
|
+
assert_kind_of Uchi::Field::Base::Index, @component
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
test "renders the field content" do
|
|
101
|
+
result = render_inline(@component)
|
|
102
|
+
|
|
103
|
+
# The component renders the object directly, so we check for the object representation
|
|
104
|
+
assert_not_nil result.to_html
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
class BelongsToShowTest < ViewComponent::TestCase
|
|
109
|
+
def setup
|
|
110
|
+
@book = Book.create!(original_title: "The Hobbit")
|
|
111
|
+
@field = Uchi::Field::BelongsTo.new(:book)
|
|
112
|
+
@record = Title.new(book: @book, locale: "da-DK", title: "Hobbitten")
|
|
113
|
+
@repository = Uchi::Repositories::Title.new
|
|
114
|
+
|
|
115
|
+
@component = Uchi::Field::BelongsTo::Show.new(
|
|
116
|
+
field: @field,
|
|
117
|
+
record: @record,
|
|
118
|
+
repository: @repository
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
test "inherits from Base component" do
|
|
123
|
+
assert_kind_of Uchi::Field::Base::Show, @component
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
test "can be rendered without errors" do
|
|
127
|
+
# Skip rendering test due to missing route dependencies
|
|
128
|
+
assert_nothing_raised do
|
|
129
|
+
@component
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "ostruct"
|
|
3
|
+
|
|
4
|
+
module Uchi
|
|
5
|
+
class Field
|
|
6
|
+
class BlankTest < ActiveSupport::TestCase
|
|
7
|
+
def setup
|
|
8
|
+
@field = Uchi::Field::Blank.new(:separator)
|
|
9
|
+
@form = OpenStruct.new(object: OpenStruct.new(separator: nil))
|
|
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::Blank::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::Blank::Index, component
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test "#searchable? returns false when explicitly set" do
|
|
42
|
+
field = Uchi::Field::Blank.new(:separator, 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::Blank::Show, component
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test "#sortable? returns false when explicitly set" do
|
|
55
|
+
field = Uchi::Field::Blank.new(:separator, sortable: false)
|
|
56
|
+
assert_not field.sortable?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class BlankEditTest < ViewComponent::TestCase
|
|
61
|
+
def setup
|
|
62
|
+
@field = Uchi::Field::Blank.new(:separator)
|
|
63
|
+
@record = Author.new(name: "Test Author")
|
|
64
|
+
@repository = Uchi::Repositories::Author.new
|
|
65
|
+
@view_context = ActionController::Base.new.view_context
|
|
66
|
+
|
|
67
|
+
@form = ActionView::Helpers::FormBuilder.new(:author, @record, @view_context, {})
|
|
68
|
+
|
|
69
|
+
@component = Uchi::Field::Blank::Edit.new(
|
|
70
|
+
field: @field,
|
|
71
|
+
form: @form,
|
|
72
|
+
hint: "Custom hint",
|
|
73
|
+
label: "Custom label",
|
|
74
|
+
repository: @repository
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
test "inherits from Base component" do
|
|
79
|
+
assert_kind_of Uchi::Field::Base::Edit, @component
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class BlankIndexTest < ViewComponent::TestCase
|
|
84
|
+
def setup
|
|
85
|
+
@field = Uchi::Field::Blank.new(:separator)
|
|
86
|
+
@record = Author.new(name: "Test Author")
|
|
87
|
+
@repository = Uchi::Repositories::Author.new
|
|
88
|
+
|
|
89
|
+
@component = Uchi::Field::Blank::Index.new(
|
|
90
|
+
field: @field,
|
|
91
|
+
record: @record,
|
|
92
|
+
repository: @repository
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
test "inherits from Base component" do
|
|
97
|
+
assert_kind_of Uchi::Field::Base::Index, @component
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
class BlankShowTest < ViewComponent::TestCase
|
|
102
|
+
def setup
|
|
103
|
+
@field = Uchi::Field::Blank.new(:separator)
|
|
104
|
+
@record = Author.new(name: "Test Author")
|
|
105
|
+
@repository = Uchi::Repositories::Author.new
|
|
106
|
+
|
|
107
|
+
@component = Uchi::Field::Blank::Show.new(
|
|
108
|
+
field: @field,
|
|
109
|
+
record: @record,
|
|
110
|
+
repository: @repository
|
|
111
|
+
)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
test "inherits from Base component" do
|
|
115
|
+
assert_kind_of Uchi::Field::Base::Show, @component
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "ostruct"
|
|
3
|
+
|
|
4
|
+
module Uchi
|
|
5
|
+
class Field
|
|
6
|
+
class BooleanTest < ActiveSupport::TestCase
|
|
7
|
+
def setup
|
|
8
|
+
@field = Uchi::Field::Boolean.new(:active)
|
|
9
|
+
@form = OpenStruct.new(object: OpenStruct.new(active: true))
|
|
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::Boolean::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::Boolean::Index, component
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test "#searchable? returns false when explicitly set" do
|
|
42
|
+
field = Uchi::Field::Boolean.new(:active, 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::Boolean::Show, component
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test "#sortable? returns false when explicitly set" do
|
|
55
|
+
field = Uchi::Field::Boolean.new(:active, sortable: false)
|
|
56
|
+
assert_not field.sortable?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class BooleanEditTest < ViewComponent::TestCase
|
|
61
|
+
def setup
|
|
62
|
+
@field = Uchi::Field::Boolean.new(:active)
|
|
63
|
+
@record = Author.new(name: "Test Author")
|
|
64
|
+
@record.define_singleton_method(:active) { true }
|
|
65
|
+
@record.define_singleton_method(:active=) { |val| @active = 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::Boolean::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 "renders a checkbox field with the field content" do
|
|
85
|
+
render_inline(@component)
|
|
86
|
+
|
|
87
|
+
assert_selector("input[type='checkbox'][name='author[active]']")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
test "renders label with specified text" do
|
|
91
|
+
render_inline(@component)
|
|
92
|
+
|
|
93
|
+
assert_selector("label", text: "Custom label")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
test "renders hint when provided" do
|
|
97
|
+
render_inline(@component)
|
|
98
|
+
|
|
99
|
+
assert_selector("p", text: "Custom hint")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
test "initializes the input component with the correct options" do
|
|
103
|
+
expected_options = {
|
|
104
|
+
attribute: :active,
|
|
105
|
+
form: @form,
|
|
106
|
+
label: {content: "Custom label"},
|
|
107
|
+
hint: {content: "Custom hint"}
|
|
108
|
+
}
|
|
109
|
+
assert_equal expected_options, @component.send(:options)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class BooleanIndexTest < ViewComponent::TestCase
|
|
114
|
+
def setup
|
|
115
|
+
@field = Uchi::Field::Boolean.new(:active)
|
|
116
|
+
@record = Author.new(name: "Test Author")
|
|
117
|
+
@record.define_singleton_method(:active) { true }
|
|
118
|
+
@repository = Uchi::Repositories::Author.new
|
|
119
|
+
|
|
120
|
+
@component = Uchi::Field::Boolean::Index.new(
|
|
121
|
+
field: @field,
|
|
122
|
+
record: @record,
|
|
123
|
+
repository: @repository
|
|
124
|
+
)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
test "inherits from Base component" do
|
|
128
|
+
assert_kind_of Uchi::Field::Base::Index, @component
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
test "renders the field content" do
|
|
132
|
+
result = render_inline(@component)
|
|
133
|
+
|
|
134
|
+
assert_includes result.to_html, "true"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class BooleanShowTest < ViewComponent::TestCase
|
|
139
|
+
def setup
|
|
140
|
+
@field = Uchi::Field::Boolean.new(:active)
|
|
141
|
+
@record = Author.new(name: "Test Author")
|
|
142
|
+
@record.define_singleton_method(:active) { true }
|
|
143
|
+
@repository = Uchi::Repositories::Author.new
|
|
144
|
+
|
|
145
|
+
@component = Uchi::Field::Boolean::Show.new(
|
|
146
|
+
field: @field,
|
|
147
|
+
record: @record,
|
|
148
|
+
repository: @repository
|
|
149
|
+
)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
test "inherits from Base component" do
|
|
153
|
+
assert_kind_of Uchi::Field::Base::Show, @component
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
test "renders the field content" do
|
|
157
|
+
result = render_inline(@component)
|
|
158
|
+
|
|
159
|
+
assert_includes result.to_html, "true"
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
require "ostruct"
|
|
3
|
+
|
|
4
|
+
module Uchi
|
|
5
|
+
class Field
|
|
6
|
+
class DateTest < ActiveSupport::TestCase
|
|
7
|
+
def setup
|
|
8
|
+
@field = Uchi::Field::Date.new(:born_on)
|
|
9
|
+
@form = OpenStruct.new(object: OpenStruct.new(born_on: ::Date.new(1990, 1, 1)))
|
|
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::Date::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::Date::Index, component
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test "#searchable? returns false when explicitly set" do
|
|
42
|
+
field = Uchi::Field::Date.new(:born_on, 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::Date::Show, component
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test "#sortable? returns false when explicitly set" do
|
|
55
|
+
field = Uchi::Field::Date.new(:born_on, sortable: false)
|
|
56
|
+
assert_not field.sortable?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class DateEditTest < ViewComponent::TestCase
|
|
61
|
+
def setup
|
|
62
|
+
@field = Uchi::Field::Date.new(:born_on)
|
|
63
|
+
@record = Author.new(name: "Test Author")
|
|
64
|
+
@record.define_singleton_method(:born_on) { ::Date.new(1990, 1, 1) }
|
|
65
|
+
@record.define_singleton_method(:born_on=) { |val| @born_on = 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::Date::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 "renders a date input field" do
|
|
85
|
+
render_inline(@component)
|
|
86
|
+
|
|
87
|
+
assert_selector("input[name='author[born_on]']")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
test "renders label with specified text" do
|
|
91
|
+
render_inline(@component)
|
|
92
|
+
|
|
93
|
+
assert_selector("label", text: "Custom label")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
test "renders hint when provided" do
|
|
97
|
+
render_inline(@component)
|
|
98
|
+
|
|
99
|
+
assert_selector("p", text: "Custom hint")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
test "initializes the input component with the correct options" do
|
|
103
|
+
expected_options = {
|
|
104
|
+
attribute: :born_on,
|
|
105
|
+
form: @form,
|
|
106
|
+
label: {content: "Custom label"},
|
|
107
|
+
hint: {content: "Custom hint"}
|
|
108
|
+
}
|
|
109
|
+
assert_equal expected_options, @component.send(:options)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class DateIndexTest < ViewComponent::TestCase
|
|
114
|
+
def setup
|
|
115
|
+
@field = Uchi::Field::Date.new(:born_on)
|
|
116
|
+
@record = Author.new(name: "Test Author")
|
|
117
|
+
@record.define_singleton_method(:born_on) { ::Date.new(1990, 1, 1) }
|
|
118
|
+
@repository = Uchi::Repositories::Author.new
|
|
119
|
+
|
|
120
|
+
@component = Uchi::Field::Date::Index.new(
|
|
121
|
+
field: @field,
|
|
122
|
+
record: @record,
|
|
123
|
+
repository: @repository
|
|
124
|
+
)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
test "inherits from Base component" do
|
|
128
|
+
assert_kind_of Uchi::Field::Base::Index, @component
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
test "renders the field content" do
|
|
132
|
+
result = render_inline(@component)
|
|
133
|
+
|
|
134
|
+
assert_includes result.to_html, "1990-01-01"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class DateShowTest < ViewComponent::TestCase
|
|
139
|
+
def setup
|
|
140
|
+
@field = Uchi::Field::Date.new(:born_on)
|
|
141
|
+
@record = Author.new(name: "Test Author")
|
|
142
|
+
@record.define_singleton_method(:born_on) { ::Date.new(1990, 1, 1) }
|
|
143
|
+
@repository = Uchi::Repositories::Author.new
|
|
144
|
+
|
|
145
|
+
@component = Uchi::Field::Date::Show.new(
|
|
146
|
+
field: @field,
|
|
147
|
+
record: @record,
|
|
148
|
+
repository: @repository
|
|
149
|
+
)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
test "inherits from Base component" do
|
|
153
|
+
assert_kind_of Uchi::Field::Base::Show, @component
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
test "renders the field content" do
|
|
157
|
+
result = render_inline(@component)
|
|
158
|
+
|
|
159
|
+
assert_includes result.to_html, "1990-01-01"
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|