bootstrap_form 4.4.0 → 5.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +48 -0
- data/.gitignore +28 -3
- data/.rubocop.yml +19 -15
- data/CHANGELOG.md +82 -1
- data/CONTRIBUTING.md +73 -12
- data/Dangerfile +5 -7
- data/Dockerfile +21 -0
- data/Gemfile +8 -11
- data/README.md +829 -82
- data/RELEASING.md +5 -10
- data/UPGRADE-4.0.md +1 -1
- data/UPGRADE-5.0.md +25 -0
- data/bootstrap_form.gemspec +8 -5
- data/demo/.ruby-version +1 -0
- data/demo/Gemfile +80 -0
- data/demo/Gemfile.lock +261 -0
- data/demo/Procfile.dev +2 -0
- data/demo/app/assets/builds/.keep +0 -0
- data/demo/app/assets/builds/application.js.LICENSE.txt +9 -0
- data/demo/app/assets/config/manifest.js +2 -2
- data/demo/app/assets/stylesheets/actiontext.css +31 -0
- data/demo/app/assets/stylesheets/application.scss +1 -1
- data/demo/app/controllers/bootstrap_controller.rb +17 -2
- data/demo/app/controllers/users_controller.rb +9 -0
- data/demo/app/helpers/bootstrap_helper.rb +5 -5
- data/demo/app/javascript/application.js +3 -0
- data/demo/app/models/skill.rb +15 -0
- data/demo/app/models/user.rb +14 -0
- data/demo/app/views/active_storage/blobs/_blob.html.erb +1 -1
- data/demo/app/views/bootstrap/form.html.erb +13 -0
- data/demo/app/views/layouts/action_text/contents/_content.html.erb +3 -0
- data/demo/app/views/layouts/application.html.erb +28 -20
- data/demo/bin/dev +9 -0
- data/demo/config/environments/development.rb +3 -3
- data/demo/config/puma.rb +2 -2
- data/demo/config/routes.rb +1 -0
- data/demo/db/schema.rb +31 -16
- data/demo/doc/screenshots/bootstrap/index/00_horizontal_form.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/01_with_validation_error.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/02_inline_form.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/03_simple_action_text_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/index/04_floating_labels.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/00_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/01_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/02_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/03_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/04_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/05_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/06_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/07_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/08_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/09_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/10_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/11_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/12_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/13_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/14_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/15_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/16_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/17_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/18_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/19_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/20_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/21_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/22_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/23_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/24_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/25_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/26_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/27_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/28_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/29_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/30_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/31_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/32_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/33_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/34_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/35_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/36_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/37_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/38_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/39_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/40_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/41_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/42_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/43_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/44_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/45_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/46_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/47_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/48_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/49_example.png +0 -0
- data/demo/doc/screenshots/bootstrap/readme/50_example.png +0 -0
- data/demo/package.json +10 -6
- data/demo/test/application_system_test_case.rb +8 -0
- data/demo/test/controllers/bootstrap_controller_test.rb +8 -0
- data/demo/test/controllers/users_controller_test.rb +13 -0
- data/demo/test/fixtures/users.yml +2 -0
- data/demo/test/system/bootstrap_test.rb +84 -0
- data/demo/test/test_helper.rb +10 -0
- data/demo/webpack.config.js +20 -0
- data/demo/yarn.lock +4063 -3144
- data/docker-compose.yml +49 -0
- data/gemfiles/5.2.gemfile +2 -15
- data/gemfiles/6.0.gemfile +2 -17
- data/gemfiles/6.1.gemfile +4 -0
- data/gemfiles/7.0.gemfile +6 -0
- data/gemfiles/edge.gemfile +2 -17
- data/lib/bootstrap_form/action_view_extensions/form_helper.rb +1 -1
- data/lib/bootstrap_form/components/hints.rb +13 -4
- data/lib/bootstrap_form/components/labels.rb +2 -2
- data/lib/bootstrap_form/components/validation.rb +1 -1
- data/lib/bootstrap_form/configuration.rb +22 -0
- data/lib/bootstrap_form/form_builder.rb +10 -12
- data/lib/bootstrap_form/form_group.rb +26 -11
- data/lib/bootstrap_form/form_group_builder.rb +6 -8
- data/lib/bootstrap_form/helpers/bootstrap.rb +17 -12
- data/lib/bootstrap_form/inputs/base.rb +5 -5
- data/lib/bootstrap_form/inputs/check_box.rb +11 -23
- data/lib/bootstrap_form/inputs/collection_check_boxes.rb +5 -1
- data/lib/bootstrap_form/inputs/collection_select.rb +2 -1
- data/lib/bootstrap_form/inputs/file_field.rb +3 -15
- data/lib/bootstrap_form/inputs/grouped_collection_select.rb +2 -1
- data/lib/bootstrap_form/inputs/radio_button.rb +17 -30
- data/lib/bootstrap_form/inputs/select.rb +1 -0
- data/lib/bootstrap_form/inputs/time_zone_select.rb +1 -0
- data/lib/bootstrap_form/version.rb +1 -1
- data/lib/bootstrap_form.rb +17 -7
- metadata +94 -16
- data/.travis.yml +0 -42
- data/demo/config/initializers/assets.rb +0 -14
- data/gemfiles/5.0.gemfile +0 -18
- data/gemfiles/5.1.gemfile +0 -17
@@ -6,12 +6,12 @@
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
7
7
|
|
8
8
|
<!-- Bootstrap CSS -->
|
9
|
-
|
10
|
-
|
9
|
+
<!-- CSS only -->
|
10
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
|
11
11
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.33.0/codemirror.min.css">
|
12
12
|
|
13
13
|
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
|
14
|
-
<%=
|
14
|
+
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload', defer: true %>
|
15
15
|
|
16
16
|
<style type="text/css">
|
17
17
|
.example {
|
@@ -19,8 +19,11 @@
|
|
19
19
|
border: .2rem solid #f7f7f9;
|
20
20
|
margin-bottom: 3em;
|
21
21
|
}
|
22
|
-
|
23
|
-
margin-
|
22
|
+
.toggle {
|
23
|
+
margin-top: 1.5em;
|
24
|
+
}
|
25
|
+
.code {
|
26
|
+
margin-top: 1rem;
|
24
27
|
}
|
25
28
|
.CodeMirror {
|
26
29
|
border: 1px solid #eee;
|
@@ -34,6 +37,7 @@
|
|
34
37
|
|
35
38
|
<title>Hello, world!</title>
|
36
39
|
<%= csrf_meta_tags %>
|
40
|
+
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
|
37
41
|
</head>
|
38
42
|
|
39
43
|
<body>
|
@@ -42,26 +46,30 @@
|
|
42
46
|
</div>
|
43
47
|
|
44
48
|
<!-- Optional JavaScript -->
|
45
|
-
<!--
|
46
|
-
<script src="https://
|
47
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
|
48
|
-
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
|
49
|
-
|
49
|
+
<!-- JavaScript Bundle with Popper -->
|
50
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
|
50
51
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.33.0/codemirror.min.js"></script>
|
51
52
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.33.0/mode/htmlmixed/htmlmixed.min.js"></script>
|
52
53
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.33.0/mode/xml/xml.min.js"></script>
|
53
54
|
|
54
55
|
<script type="text/javascript">
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
56
|
+
const buttons = document.querySelectorAll('button.toggle');
|
57
|
+
const buttonsArray = Array.prototype.slice.call(buttons);
|
58
|
+
buttonsArray.forEach(function(elem) {
|
59
|
+
elem.addEventListener('click', function() {
|
60
|
+
const example = this.closest('.example');
|
61
|
+
if (example.querySelector('.code').style.display === "block") {
|
62
|
+
example.querySelector('.code').style.display = "none";
|
63
|
+
} else {
|
64
|
+
example.querySelector('.code').style.display = "block";
|
65
|
+
}
|
66
|
+
CodeMirror.fromTextArea(example.querySelector('textarea.codemirror'), {
|
67
|
+
mode: 'htmlmixed',
|
68
|
+
tabSize: 2,
|
69
|
+
lineNumbers: true,
|
70
|
+
viewportMargin: Infinity,
|
71
|
+
});
|
72
|
+
});
|
65
73
|
});
|
66
74
|
</script>
|
67
75
|
</body>
|
data/demo/bin/dev
ADDED
@@ -1,6 +1,6 @@
|
|
1
1
|
Rails.application.configure do
|
2
2
|
# Verifies that versions and hashed value of the package contents in the project's package.json
|
3
|
-
config.webpacker.check_yarn_integrity = true
|
3
|
+
# config.webpacker.check_yarn_integrity = true
|
4
4
|
# Settings specified here will take precedence over those in config/application.rb.
|
5
5
|
|
6
6
|
# In the development environment your application's code is reloaded on
|
@@ -46,10 +46,10 @@ Rails.application.configure do
|
|
46
46
|
# Debug mode disables concatenation and preprocessing of assets.
|
47
47
|
# This option may cause significant delays in view rendering with a large
|
48
48
|
# number of complex assets.
|
49
|
-
config.assets.debug = true
|
49
|
+
# config.assets.debug = true
|
50
50
|
|
51
51
|
# Suppress logger output for asset requests.
|
52
|
-
config.assets.quiet = true
|
52
|
+
# config.assets.quiet = true
|
53
53
|
|
54
54
|
# Raises error for missing translations
|
55
55
|
# config.action_view.raise_on_missing_translations = true
|
data/demo/config/puma.rb
CHANGED
@@ -4,12 +4,12 @@
|
|
4
4
|
# the maximum value specified for Puma. Default is set to 5 threads for minimum
|
5
5
|
# and maximum; this matches the default thread size of Active Record.
|
6
6
|
#
|
7
|
-
threads_count = ENV.fetch("RAILS_MAX_THREADS"
|
7
|
+
threads_count = ENV.fetch("RAILS_MAX_THREADS", 5)
|
8
8
|
threads threads_count, threads_count
|
9
9
|
|
10
10
|
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
|
11
11
|
#
|
12
|
-
port ENV.fetch("PORT"
|
12
|
+
port ENV.fetch("PORT", 3000)
|
13
13
|
|
14
14
|
# Specifies the `environment` that Puma will run in.
|
15
15
|
#
|
data/demo/config/routes.rb
CHANGED
data/demo/db/schema.rb
CHANGED
@@ -2,32 +2,32 @@
|
|
2
2
|
# of editing this file, please use the migrations feature of Active Record to
|
3
3
|
# incrementally modify your database, and then regenerate this schema definition.
|
4
4
|
#
|
5
|
-
# This file is the source Rails uses to define your schema when running `rails
|
6
|
-
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
|
5
|
+
# This file is the source Rails uses to define your schema when running `bin/rails
|
6
|
+
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
|
7
7
|
# be faster and is potentially less error prone than running all of your
|
8
8
|
# migrations from scratch. Old migrations may fail to apply correctly if those
|
9
9
|
# migrations use external dependencies or application code.
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 2022_01_09_230956) do
|
14
14
|
|
15
15
|
create_table "action_text_rich_texts", force: :cascade do |t|
|
16
16
|
t.string "name", null: false
|
17
|
-
t.text "body"
|
17
|
+
t.text "body"
|
18
18
|
t.string "record_type", null: false
|
19
|
-
t.
|
20
|
-
t.datetime "created_at", null: false
|
21
|
-
t.datetime "updated_at", null: false
|
19
|
+
t.bigint "record_id", null: false
|
20
|
+
t.datetime "created_at", precision: 6, null: false
|
21
|
+
t.datetime "updated_at", precision: 6, null: false
|
22
22
|
t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
|
23
23
|
end
|
24
24
|
|
25
25
|
create_table "active_storage_attachments", force: :cascade do |t|
|
26
26
|
t.string "name", null: false
|
27
27
|
t.string "record_type", null: false
|
28
|
-
t.
|
29
|
-
t.
|
30
|
-
t.datetime "created_at", null: false
|
28
|
+
t.bigint "record_id", null: false
|
29
|
+
t.bigint "blob_id", null: false
|
30
|
+
t.datetime "created_at", precision: 6, null: false
|
31
31
|
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
|
32
32
|
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
|
33
33
|
end
|
@@ -37,20 +37,33 @@ ActiveRecord::Schema.define(version: 2019_01_26_192508) do
|
|
37
37
|
t.string "filename", null: false
|
38
38
|
t.string "content_type"
|
39
39
|
t.text "metadata"
|
40
|
+
t.string "service_name", null: false
|
40
41
|
t.bigint "byte_size", null: false
|
41
|
-
t.string "checksum"
|
42
|
-
t.datetime "created_at", null: false
|
42
|
+
t.string "checksum"
|
43
|
+
t.datetime "created_at", precision: 6, null: false
|
43
44
|
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
|
44
45
|
end
|
45
46
|
|
47
|
+
create_table "active_storage_variant_records", force: :cascade do |t|
|
48
|
+
t.bigint "blob_id", null: false
|
49
|
+
t.string "variation_digest", null: false
|
50
|
+
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
|
51
|
+
end
|
52
|
+
|
46
53
|
create_table "addresses", force: :cascade do |t|
|
47
54
|
t.integer "user_id"
|
48
55
|
t.string "street"
|
49
56
|
t.string "city"
|
50
57
|
t.string "state"
|
51
58
|
t.string "zip_code"
|
52
|
-
t.datetime "created_at", null: false
|
53
|
-
t.datetime "updated_at", null: false
|
59
|
+
t.datetime "created_at", precision: 6, null: false
|
60
|
+
t.datetime "updated_at", precision: 6, null: false
|
61
|
+
end
|
62
|
+
|
63
|
+
create_table "bogons", force: :cascade do |t|
|
64
|
+
t.datetime "created_at", precision: 6, null: false
|
65
|
+
t.datetime "updated_at", precision: 6, null: false
|
66
|
+
t.integer "food_waste_main"
|
54
67
|
end
|
55
68
|
|
56
69
|
create_table "users", force: :cascade do |t|
|
@@ -62,8 +75,10 @@ ActiveRecord::Schema.define(version: 2019_01_26_192508) do
|
|
62
75
|
t.text "preferences"
|
63
76
|
t.boolean "terms", default: false
|
64
77
|
t.string "type"
|
65
|
-
t.datetime "created_at", null: false
|
66
|
-
t.datetime "updated_at", null: false
|
78
|
+
t.datetime "created_at", precision: 6, null: false
|
79
|
+
t.datetime "updated_at", precision: 6, null: false
|
67
80
|
end
|
68
81
|
|
82
|
+
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
83
|
+
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
69
84
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/demo/package.json
CHANGED
@@ -2,16 +2,20 @@
|
|
2
2
|
"name": "dummy",
|
3
3
|
"private": true,
|
4
4
|
"dependencies": {
|
5
|
-
"@rails/actioncable": "^6.
|
6
|
-
"@rails/actiontext": "^6.
|
7
|
-
"@rails/activestorage": "^6.
|
8
|
-
"@rails/ujs": "^6.
|
9
|
-
"@rails/webpacker": "^
|
5
|
+
"@rails/actioncable": "^6.1.0",
|
6
|
+
"@rails/actiontext": "^6.1.0",
|
7
|
+
"@rails/activestorage": "^6.1.0",
|
8
|
+
"@rails/ujs": "^6.1.0",
|
9
|
+
"@rails/webpacker": "^5.0.0",
|
10
10
|
"trix": "^1.0.0",
|
11
11
|
"turbolinks": "^5.2.0"
|
12
12
|
},
|
13
13
|
"version": "0.1.0",
|
14
14
|
"devDependencies": {
|
15
|
-
"webpack-dev-server": "^
|
15
|
+
"webpack-dev-server": "^4.0.0"
|
16
|
+
},
|
17
|
+
"scripts": {
|
18
|
+
"build": "webpack --config webpack.config.js",
|
19
|
+
"build:css": "webpack --config webpack.config.js"
|
16
20
|
}
|
17
21
|
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
4
|
+
include Capybara::Screenshot::Diff
|
5
|
+
driven_by :selenium, using: :headless_chrome, screen_size: [960, 720] do |capabilities|
|
6
|
+
capabilities.add_argument "force-device-scale-factor=1"
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class UsersControllerTest < ActionDispatch::IntegrationTest
|
4
|
+
test "should post create" do
|
5
|
+
post users_url
|
6
|
+
assert_redirected_to root_path
|
7
|
+
end
|
8
|
+
|
9
|
+
test "should patch update" do
|
10
|
+
patch user_url(users(:one))
|
11
|
+
assert_redirected_to root_path
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "application_system_test_case"
|
2
|
+
|
3
|
+
class BootstrapTest < ApplicationSystemTestCase
|
4
|
+
setup { screenshot_section :bootstrap }
|
5
|
+
|
6
|
+
test "visiting the index" do
|
7
|
+
screenshot_group :index
|
8
|
+
visit root_url
|
9
|
+
|
10
|
+
all(".toggle").each { |btn| execute_script "arguments[0].remove()", btn }
|
11
|
+
|
12
|
+
all("h3").each do |header|
|
13
|
+
example = header.first(:xpath, "./following-sibling::div")
|
14
|
+
scroll_to example
|
15
|
+
sleep 0.5
|
16
|
+
screenshot header.text.downcase.tr(" ", "_"), crop: bounds(example), color_distance_limit: 2
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
HEADERS = ["Generated HTML", "This generates", "Which outputs", "will be rendered as"].join("|").freeze
|
21
|
+
REGEXP =
|
22
|
+
/(?:!\[[^\]]*\]\([^)]+\)\s*)?```erb\n(.*?)\n```\s*((?:#{HEADERS}).*?$)?\s*(```html\n(?:.*?)\n```\s*)?/mi
|
23
|
+
.freeze
|
24
|
+
test "readme examples" do
|
25
|
+
screenshot_group :readme
|
26
|
+
|
27
|
+
readme = File.read(File.expand_path("../../../README.md", __dir__))
|
28
|
+
augmented_readme = readme.gsub(REGEXP) do |_|
|
29
|
+
erb = Regexp.last_match(1)
|
30
|
+
header = Regexp.last_match(2)
|
31
|
+
unless /\A<%= bootstrap[^>]*>\n\s*...\s*<% end %>\z/.match? erb
|
32
|
+
wrapped_erb = erb.starts_with?("<%= bootstrap") ? erb : <<~ERB
|
33
|
+
<%= bootstrap_form_with model: @user do |f| %>
|
34
|
+
#{erb}
|
35
|
+
<% end %>
|
36
|
+
ERB
|
37
|
+
|
38
|
+
visit fragment_path erb: wrapped_erb
|
39
|
+
wrapper = find(".p-3")
|
40
|
+
i = @screenshot_counter
|
41
|
+
screenshot :example, crop: bounds(wrapper)
|
42
|
+
wrapper = wrapper.find("form") if wrapped_erb != erb
|
43
|
+
html = wrapper["innerHTML"].strip.gsub("><", ">\n<")
|
44
|
+
assert html.present?, erb
|
45
|
+
doc = Nokogiri::HTML.fragment(html)
|
46
|
+
doc.traverse do |node|
|
47
|
+
if node.is_a?(Nokogiri::XML::Element)
|
48
|
+
node.attributes.sort_by(&:first).each do |name, value|
|
49
|
+
node.delete(name)
|
50
|
+
node[name] = value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
html = doc.to_html
|
55
|
+
image = <<~MD
|
56
|
+
![Example #{i}](demo/doc/screenshots/bootstrap/readme/#{format('%02i', i)}_example.png "Example #{i}")
|
57
|
+
MD
|
58
|
+
html = <<~MD
|
59
|
+
|
60
|
+
#{header || 'Generated HTML:'}
|
61
|
+
|
62
|
+
```html
|
63
|
+
#{HtmlBeautifier.beautify(html)}
|
64
|
+
```
|
65
|
+
MD
|
66
|
+
end
|
67
|
+
<<~MD
|
68
|
+
#{image}```erb
|
69
|
+
#{erb}
|
70
|
+
```
|
71
|
+
#{html}
|
72
|
+
MD
|
73
|
+
end
|
74
|
+
augmented_readme.gsub!(/127.0.0.1:\d+/, "test.host")
|
75
|
+
File.write(File.expand_path("../../../README.md", __dir__), augmented_readme)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def bounds(node)
|
81
|
+
client_rect = evaluate_script("arguments[0].getBoundingClientRect()", node.native)
|
82
|
+
[client_rect["left"].floor, client_rect["top"].floor, client_rect["right"].ceil, client_rect["bottom"].ceil]
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
const path = require("path")
|
2
|
+
const webpack = require("webpack")
|
3
|
+
|
4
|
+
module.exports = {
|
5
|
+
mode: "production",
|
6
|
+
devtool: "source-map",
|
7
|
+
entry: {
|
8
|
+
application: "./app/javascript/application.js"
|
9
|
+
},
|
10
|
+
output: {
|
11
|
+
filename: "[name].js",
|
12
|
+
sourceMapFilename: "[name].js.map",
|
13
|
+
path: path.resolve(__dirname, "app/assets/builds"),
|
14
|
+
},
|
15
|
+
plugins: [
|
16
|
+
new webpack.optimize.LimitChunkCountPlugin({
|
17
|
+
maxChunks: 1
|
18
|
+
})
|
19
|
+
]
|
20
|
+
}
|