diff --git a/.ameba.yml b/.ameba.yml index 82c244930..b7c7cdf74 100644 --- a/.ameba.yml +++ b/.ameba.yml @@ -1,24 +1,11 @@ -# This configuration file was generated by `ameba --gen-config` -# on 2026-04-02 23:47:16 UTC using Ameba version 1.6.4. -# The point is for the user to remove these configuration records -# one by one as the reported problems are removed from the code base. - -# Problems found: 92 -# Run `ameba --only Lint/UselessAssign` for details -Lint/UselessAssign: - Description: Disallows useless variable assignments - ExcludeTypeDeclarations: true - Enabled: true - Severity: Warning - -# Problems found: 9 -# Run `ameba --only Lint/Typos` for details Lint/Typos: - Description: Reports typos found in source files + Enabled: true FailOnError: false Excluded: - spec/lucky/text_helpers/truncate_spec.cr - spec/lucky/text_helpers/excerpts_spec.cr - spec/lucky/secure_headers_spec.cr - Enabled: true - Severity: Warning + +Lint/AssignmentInCallArgument: + Excluded: + - spec/lucky/memoize_spec.cr diff --git a/.github/workflows/ameba.yml b/.github/workflows/ameba.yml new file mode 100644 index 000000000..013377843 --- /dev/null +++ b/.github/workflows/ameba.yml @@ -0,0 +1,19 @@ +name: Ameba + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Download source + uses: actions/checkout@v7 + + - name: Run Ameba Linter + uses: crystal-ameba/github-action@master diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62889e8ad..5e5713e7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,25 +4,9 @@ on: push: branches: [main] pull_request: - branches: "*" + branches: '*' jobs: - check_format: - strategy: - fail-fast: false - runs-on: ubuntu-latest - continue-on-error: false - steps: - - uses: actions/checkout@v6 - - uses: crystal-lang/install-crystal@v1 - with: - crystal: latest - - name: Install shards - run: shards install - - name: Format - run: crystal tool format --check - - name: Lint - run: ./bin/ameba specs: strategy: fail-fast: false diff --git a/bin/lucky.gen.action.cr b/bin/lucky.gen.action.cr index 43a3a11c9..6c0da41b9 100644 --- a/bin/lucky.gen.action.cr +++ b/bin/lucky.gen.action.cr @@ -1,15 +1,15 @@ require "colorize" puts <<-ERROR - Missing 'browser' or 'api' after 'gen.action' + Missing 'browser' or 'api' after 'gen.action' - For actions used in a browser (HTML, redirects)... + For actions used in a browser (HTML, redirects)... - #{"lucky gen.action.browser".colorize.green.bold} + #{"lucky gen.action.browser".colorize.green.bold} - For an API endpoint (JSON, XML, GraphQL)... + For an API endpoint (JSON, XML, GraphQL)... - #{"lucky gen.action.api".colorize.green.bold} + #{"lucky gen.action.api".colorize.green.bold} - ERROR + ERROR diff --git a/shard.yml b/shard.yml index f31d587cd..230b4d7c3 100644 --- a/shard.yml +++ b/shard.yml @@ -58,6 +58,6 @@ development_dependencies: version: ~> 0.3.0 ameba: github: crystal-ameba/ameba - version: ~> 1.6.4 + branch: master license: MIT diff --git a/spec/lucky/action_pipes_spec.cr b/spec/lucky/action_pipes_spec.cr index 3dd927370..ffd97732e 100644 --- a/spec/lucky/action_pipes_spec.cr +++ b/spec/lucky/action_pipes_spec.cr @@ -235,9 +235,9 @@ describe Lucky::Action do end Pipes::HaltedBefore.new(build_context, params).call halted_pipe = events.find! { |e| e.name == "redirect_me" } - halted_pipe.continued.should eq false + halted_pipe.continued.should be_false halted_pipe.position.to_s.should eq "Before" - halted_pipe.before?.should eq true + halted_pipe.before?.should be_true end it "publishes an event on after when halted" do @@ -247,9 +247,9 @@ describe Lucky::Action do end Pipes::HaltedAfter.new(build_context, params).call halted_pipe = events.find! { |e| e.name == "redirect_me" } - halted_pipe.continued.should eq false + halted_pipe.continued.should be_false halted_pipe.position.to_s.should eq "After" - halted_pipe.after?.should eq true + halted_pipe.after?.should be_true end end end diff --git a/spec/lucky/action_redirect_spec.cr b/spec/lucky/action_redirect_spec.cr index 0df6e5afa..50c3366ad 100644 --- a/spec/lucky/action_redirect_spec.cr +++ b/spec/lucky/action_redirect_spec.cr @@ -165,7 +165,7 @@ describe Lucky::Action do response = action.redirect to: "/somewhere", status: 302 should_redirect(action, to: "/somewhere", status: 200) action.context.response.headers.has_key?("Turbolinks-Location").should be_false - response.body.should eq %[Turbolinks.clearCache();\nTurbolinks.visit("/somewhere", {"action": "replace"})] + response.body.should eq %(Turbolinks.clearCache();\nTurbolinks.visit("/somewhere", {"action": "replace"})) end it "set a cookie for redirects occurring during a turbolinks GET request" do diff --git a/spec/lucky/action_route_params_spec.cr b/spec/lucky/action_route_params_spec.cr index b91f11a97..0472e36bb 100644 --- a/spec/lucky/action_route_params_spec.cr +++ b/spec/lucky/action_route_params_spec.cr @@ -39,7 +39,7 @@ describe "Automatically generated param helpers" do action = TestOptionalParamAction.new(build_context, {"required" => "1", "optional_1" => "2"}) action.required.should eq "1" action.optional_1.should eq "2" - action.optional_2.should eq nil + action.optional_2.should be_nil typeof(action.optional_1).should eq String? typeof(action.optional_2).should eq String? end diff --git a/spec/lucky/action_spec.cr b/spec/lucky/action_spec.cr index 751141744..ae6a16055 100644 --- a/spec/lucky/action_spec.cr +++ b/spec/lucky/action_spec.cr @@ -537,7 +537,7 @@ describe Lucky::Action do it "is initialized to nil" do action = OptionalParams::Index.new(build_context(path: ""), params) - action.page.should eq nil + action.page.should be_nil end it "is fetched if present" do @@ -557,7 +557,7 @@ describe Lucky::Action do it "can specify nil as the default value" do action = OptionalParams::Index.new(build_context(path: ""), params) - action.nilable_with_explicit_nil.should eq nil + action.nilable_with_explicit_nil.should be_nil end it "overrides the default if present" do @@ -612,7 +612,7 @@ describe Lucky::Action do it "returns nil when the key is passed with no value for an optional param" do action = OptionalParams::Index.new(build_context(path: "/?optional_bool_with_no_default"), params) - action.optional_bool_with_no_default.should eq(nil) + action.optional_bool_with_no_default.should be_nil end end end diff --git a/spec/lucky/base_http_client_spec.cr b/spec/lucky/base_http_client_spec.cr index fdc0160b0..2cb38fb11 100644 --- a/spec/lucky/base_http_client_spec.cr +++ b/spec/lucky/base_http_client_spec.cr @@ -103,7 +103,7 @@ describe Lucky::BaseHTTPClient do { "event_id": "1"} { "type": "event"} { "event_id": "2", "type": "event", "platform": ""} - JSON + JSON response = MyClient.new.exec_raw(HelloWorldAction, test_data) request = TestServer.last_request @@ -117,7 +117,7 @@ describe Lucky::BaseHTTPClient do { "event_id": "1"} { "type": "event"} { "event_id": "2", "type": "event", "platform": ""} - JSON + JSON response = MyClient.new.exec_raw(HelloWorldAction.route, test_data) request = TestServer.last_request @@ -129,7 +129,7 @@ describe Lucky::BaseHTTPClient do {% for method in [:put, :patch, :post, :delete, :get, :options] %} describe "\#{{method.id}}" do it "sends correct request to correct uri and gives the correct response" do - response = MyClient.new.{{method.id}}( + response = MyClient.new.{{ method.id }}( path: "hello", foo: "bar" ) @@ -141,7 +141,7 @@ describe Lucky::BaseHTTPClient do end it "works without params" do - response = MyClient.new.{{method.id}}(path: "hello") + response = MyClient.new.{{ method.id }}(path: "hello") request = TestServer.last_request request.method.should eq({{ method.id.stringify }}.upcase) diff --git a/spec/lucky/base_tags_spec.cr b/spec/lucky/base_tags_spec.cr index afe5bd65e..cbdcdefae 100644 --- a/spec/lucky/base_tags_spec.cr +++ b/spec/lucky/base_tags_spec.cr @@ -38,9 +38,9 @@ describe Lucky::BaseTags do page.video(attrs: [:autoplay, :controls, :loop], poster: "https://luckyframework.org/nothing.png") do page.source(src: "https://luckyframework.org/nothing.mp4", type: "video/mp4") end - end.should contain %{} + end.should contain %() - view(&.video(id: "player", "data-stream": "https://luckyframework.org/demo.mp4")).should eq %{} + view(&.video(id: "player", "data-stream": "https://luckyframework.org/demo.mp4")).should eq %() end it "renders a button with a disabled boolean attribute" do @@ -48,14 +48,14 @@ describe Lucky::BaseTags do end it "renders an input with autofocus boolean attribute" do - view(&.input(attrs: [:autofocus], type: "text")).to_s.should contain %{} + view(&.input(attrs: [:autofocus], type: "text")).to_s.should contain %() end describe "#style" do it "renders a style tag" do view(&.style("body { font-size: 2em; }")).should contain <<-HTML - - HTML + + HTML end end end diff --git a/spec/lucky/component_spec.cr b/spec/lucky/component_spec.cr index 8e5369b63..9f54dc5c8 100644 --- a/spec/lucky/component_spec.cr +++ b/spec/lucky/component_spec.cr @@ -171,8 +171,8 @@ describe "components rendering" do it "uses context from being mounted" do contents = TestMountPage.new(context_with_csrf).render.to_s contents.should contain <<-HTML - input type="hidden" name="_csrf" - HTML + input type="hidden" name="_csrf" + HTML end end diff --git a/spec/lucky/cookies/cookie_jar_spec.cr b/spec/lucky/cookies/cookie_jar_spec.cr index 7a5521fde..ea6511898 100644 --- a/spec/lucky/cookies/cookie_jar_spec.cr +++ b/spec/lucky/cookies/cookie_jar_spec.cr @@ -104,7 +104,7 @@ describe Lucky::CookieJar do cookies = HTTP::Cookies.new cookies[cookie_key] = cookie_value jar = Lucky::CookieJar.from_request_cookies(cookies) - jar.get?(cookie_key).should eq(nil) + jar.get?(cookie_key).should be_nil end describe "#set" do diff --git a/spec/lucky/cookies/flash_store_spec.cr b/spec/lucky/cookies/flash_store_spec.cr index d2ac90c83..3063510f3 100644 --- a/spec/lucky/cookies/flash_store_spec.cr +++ b/spec/lucky/cookies/flash_store_spec.cr @@ -10,11 +10,11 @@ describe Lucky::FlashStore do it "raises an error when flash JSON is invalid" do message = <<-MESSAGE - The flash messages (stored as JSON) failed to parse in a JSON parser. - Here's what it tries to parse: + The flash messages (stored as JSON) failed to parse in a JSON parser. + Here's what it tries to parse: - not_valid_json=invalid - MESSAGE + not_valid_json=invalid + MESSAGE expect_raises(Lucky::InvalidFlashJSONError, message) do Lucky::FlashStore.from_session(build_invalid_session) @@ -92,14 +92,14 @@ describe Lucky::FlashStore do it "returns true if there are key/value pairs" do flash_store = build_flash_store({"some_key" => "some_value"}) - # ameba:disable Performance/AnyInsteadOfEmpty + # ameba:disable Performance/AnyInsteadOfPresent flash_store.any?.should be_true end it "returns false if there are no key/value pairs" do flash_store = build_flash_store - # ameba:disable Performance/AnyInsteadOfEmpty + # ameba:disable Performance/AnyInsteadOfPresent flash_store.any?.should be_false end end diff --git a/spec/lucky/forgery_protection_helpers_spec.cr b/spec/lucky/forgery_protection_helpers_spec.cr index 933ba5a04..ff3d9e6f0 100644 --- a/spec/lucky/forgery_protection_helpers_spec.cr +++ b/spec/lucky/forgery_protection_helpers_spec.cr @@ -15,8 +15,8 @@ describe Lucky::ForgeryProtectionHelpers do context.session.set(Lucky::ProtectFromForgery::SESSION_KEY, "my_token") view(context, &.csrf_hidden_input).should contain <<-HTML - - HTML + + HTML end it "renders a meta tag for Rails UJS (and other JS that may need it)" do @@ -25,11 +25,11 @@ describe Lucky::ForgeryProtectionHelpers do rendered = view(context, &.csrf_meta_tags) rendered.should contain <<-HTML - - HTML + + HTML rendered.should contain <<-HTML - - HTML + + HTML end end diff --git a/spec/lucky/form_helpers_spec.cr b/spec/lucky/form_helpers_spec.cr index 0c2d110bf..f180bf827 100644 --- a/spec/lucky/form_helpers_spec.cr +++ b/spec/lucky/form_helpers_spec.cr @@ -73,34 +73,34 @@ describe Lucky::FormHelpers do it "renders a form tag" do without_csrf_protection do view(&.inferred_put_form).should contain <<-HTML -
- HTML + + HTML view(&.inferred_post_form).should contain <<-HTML - - HTML + + HTML view(&.inferred_get_form).should contain <<-HTML - - HTML + + HTML view(&.form_with_html_options).should contain <<-HTML - - HTML + + HTML form = view(&.form_for(FormHelpers::Index) { }) form.should contain <<-HTML - - HTML + + HTML form = view(&.form_for(FormHelpers::Index, class: "form-block") { }) form.should contain <<-HTML - - HTML + + HTML view(&.form_with_bool_attr).should contain <<-HTML - - HTML + + HTML form = view do |page| page.form_wrapper(FormHelpers::Create) do @@ -109,8 +109,8 @@ describe Lucky::FormHelpers do end form.should contain <<-HTML - - HTML + + HTML end end @@ -121,40 +121,40 @@ describe Lucky::FormHelpers do form = view(context_with_csrf, &.form_for(FormHelpers::Index) { }) form.should contain <<-HTML - - HTML + + HTML end it "converts the multipart argument" do without_csrf_protection do view(&.form_with_multipart).should contain <<-HTML - - HTML + + HTML view(&.form_with_multipart_false).should contain <<-HTML - - HTML + + HTML end end it "renders submit input" do view(&.submit("Save")).should contain <<-HTML - - HTML + + HTML view(&.submit("Save", class: "cool")).should contain <<-HTML - - HTML + + HTML end it "renders submit input with attributes" do view(&.submit("Save", attrs: [:disabled])).should contain <<-HTML - - HTML + + HTML view(&.submit("Save", class: "cool", attrs: [:hidden, :disabled])).should contain <<-HTML - - HTML + + HTML end end diff --git a/spec/lucky/format_integration_spec.cr b/spec/lucky/format_integration_spec.cr index a71c45ce3..ebce9cde6 100644 --- a/spec/lucky/format_integration_spec.cr +++ b/spec/lucky/format_integration_spec.cr @@ -63,7 +63,7 @@ describe "Format Integration" do ctx.request.path.should eq("/js/main.js") } result = handler.call(context) - result.should eq(nil) + result.should be_nil end it "supports multiple format extensions" do diff --git a/spec/lucky/html_page_spec.cr b/spec/lucky/html_page_spec.cr index d6908e9b9..602134d66 100644 --- a/spec/lucky/html_page_spec.cr +++ b/spec/lucky/html_page_spec.cr @@ -72,7 +72,7 @@ class LessNeedyDefaultsPage < MainLayout needs bool : Bool = false needs nil_default : String? = nil needs inferred_nil_default : String? - needs inferred_nil_default2 : String | Nil + needs inferred_nil_default2 : String? def inner div @a_string diff --git a/spec/lucky/link_helpers_spec.cr b/spec/lucky/link_helpers_spec.cr index 7a68dd07a..cb5bf21f4 100644 --- a/spec/lucky/link_helpers_spec.cr +++ b/spec/lucky/link_helpers_spec.cr @@ -61,26 +61,26 @@ describe Lucky::LinkHelpers do it "renders a link tag with an action" do view(&.link("Test", to: LinkHelpers::Index)).should contain <<-HTML - Test - HTML + Test + HTML link = view(&.link(to: LinkHelpers::Index, class: "link") { }) link.should contain <<-HTML - - HTML + + HTML end it "renders a link tag with a block" do view(&.http_get_route_with_block).should contain <<-HTML - Hello - HTML + Hello + HTML end it "renders a link tag without text" do view(&.http_get_route_without_text).should contain <<-HTML - - HTML + + HTML end it "renders a link with uuid" do @@ -90,26 +90,26 @@ describe Lucky::LinkHelpers do it "renders a link with a special data attribute" do view(&.link(to: LinkHelpers::Index, "data-is-useless": true)).should contain <<-HTML - - HTML + + HTML view(&.link(to: LinkHelpers::Index, "data-num": 4)).should contain <<-HTML - - HTML + + HTML end it "renders a link with boolean attrs" do view(&.http_get_route_with_text_and_attrs).should contain <<-HTML - Text - HTML + Text + HTML view(&.http_get_route_with_attrs_no_text).should contain <<-HTML - - HTML + + HTML view(&.http_get_route_with_block_and_attrs).should contain <<-HTML - Hello - HTML + Hello + HTML end end diff --git a/spec/lucky/memoize_spec.cr b/spec/lucky/memoize_spec.cr index 84d349d6b..6877b0d05 100644 --- a/spec/lucky/memoize_spec.cr +++ b/spec/lucky/memoize_spec.cr @@ -101,9 +101,9 @@ describe "memoizations" do it "works with predicate methods" do object = ObjectWithMemoizedMethods.new - object.method_4?.should eq(true) - object.method_4?.should eq(true) - object.method_4?.should eq(true) + object.method_4?.should be_true + object.method_4?.should be_true + object.method_4?.should be_true object.times_method_4_called.should eq(1) end @@ -119,9 +119,9 @@ describe "memoizations" do it "calls uncached with predicate and bang methods" do object = ObjectWithMemoizedMethods.new - object.method_4__uncached?.should eq(true) - object.method_4__uncached?.should eq(true) - object.method_4__uncached?.should eq(true) + object.method_4__uncached?.should be_true + object.method_4__uncached?.should be_true + object.method_4__uncached?.should be_true object.times_method_4_called.should eq(3) object.method_5__uncached!.should eq("Boom!") diff --git a/spec/lucky/paginator/paginator_spec.cr b/spec/lucky/paginator/paginator_spec.cr index d74a66996..ae00b0fc2 100644 --- a/spec/lucky/paginator/paginator_spec.cr +++ b/spec/lucky/paginator/paginator_spec.cr @@ -47,32 +47,32 @@ describe Lucky::Paginator do describe "#last_page?" do it "returns true if the current page is the last one" do - build_pages(page: 2, per_page: 1, item_count: 2).last_page?.should eq(true) - build_pages(page: 1, per_page: 1, item_count: 1).last_page?.should eq(true) + build_pages(page: 2, per_page: 1, item_count: 2).last_page?.should be_true + build_pages(page: 1, per_page: 1, item_count: 1).last_page?.should be_true end it "returns false if the current page is not the last one" do - build_pages(page: 1, per_page: 1, item_count: 2).last_page?.should eq(false) + build_pages(page: 1, per_page: 1, item_count: 2).last_page?.should be_false end end describe "#first_page?" do it "returns true if the current page is the first one" do - build_pages(page: 1, per_page: 1, item_count: 1).first_page?.should eq(true) + build_pages(page: 1, per_page: 1, item_count: 1).first_page?.should be_true end it "otherwise returns false" do - build_pages(page: 2, per_page: 1, item_count: 2).first_page?.should eq(false) + build_pages(page: 2, per_page: 1, item_count: 2).first_page?.should be_false end end describe "#overflowed?" do it "returns true if the current page is past the last page" do - build_pages(page: 2, per_page: 1, item_count: 1).overflowed?.should eq(true) + build_pages(page: 2, per_page: 1, item_count: 1).overflowed?.should be_true end it "otherwise returns false" do - build_pages(page: 1, per_page: 1, item_count: 1).overflowed?.should eq(false) + build_pages(page: 1, per_page: 1, item_count: 1).overflowed?.should be_false end end diff --git a/spec/lucky/params_spec.cr b/spec/lucky/params_spec.cr index 312321d3e..35cc2195f 100644 --- a/spec/lucky/params_spec.cr +++ b/spec/lucky/params_spec.cr @@ -420,7 +420,7 @@ describe Lucky::Params do request = build_request body: "", content_type: "" request.query = "a=1" params = Lucky::Params.new(request) - params.nested?("a").empty?.should eq true + params.nested?("a").empty?.should be_true end it "gets nested params after unescaping" do @@ -531,7 +531,7 @@ describe Lucky::Params do request = build_request body: "", content_type: "" request.query = "a[]=1" params = Lucky::Params.new(request) - params.nested_arrays?("a").empty?.should eq true + params.nested_arrays?("a").empty?.should be_true end it "gets nested array params after unescaping" do @@ -573,7 +573,7 @@ describe Lucky::Params do params = Lucky::Params.new(request) file = params.get_file(:welcome_file) - file.is_a?(Lucky::UploadedFile).should eq(true) + file.is_a?(Lucky::UploadedFile).should be_true File.read(file.path).should eq "welcome file contents" end @@ -772,7 +772,7 @@ describe Lucky::Params do request = build_request body: "", content_type: "" request.query = "a=1" params = Lucky::Params.new(request) - params.many_nested?("a").empty?.should eq true + params.many_nested?("a").empty?.should be_true end it "gets nested params after unescaping" do @@ -844,7 +844,7 @@ describe Lucky::Params do route_params = {"id" => "from_route"} params = Lucky::Params.new(request) - params.get?(:id).should eq nil + params.get?(:id).should be_nil params.route_params = route_params params.get?(:id).should eq "from_route" diff --git a/spec/lucky/remote_ip_handler_spec.cr b/spec/lucky/remote_ip_handler_spec.cr index 2d61ce834..7892bec73 100644 --- a/spec/lucky/remote_ip_handler_spec.cr +++ b/spec/lucky/remote_ip_handler_spec.cr @@ -8,7 +8,7 @@ describe Lucky::RemoteIpHandler do context = build_context(path: "/path") run_remote_ip_handler(context) - context.request.remote_address.should eq nil + context.request.remote_address.should be_nil context.request.remote_ip.should eq "" end @@ -44,7 +44,7 @@ describe Lucky::RemoteIpHandler do context = build_context(request) run_remote_ip_handler(context) - context.request.remote_address.should eq nil + context.request.remote_address.should be_nil context.request.remote_ip.should eq "" end diff --git a/spec/lucky/specialty_tags_spec.cr b/spec/lucky/specialty_tags_spec.cr index bd74b5a08..395535bbd 100644 --- a/spec/lucky/specialty_tags_spec.cr +++ b/spec/lucky/specialty_tags_spec.cr @@ -12,18 +12,18 @@ end describe Lucky::SpecialtyTags do it "renders doctype" do view(&.html_doctype).should contain <<-HTML - - HTML + + HTML end it "renders css link tag" do view(&.css_link("app.css")).should eq <<-HTML - - HTML + + HTML view(&.css_link("app.css", rel: "preload", media: "print")).should eq <<-HTML - - HTML + + HTML end it "cache-busts non-fingerprinted local css links" do @@ -58,38 +58,38 @@ describe Lucky::SpecialtyTags do it "renders js link tag" do view(&.js_link("app.js")).should contain <<-HTML - - HTML + + HTML view(&.js_link("app.js", foo: "bar")).should contain <<-HTML - - HTML + + HTML end it "render utf8 meta tag" do view(&.utf8_charset).should contain <<-HTML - - HTML + + HTML end it "renders responsive meta tag" do view(&.responsive_meta_tag).should contain <<-HTML - - HTML + + HTML view(&.responsive_meta_tag(width: 600)).should contain <<-HTML - - HTML + + HTML view(&.responsive_meta_tag(height: 600)).should contain <<-HTML - - HTML + + HTML end it "renders canonical link tag" do view(&.canonical_link("https://it.is/here")).should contain <<-HTML - - HTML + + HTML end it "renders bun reload script in development" do @@ -117,12 +117,12 @@ describe Lucky::SpecialtyTags do it "renders proper non-breaking space entity" do view(&.nbsp).should contain <<-HTML - - HTML + + HTML view(&.nbsp(3)).should contain <<-HTML - - HTML + + HTML end end diff --git a/spec/lucky/static_compression_handler_spec.cr b/spec/lucky/static_compression_handler_spec.cr index e19828982..621b18109 100644 --- a/spec/lucky/static_compression_handler_spec.cr +++ b/spec/lucky/static_compression_handler_spec.cr @@ -18,7 +18,7 @@ describe Lucky::StaticCompressionHandler do end it "calls next when content type isn't in Lucky::Server.gzip_content_types" do - Lucky::Server.temp_config(gzip_enabled: true, gzip_content_types: %w(text/html)) do + Lucky::Server.temp_config(gzip_enabled: true, gzip_content_types: %w[text/html]) do context = build_context(path: PATH) context.request.headers["Accept-Encoding"] = "gzip" next_called = false @@ -95,7 +95,7 @@ private def gzip_path end private def etag - %{W/"#{last_modified.to_unix}"} + %(W/"#{last_modified.to_unix}") end private def last_modified diff --git a/spec/lucky/text_helpers/highlight_spec.cr b/spec/lucky/text_helpers/highlight_spec.cr index a381ef91f..f627a2b4e 100644 --- a/spec/lucky/text_helpers/highlight_spec.cr +++ b/spec/lucky/text_helpers/highlight_spec.cr @@ -6,11 +6,11 @@ class HighlightTestPage include Lucky::HTMLPage def test_highlight - highlight "This is a beautiful morning, but also a beautiful day", "beautiful" { |word| + highlight "This is a beautiful morning, but also a beautiful day", "beautiful" do |word| # you can't use HTMLPage here since they append to 'view' rather than return in-place # the block highlight expects is passed to gsub which expects to get a string returned "#{word}" - } + end end end @@ -38,7 +38,7 @@ describe Lucky::TextHelpers do end it "highlights with multiple phrases in one pass" do - view(&.highlight("wow em", %w(wow em), highlighter: "\\1")).should eq %(wow em) + view(&.highlight("wow em", %w[wow em], highlighter: "\\1")).should eq %(wow em) end it "escapes HTML by default" do diff --git a/spec/tasks/gen/action_spec.cr b/spec/tasks/gen/action_spec.cr index 01c2c3a38..aa2c8ad46 100644 --- a/spec/tasks/gen/action_spec.cr +++ b/spec/tasks/gen/action_spec.cr @@ -115,6 +115,6 @@ describe Gen::Action do route: %(get "/users") ) folder = template.template_folder - LuckyTemplate.snapshot(folder).has_key?("src/actions/user/index.cr").should eq(true) + LuckyTemplate.snapshot(folder).has_key?("src/actions/user/index.cr").should be_true end end diff --git a/src/charms/int16_extensions.cr b/src/charms/int16_extensions.cr index 2f78ead5c..01f195c5b 100644 --- a/src/charms/int16_extensions.cr +++ b/src/charms/int16_extensions.cr @@ -4,6 +4,6 @@ struct Int16 include ::Lucky::AllowedInTags def to_param : String - self.to_s + to_s end end diff --git a/src/charms/int32_extensions.cr b/src/charms/int32_extensions.cr index 7a2e7f985..b69b008d9 100644 --- a/src/charms/int32_extensions.cr +++ b/src/charms/int32_extensions.cr @@ -4,6 +4,6 @@ struct Int32 include ::Lucky::AllowedInTags def to_param : String - self.to_s + to_s end end diff --git a/src/charms/int64_extensions.cr b/src/charms/int64_extensions.cr index 40e80cfe8..e685da514 100644 --- a/src/charms/int64_extensions.cr +++ b/src/charms/int64_extensions.cr @@ -4,6 +4,6 @@ struct Int64 include ::Lucky::AllowedInTags def to_param : String - self.to_s + to_s end end diff --git a/src/charms/object.cr b/src/charms/object.cr index 0b2c115a1..37a05e6f6 100644 --- a/src/charms/object.cr +++ b/src/charms/object.cr @@ -4,7 +4,7 @@ class Object def blank? : Bool if self.responds_to?(:empty?) - self.empty? + self.empty? # ameba:disable Style/RedundantSelf else false end diff --git a/src/charms/uuid_extensions.cr b/src/charms/uuid_extensions.cr index 50bac0dad..c2447d231 100644 --- a/src/charms/uuid_extensions.cr +++ b/src/charms/uuid_extensions.cr @@ -2,6 +2,6 @@ struct UUID include ::Lucky::AllowedInTags def to_param : String - self.to_s + to_s end end diff --git a/src/lucky/action_pipes.cr b/src/lucky/action_pipes.cr index 889853749..040025839 100644 --- a/src/lucky/action_pipes.cr +++ b/src/lucky/action_pipes.cr @@ -15,9 +15,9 @@ module Lucky::ActionPipes {% AFTER_PIPES[pipe.id] = false %} {% else %} {% pipe.raise <<-ERROR.lines.join(" ") - Can't skip '#{pipe}' because the pipe is not used. - Check the spelling of the pipe that you are trying to skip. - ERROR + Can't skip '#{pipe}' because the pipe is not used. + Check the spelling of the pipe that you are trying to skip. + ERROR %} {% end %} {% end %} diff --git a/src/lucky/asset_helpers.cr b/src/lucky/asset_helpers.cr index 293309b87..700054b4c 100644 --- a/src/lucky/asset_helpers.cr +++ b/src/lucky/asset_helpers.cr @@ -68,26 +68,26 @@ module Lucky::AssetHelpers {% end %} {% elsif path.is_a?(StringInterpolation) %} {% raise <<-ERROR - \n - The 'asset' macro doesn't work with string interpolation + \n + The 'asset' macro doesn't work with string interpolation - Try this... + Try this... - ▸ Use the 'dynamic_asset' method instead + ▸ Use the 'dynamic_asset' method instead - ERROR + ERROR %} {% else %} {% raise <<-ERROR - \n - The 'asset' macro requires a literal string like "my-logo.png", instead got: #{path} + \n + The 'asset' macro requires a literal string like "my-logo.png", instead got: #{path} - Try this... + Try this... - ▸ If you're using a variable, switch to a literal string - ▸ If you can't use a literal string, use the 'dynamic_asset' method instead + ▸ If you're using a variable, switch to a literal string + ▸ If you can't use a literal string, use the 'dynamic_asset' method instead - ERROR + ERROR %} {% end %} end diff --git a/src/lucky/assignable.cr b/src/lucky/assignable.cr index 92469e0c4..d71e00855 100644 --- a/src/lucky/assignable.cr +++ b/src/lucky/assignable.cr @@ -86,15 +86,15 @@ module Lucky::Assignable macro generate_needy_initializer {% if !@type.abstract? %} - {% sorted_assigns = ASSIGNS.sort_by { |dec| + {% sorted_assigns = ASSIGNS.sort_by do |dec| has_explicit_value = dec.type.is_a?(Metaclass) || - dec.type.types.any? { |type| + dec.type.types.any? do |type| (type.is_a?(Metaclass) || type.is_a?(ProcNotation) || type.is_a?(Generic)) ? false : type.names.includes?(Nil.id) - } || + end || !dec.value.is_a?(Nop) has_explicit_value ? 1 : 0 - } %} + end %} # Check if this is a BaseComponent - if so, don't accept unused exposures {% is_component = @type.ancestors.any? { |ancestor| ancestor.stringify == "Lucky::BaseComponent" } %} diff --git a/src/lucky/base_http_client.cr b/src/lucky/base_http_client.cr index 2fc55258b..764090b57 100644 --- a/src/lucky/base_http_client.cr +++ b/src/lucky/base_http_client.cr @@ -133,7 +133,7 @@ abstract class Lucky::BaseHTTPClient @port = -1 def self.from_app(app : Lucky::BaseAppServer) : self - self.new(HTTP::Server.build_middleware(app.middleware)) + new(HTTP::Server.build_middleware(app.middleware)) end def initialize(@app : HTTP::Handler) diff --git a/src/lucky/context_extensions.cr b/src/lucky/context_extensions.cr index 76391ce61..de945e5a0 100644 --- a/src/lucky/context_extensions.cr +++ b/src/lucky/context_extensions.cr @@ -11,7 +11,7 @@ class HTTP::Server::Context # # This stores the format extracted from the URL path (e.g., .csv, .json) # This takes precedence over Accept header-based format detection - property _url_format : Lucky::Format | Lucky::FormatRegistry::CustomFormat | Nil = nil + property _url_format : Lucky::Format | Lucky::FormatRegistry::CustomFormat? = nil # :nodoc: # diff --git a/src/lucky/cookies/cookie_jar.cr b/src/lucky/cookies/cookie_jar.cr index 3db41a13c..2646918cb 100644 --- a/src/lucky/cookies/cookie_jar.cr +++ b/src/lucky/cookies/cookie_jar.cr @@ -133,8 +133,8 @@ class Lucky::CookieJar raise Lucky::CookieOverflowError.new("size of '#{key}' cookie is too big") end cookies[key.to_s] = set_cookies[key.to_s] = raw_cookie - rescue e : IO::Error - raise InvalidCookieValueError.new(key, cause: e) + rescue ex : IO::Error + raise InvalidCookieValueError.new(key, cause: ex) end private def encrypt(raw_value : String) : String @@ -151,7 +151,7 @@ class Lucky::CookieJar base_64_encrypted_part = cookie_value.lchop(LUCKY_ENCRYPTION_PREFIX) String.new(encryptor.verify_and_decrypt(base_64_encrypted_part)) - rescue e + rescue # an error happened while decrypting the cookie # we will treat that as if no cookie was passed end diff --git a/src/lucky/cookies/flash_store.cr b/src/lucky/cookies/flash_store.cr index 7fcd49187..9a616eb76 100644 --- a/src/lucky/cookies/flash_store.cr +++ b/src/lucky/cookies/flash_store.cr @@ -18,8 +18,8 @@ class Lucky::FlashStore end end self - rescue e : JSON::ParseException - raise Lucky::InvalidFlashJSONError.new(session.get?(SESSION_KEY), cause: e) + rescue ex : JSON::ParseException + raise Lucky::InvalidFlashJSONError.new(session.get?(SESSION_KEY), cause: ex) end def keep : Nil diff --git a/src/lucky/enforce_underscored_route.cr b/src/lucky/enforce_underscored_route.cr index ff2a8b9a1..354ab5818 100644 --- a/src/lucky/enforce_underscored_route.cr +++ b/src/lucky/enforce_underscored_route.cr @@ -6,28 +6,28 @@ module Lucky::EnforceUnderscoredRoute macro enforce_route_style(path, action) {% if path.includes?("-") %} {% raise <<-ERROR - #{path} defined in '#{action}' should use an underscore. + #{path} defined in '#{action}' should use an underscore. - In '#{action}' + In '#{action}' - ▸ Change #{path} - ▸ To #{path.gsub(/-/, "_")} + ▸ Change #{path} + ▸ To #{path.gsub(/-/, "_")} - Or, skip the style check for this action + Or, skip the style check for this action - class #{action} - + include Lucky::SkipRouteStyleCheck - end + class #{action} + + include Lucky::SkipRouteStyleCheck + end - Or, skip checking all actions by removing 'Lucky::EnforceUnderscoredRoute' + Or, skip checking all actions by removing 'Lucky::EnforceUnderscoredRoute' - # Remove from both BrowserAction and ApiAction - class BrowserAction/ApiAction - - include Lucky::EnforceUnderscoredRoute - end + # Remove from both BrowserAction and ApiAction + class BrowserAction/ApiAction + - include Lucky::EnforceUnderscoredRoute + end - ERROR + ERROR %} {% end %} end diff --git a/src/lucky/errors.cr b/src/lucky/errors.cr index 67f6dbed9..44508f0ec 100644 --- a/src/lucky/errors.cr +++ b/src/lucky/errors.cr @@ -40,21 +40,21 @@ module Lucky def initialize(@request : HTTP::Request) accept_header = request.headers["accept"]? super <<-TEXT - Lucky couldn't figure out what format the client accepts. + Lucky couldn't figure out what format the client accepts. - The client's Accept header: '#{accept_header}' + The client's Accept header: '#{accept_header}' - You can teach Lucky how to handle this header: + You can teach Lucky how to handle this header: - #{"# Add this in config/mime_types.cr".colorize.dim} - Lucky::MimeType.register "#{accept_header}", :custom_format + #{"# Add this in config/mime_types.cr".colorize.dim} + Lucky::MimeType.register "#{accept_header}", :custom_format - Or use one of these headers Lucky knows about: + Or use one of these headers Lucky knows about: - #{Lucky::MimeType.known_accept_headers.join(", ")} + #{Lucky::MimeType.known_accept_headers.join(", ")} - TEXT + TEXT end def renderable_status : Int32 @@ -73,17 +73,17 @@ module Lucky def initialize(@request : HTTP::Request, action_name : String, format : Symbol, accepted_formats : Array(Symbol)) super <<-TEXT - The request wants :#{format}, but #{action_name} does not accept it. + The request wants :#{format}, but #{action_name} does not accept it. - Accepted formats: #{accepted_formats.map(&.to_s).join(", ")} + Accepted formats: #{accepted_formats.map(&.to_s).join(", ")} - Try this... + Try this... - ▸ Add :#{format} to 'accepted_formats' in #{action_name} or its parent class. - ▸ Make your request using one of the accepted formats. + ▸ Add :#{format} to 'accepted_formats' in #{action_name} or its parent class. + ▸ Make your request using one of the accepted formats. - TEXT + TEXT end def renderable_status : Int32 @@ -132,14 +132,14 @@ module Lucky private def _message <<-ERROR - Cookie value for '#{key}' is invalid. + Cookie value for '#{key}' is invalid. - Be sure the value does not contain any blank characters, - comma, double quote, semicolon, or double backslash. + Be sure the value does not contain any blank characters, + comma, double quote, semicolon, or double backslash. - See https://tools.ietf.org/html/rfc6265#section-4.1.1 for valid - characters - ERROR + See https://tools.ietf.org/html/rfc6265#section-4.1.1 for valid + characters + ERROR end end @@ -232,11 +232,11 @@ module Lucky private def _message <<-MESSAGE - The flash messages (stored as JSON) failed to parse in a JSON parser. - Here's what it tries to parse: + The flash messages (stored as JSON) failed to parse in a JSON parser. + Here's what it tries to parse: - #{bad_json} - MESSAGE + #{bad_json} + MESSAGE end end @@ -253,7 +253,7 @@ module Lucky <<-MESSAGE Expected subdomain matcher(s): #{@expected} Did not match host: #{@host} - MESSAGE + MESSAGE end end end diff --git a/src/lucky/exposable.cr b/src/lucky/exposable.cr index 4e59d14f6..633f16bb7 100644 --- a/src/lucky/exposable.cr +++ b/src/lucky/exposable.cr @@ -111,14 +111,14 @@ module Lucky::Exposable {% if method_name_str.ends_with?('?') || method_name_str.ends_with?('!') %} {% method_name.raise <<-ERROR - Methods ending in '?' or '!' cannot be exposed to pages. - #{@type.name} called `expose #{method_name_str.id}` + Methods ending in '?' or '!' cannot be exposed to pages. + #{@type.name} called `expose #{method_name_str.id}` - Try this... + Try this... - ▸ Define your method without ? or ! then... - ▸ expose #{method_name_str.gsub(/[!?]$/, "").id} - ERROR + ▸ Define your method without ? or ! then... + ▸ expose #{method_name_str.gsub(/[!?]$/, "").id} + ERROR %} {% end %} {% EXPOSURES << method_name.id %} diff --git a/src/lucky/format.cr b/src/lucky/format.cr index 785d5f872..2c60082e7 100644 --- a/src/lucky/format.cr +++ b/src/lucky/format.cr @@ -56,7 +56,6 @@ enum Lucky::Format end # Parse format from file extension - # ameba:disable Metrics/CyclomaticComplexity def self.from_extension(extension : String) : Format? case extension.downcase when "html", "htm" then Html @@ -70,7 +69,6 @@ enum Lucky::Format when "atom" then Atom when "ics", "ical" then Ics when "css" then Css - else nil end end @@ -91,7 +89,6 @@ enum Lucky::Format when "text/css" then Css when "multipart/form-data" then MultipartForm when "application/x-www-form-urlencoded" then UrlEncodedForm - else nil end end end diff --git a/src/lucky/format_registry.cr b/src/lucky/format_registry.cr index 0ef6029c6..7ff833960 100644 --- a/src/lucky/format_registry.cr +++ b/src/lucky/format_registry.cr @@ -23,7 +23,7 @@ module Lucky::FormatRegistry end # Find format by extension (checks both built-in and custom formats) - def self.from_extension(extension : String) : Lucky::Format | CustomFormat | Nil + def self.from_extension(extension : String) : Lucky::Format | CustomFormat? # Try built-in formats first if format = Lucky::Format.from_extension(extension) return format @@ -38,7 +38,7 @@ module Lucky::FormatRegistry end # Find format by MIME type (checks both built-in and custom formats) - def self.from_mime_type(mime_type : String) : Lucky::Format | CustomFormat | Nil + def self.from_mime_type(mime_type : String) : Lucky::Format | CustomFormat? # Try built-in formats first if format = Lucky::Format.from_mime_type(mime_type) return format diff --git a/src/lucky/json_body_parser.cr b/src/lucky/json_body_parser.cr index 6587475ea..690e5f06b 100644 --- a/src/lucky/json_body_parser.cr +++ b/src/lucky/json_body_parser.cr @@ -12,7 +12,7 @@ class Lucky::JsonBodyParser else JSON.parse(body) end - rescue e : JSON::ParseException - raise Lucky::ParamParsingError.new(@request, cause: e) + rescue ex : JSON::ParseException + raise Lucky::ParamParsingError.new(@request, cause: ex) end end diff --git a/src/lucky/log_handler.cr b/src/lucky/log_handler.cr index 987d5dccc..6f4f141f2 100644 --- a/src/lucky/log_handler.cr +++ b/src/lucky/log_handler.cr @@ -37,9 +37,9 @@ class Lucky::LogHandler log_request_end(context, duration: duration) Lucky::Events::RequestCompleteEvent.publish(duration) end - rescue e - log_exception(context, Time.utc, e) - raise e + rescue ex + log_exception(context, Time.utc, ex) + raise ex end private def log_request_start(context : HTTP::Server::Context) : Nil diff --git a/src/lucky/memoizable.cr b/src/lucky/memoizable.cr index c90c43c4c..7404b4db5 100644 --- a/src/lucky/memoizable.cr +++ b/src/lucky/memoizable.cr @@ -40,7 +40,7 @@ module Lucky::Memoizable end %} - @__memoized_{{safe_method_name}} : Tuple( + @__memoized_{{ safe_method_name }} : Tuple( {{ method_def.return_type }}, {% for arg in method_def.args %} {{ arg.restriction }}, @@ -78,18 +78,18 @@ module Lucky::Memoizable {% end %} ) {% for arg, index in method_def.args %} - @__memoized_{{ safe_method_name }} = nil if {{arg.internal_name}} != @__memoized_{{ safe_method_name }}.try &.at({{index}} + 1) + @__memoized_{{ safe_method_name }} = nil if {{ arg.internal_name }} != @__memoized_{{ safe_method_name }}.try &.at({{ index }} + 1) {% end %} @__memoized_{{ safe_method_name }} ||= -> do result = {{ safe_method_name }}__uncached{% if special_ending %}{{ special_ending.id }}{% end %}( {% for arg in method_def.args %} - {{arg.internal_name}}, + {{ arg.internal_name }}, {% end %} ) { result, {% for arg in method_def.args %} - {{arg.internal_name}}, + {{ arg.internal_name }}, {% end %} } end.call.not_nil! @@ -108,7 +108,7 @@ module Lucky::Memoizable ) : {{ method_def.return_type }} {{ safe_method_name }}__tuple_cached{% if special_ending %}{{ special_ending.id }}{% end %}( {% for arg in method_def.args %} - {{arg.internal_name}}, + {{ arg.internal_name }}, {% end %} ).first end diff --git a/src/lucky/mime_type.cr b/src/lucky/mime_type.cr index 342bde33f..3a89f012e 100644 --- a/src/lucky/mime_type.cr +++ b/src/lucky/mime_type.cr @@ -67,7 +67,7 @@ class Lucky::MimeType end # Extract format from URL path (e.g., "/reports/123.csv" -> Format::Csv) - def self.extract_format_from_path(path : String) : Lucky::Format | Lucky::FormatRegistry::CustomFormat | Nil + def self.extract_format_from_path(path : String) : Lucky::Format | Lucky::FormatRegistry::CustomFormat? # Only match extensions in the path portion (before any query string) if match = path.match(/^[^?]*\.([a-zA-Z0-9]+)(?:\?|$)/) extension = match[1] @@ -121,12 +121,10 @@ class Lucky::MimeType # quality value. def self.parse(accept : String) : Array(MediaRange) list = accept.split(ACCEPT_SEP).compact_map do |range| - begin - MediaRange.parse(range) - rescue ex : InvalidMediaRange - Log.debug { "invalid media range in Accept: #{accept} - #{ex}" } - nil - end + MediaRange.parse(range) + rescue ex : InvalidMediaRange + Log.debug { "invalid media range in Accept: #{accept} - #{ex}" } + nil end list.unstable_sort_by! { |range| -range.qvalue.to_i32 } end @@ -144,7 +142,7 @@ class Lucky::MimeType # If we find a match in the things we accept then pick one of those formats_in_common = known_formats.select { |_media, format| accepted_formats.includes?(format) } unless formats_in_common.empty? - self.list.each do |media_range| + list.each do |media_range| if match = formats_in_common.find { |media, _format| media_range.matches?(media) } return match[1] end @@ -154,14 +152,14 @@ class Lucky::MimeType # Otherwise if the client doesn't just accept anything then try to find something they # do accept in the list of known formats unless includes_catch_all? - self.list.each do |media_range| + list.each do |media_range| if match = known_formats.find { |media, _format| media_range.matches?(media) } return match[1] end end # No known formats match the ones requested - return nil + return end # Finally the client accepts anything so use the default format @@ -218,8 +216,8 @@ class Lucky::MimeType # multiplied by 1000 and then handled as an integer. begin ($1.to_f32 * 1000).round.to_u16 - rescue e : ArgumentError | OverflowError - raise InvalidMediaRange.new("#{parameter} is not a valid qvalue", cause: e) + rescue ex : ArgumentError | OverflowError + raise InvalidMediaRange.new("#{parameter} is not a valid qvalue", cause: ex) end else 1000u16 diff --git a/src/lucky/mount_component.cr b/src/lucky/mount_component.cr index 4794fd8c5..68c3adfb8 100644 --- a/src/lucky/mount_component.cr +++ b/src/lucky/mount_component.cr @@ -38,52 +38,52 @@ module Lucky::MountComponent # :nodoc: def mount(_component : Lucky::BaseComponent, *args, **named_args) : Nil {% raise <<-ERROR - 'mount' requires a component class, not an instance of a component. + 'mount' requires a component class, not an instance of a component. - Try this... + Try this... - ▸ mount MyComponent - ▸ mount_instance MyComponent.new - ERROR + ▸ mount MyComponent + ▸ mount_instance MyComponent.new + ERROR %} end # :nodoc: def mount(_component : Lucky::BaseComponent, *args, **named_args, &) : Nil {% raise <<-ERROR - 'mount' requires a component class, not an instance of a component. + 'mount' requires a component class, not an instance of a component. - Try this... + Try this... - ▸ mount MyComponent - ▸ mount_instance MyComponent.new - ERROR + ▸ mount MyComponent + ▸ mount_instance MyComponent.new + ERROR %} end # :nodoc: def mount_instance(_component : Lucky::BaseComponent.class) : Nil {% raise <<-ERROR - 'mount_instance' requires an instance of a component, not component class. + 'mount_instance' requires an instance of a component, not component class. - Try this... + Try this... - ▸ mount MyComponent - ▸ mount_instance MyComponent.new - ERROR + ▸ mount MyComponent + ▸ mount_instance MyComponent.new + ERROR %} end # :nodoc: def mount_instance(_component : Lucky::BaseComponent.class, &) : Nil {% raise <<-ERROR - 'mount_instance' requires an instance of a component, not component class. + 'mount_instance' requires an instance of a component, not component class. - Try this... + Try this... - ▸ mount MyComponent - ▸ mount_instance MyComponent.new - ERROR + ▸ mount MyComponent + ▸ mount_instance MyComponent.new + ERROR %} end diff --git a/src/lucky/page_helpers/html_text_helpers.cr b/src/lucky/page_helpers/html_text_helpers.cr index 6fe13ee3d..7669d4ca2 100644 --- a/src/lucky/page_helpers/html_text_helpers.cr +++ b/src/lucky/page_helpers/html_text_helpers.cr @@ -30,13 +30,13 @@ module Lucky::HTMLTextHelpers # ```html # "Four score and se...Read more" # ``` - def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String | Nil = nil, escape : Bool = true, blk : Nil | Proc = nil) : Nil + def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String? = nil, escape : Bool = true, blk : Proc? = nil) : Nil content = truncate_text(text, length, omission, separator) raw(escape ? HTML.escape(content) : content) blk.call if !blk.nil? && text.size > length end - def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String | Nil = nil, escape : Bool = true, &block : -> _) : Nil + def truncate(text : String, length : Int32 = 30, omission : String = "...", separator : String? = nil, escape : Bool = true, &block : -> _) : Nil truncate(text, length, omission, separator, escape, blk: block) end diff --git a/src/lucky/page_helpers/svg_inliner.cr b/src/lucky/page_helpers/svg_inliner.cr index 940c84bf9..f85a6fc85 100644 --- a/src/lucky/page_helpers/svg_inliner.cr +++ b/src/lucky/page_helpers/svg_inliner.cr @@ -33,6 +33,6 @@ module Lucky::SvgInliner end %} - raw {{svg.gsub(/