text_helpers 0.7.0 → 1.1.0

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.

Potentially problematic release.


This version of text_helpers might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 903554bdd7d36e4e370e3ee49c9b4fea2ce583c0
4
- data.tar.gz: a44bc31df0e1ee330828bc7fce8c744cef1b851a
2
+ SHA256:
3
+ metadata.gz: d4e0a6d2b19adb159000ea905c72b4023942ae268e36ac0eb9b39baf551e7460
4
+ data.tar.gz: ba520c7137fe2355dab9c1e29cbf215c2a19baccef7b246b850f188f909e81e5
5
5
  SHA512:
6
- metadata.gz: cd7cbf44933933fde4fef80f20346ce5f69acef7c5faf5842f73397db143ec3a13b59b2ada6ced119fc9500b76f0a1ff832d81d3bce9cf8f4054168c8f712a1b
7
- data.tar.gz: ce8278cd00a6b9ec4df5e4aaaf9ae6486fb5a4e7212b9f4d0528647f05a32104958b01df0fe2e333ef0350130070f41357f8ec011c8e0a6b7094e94077c3b74d
6
+ metadata.gz: c1fb87f89fbc7e42cfeab3fa224573097626b6dafd3c252076f7b13df1de5c7a8e8046b95207ba8d69dc9d50aa4290b2bd859166ef2cf17441bddad961ad8f10
7
+ data.tar.gz: 599e77b95ca58b291bf1d0348b65cfb4e7f2ff831e2a2850a2fd883df1e4fb9e6d569aecd1a209fb6cedf1df1e7aa9136be5ec3db55a6bc61b3ab2b3197d9eb5
@@ -1,3 +1,4 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2.2
3
+ - 2.6.2
4
+ - 2.7.0
@@ -0,0 +1,88 @@
1
+ # Change Log
2
+
3
+ ## [1.1.0] - 2020-12-02
4
+
5
+ ### New Features
6
+
7
+ - Add `rel=noopener` to external links (thanks to @n00dle)
8
+
9
+ ## [1.0.1] - 2020-12-02
10
+
11
+ ### Changes
12
+
13
+ - Support cascading backends by default
14
+
15
+ ## [1.0.0] - 2020-03-27
16
+
17
+ ### Changes
18
+
19
+ - **(Breaking)** Drop explicit support for Ruby versions below 2.6
20
+
21
+ ### Bug Fixes
22
+
23
+ - Properly support translations using I18n::Pluralization backend (thanks to @jhanggi)
24
+
25
+ ## [0.7.2] - 2019-07-06
26
+
27
+ ### Bug Fixes
28
+
29
+ - Improve orphaned text matcher targeting
30
+
31
+ ## [0.7.1] - 2019-07-05
32
+
33
+ ### Bug Fixes
34
+
35
+ - Prevent unnecessary non-breaking spaces in generated HTML
36
+
37
+ ### Changes
38
+
39
+ - Improve `NotImplementedError` messaging (thanks to @stephen-puiszis)
40
+ - Update README with spec setup instructions (thanks to @jhanggi)
41
+
42
+ ## [0.7.0] - 2016-05-06
43
+
44
+ ### New features
45
+
46
+ - Automatically load entire locale directory via Railtie
47
+
48
+ ## [0.6.1] - 2015-10-01
49
+
50
+ ### Changes
51
+
52
+ - Bump version requirement for Redcarpet gem to address memory leaks
53
+
54
+ ## [0.6.0] - 2015-06-15
55
+
56
+ ### New Features
57
+
58
+ - Apply `target=_blank` attribute to anchor tags pointed at external URLs
59
+
60
+ ## [0.5.3] - 2015-02-25
61
+
62
+ ### Changes
63
+
64
+ - Update spec helpers for compatibility with RSpec 3 (thanks to @gabrielg)
65
+
66
+ ## [0.5.2] - 2015-02-03
67
+
68
+ ### Changes
69
+
70
+ - Support cascading backends for interpolated keys (thanks to @gabrielg)
71
+
72
+ ## [0.5.1] - 2015-01-23
73
+
74
+ ### New Features
75
+
76
+ - Add RSpec helpers (thanks to @gabrielg)
77
+
78
+ [1.1.0]: https://github.com/ahorner/text-helpers/compare/v1.0.1...v1.1.0
79
+ [1.0.1]: https://github.com/ahorner/text-helpers/compare/v1.0.0...v1.0.1
80
+ [1.0.0]: https://github.com/ahorner/text-helpers/compare/v0.7.2...v1.0.0
81
+ [0.7.2]: https://github.com/ahorner/text-helpers/compare/v0.7.1...v0.7.2
82
+ [0.7.1]: https://github.com/ahorner/text-helpers/compare/v0.7.0...v0.7.1
83
+ [0.7.0]: https://github.com/ahorner/text-helpers/compare/v0.6.1...v0.7.0
84
+ [0.6.1]: https://github.com/ahorner/text-helpers/compare/v0.6.0...v0.6.1
85
+ [0.6.0]: https://github.com/ahorner/text-helpers/compare/v0.5.3...v0.6.0
86
+ [0.5.3]: https://github.com/ahorner/text-helpers/compare/v0.5.2...v0.5.3
87
+ [0.5.2]: https://github.com/ahorner/text-helpers/compare/v0.5.1...v0.5.2
88
+ [0.5.1]: https://github.com/ahorner/text-helpers/compare/v0.5.0...v0.5.1
data/README.md CHANGED
@@ -60,7 +60,9 @@ The controller text helpers described above can be accessed in controller specs
60
60
 
61
61
  ### Temporary/Stub Localizations
62
62
 
63
- `text_helpers/rspec.rb` contains some helpers for setting up a test localization environment during your test runs.
63
+ `text_helpers/rspec.rb` contains some helpers for setting up a test localization
64
+ environment during your test runs. You can enable the helper methods by adding
65
+ the `:text_helpers` tag to the examples that require them.
64
66
 
65
67
  To configure it, `require "text_helpers/rspec"` and configure the `before` and
66
68
  `after` hooks appropriately:
@@ -69,11 +71,13 @@ To configure it, `require "text_helpers/rspec"` and configure the `before` and
69
71
  require 'text_helpers/rspec'
70
72
 
71
73
  RSpec.configure do |config|
74
+ config.include TextHelpers::RSpec::TestHelpers, text_helpers: true
75
+
72
76
  config.before(:suite) do
73
77
  TextHelpers::RSpec.setup_spec_translations
74
78
  end
75
79
 
76
- config.after(:each) do
80
+ config.after(:each, :text_helpers) do
77
81
  TextHelpers::RSpec.reset_spec_translations
78
82
  end
79
83
  end
@@ -83,7 +87,13 @@ Temporary localizations can then be defined within your examples via the
83
87
  `#set_translation` method, like so:
84
88
 
85
89
  ```
86
- set_translation('models.user.attributes.name', 'Name')
90
+ describe "with a translation set", :text_helpers do
91
+ before do
92
+ set_translation('models.user.attributes.name', 'Name')
93
+ end
94
+
95
+ it { ... }
96
+ end
87
97
  ```
88
98
 
89
99
  ## Configuration & Initialization
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rake/testtask'
4
4
 
5
5
  Rake::TestTask.new do |t|
6
6
  t.pattern = "test/**/*_test.rb"
7
+ t.warning = false
7
8
  end
8
9
 
9
10
  task default: :test
@@ -5,10 +5,10 @@ require "text_helpers/railtie" if defined?(Rails)
5
5
  module TextHelpers
6
6
  # RaiseExceptionHandler just raises all exceptions, rather than swallowing
7
7
  # MissingTranslation ones. It's cribbed almost verbatim from
8
- # http://edgeguides.rubyonrails.org/i18n.html#customize-your-i18n-setup.
8
+ # https://guides.rubyonrails.org/i18n.html#using-different-exception-handlers.
9
9
  class RaiseExceptionHandler < I18n::ExceptionHandler
10
10
  def call(exception, locale, key, options)
11
- if exception.is_a?(I18n::MissingTranslation)
11
+ if exception.is_a?(I18n::MissingTranslation) && key.to_s != "i18n.plural.rule"
12
12
  raise exception.to_exception
13
13
  else
14
14
  super
@@ -12,7 +12,7 @@ module TextHelpers
12
12
  attributes = [
13
13
  ("href=\"#{link}\"" if link),
14
14
  ("title=\"#{title}\"" if title),
15
- ("target=\"_blank\"" if link =~ PROTOCOL_MATCHER),
15
+ ("target=\"_blank\" rel=\"noopener\"" if link.match?(PROTOCOL_MATCHER)),
16
16
  ]
17
17
 
18
18
  "<a #{attributes.compact.join(" ")}>#{content}</a>"
@@ -22,7 +22,8 @@ module TextHelpers
22
22
 
23
23
  module Translation
24
24
 
25
- ORPHAN_MATCHER = /\s(?![^<]*>)(\S+\s*<\/(?:p|li)>)/.freeze
25
+ ORPHAN_MATCHER = /(\w+)[ \t](?![^<]*>)(\S+\s*<\/(?:p|li)>)/.freeze
26
+ KEYPATH_MATCHER = /!([\w.\/]+)!/.freeze
26
27
 
27
28
  # Public: Get the I18n localized text for the passed key.
28
29
  #
@@ -34,17 +35,17 @@ module TextHelpers
34
35
  # Returns a String resulting from the I18n lookup.
35
36
  def text(key, options = {})
36
37
  options = html_safe_options(options)
37
- text = I18n.t(key, {
38
+ text = I18n.t(key, **{
38
39
  scope: self.translation_scope,
39
- default: "!#{key}!"
40
+ default: "!#{key}!",
41
+ cascade: true,
40
42
  }.merge(options)).strip
41
43
 
42
- interpolation_options = options.dup
43
- interpolation_options[:cascade] = true unless interpolation_options.has_key?(:cascade)
44
+ interpolation_options = { cascade: true }.merge(options)
44
45
 
45
46
  # Interpolate any keypaths (e.g., `!some.lookup.path/key!`) found in the text.
46
- while text =~ /!([\w._\/]+)!/ do
47
- text = text.gsub(/!([\w._\/]+)!/) { |match| I18n.t($1, interpolation_options) }
47
+ while text.match?(KEYPATH_MATCHER) do
48
+ text = text.gsub(KEYPATH_MATCHER) { |match| I18n.t($1, **interpolation_options) }
48
49
  end
49
50
 
50
51
  text = smartify(text) if options.fetch(:smart, true)
@@ -65,7 +66,7 @@ module TextHelpers
65
66
  def html(key, options = {})
66
67
  rendered = markdown(text(key, options.merge(smart: false)))
67
68
 
68
- rendered = options[:orphans] ? rendered : rendered.gsub(ORPHAN_MATCHER, '&nbsp;\1')
69
+ rendered = options[:orphans] ? rendered : rendered.gsub(ORPHAN_MATCHER, '\1&nbsp;\2')
69
70
  rendered = rendered.gsub(/<\/?p>/, '') if options[:inline]
70
71
  rendered.html_safe
71
72
  end
@@ -82,7 +83,7 @@ module TextHelpers
82
83
  smartify(@renderer.render(text))
83
84
  end
84
85
 
85
- # Protected: Auto-apply smart quotes and to the passed text.
86
+ # Internal: Auto-apply smart quotes to the passed text.
86
87
  #
87
88
  # text - A String which should be passed through the SmartyPants renderer.
88
89
  #
@@ -91,16 +92,16 @@ module TextHelpers
91
92
  Redcarpet::Render::SmartyPants.render(text)
92
93
  end
93
94
 
94
- # Protected: The proper scope for I18n translation.
95
+ # Internal: The proper scope for I18n translation.
95
96
  #
96
97
  # Must be implemented by any classes which include this module.
97
98
  #
98
99
  # Raises NotImplementedError.
99
100
  def translation_scope
100
- raise NotImplementedError
101
+ raise NotImplementedError, "must implement a public method `translation_scope` to determine I18n scope"
101
102
  end
102
103
 
103
- # Protected: Convert all passed in arguments into html-safe strings
104
+ # Internal: Convert all passed in arguments into html-safe strings
104
105
  #
105
106
  # hash - a set of key-value pairs, which converts the second argument into an html-safe string
106
107
  #
@@ -1,3 +1,3 @@
1
1
  module TextHelpers
2
- VERSION = "0.7.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,4 +1,4 @@
1
- require_relative '../../test_helper'
1
+ require_relative "../../test_helper"
2
2
 
3
3
  describe TextHelpers::Translation do
4
4
  before do
@@ -9,6 +9,7 @@ describe TextHelpers::Translation do
9
9
  before do
10
10
  @scoped_text = "Scoped lookup"
11
11
  @global_text = "Global lookup"
12
+ @single_word_text = "Single"
12
13
  @email_address = "user@example.org"
13
14
  @multiline_text = <<-MULTI.gsub(/^[ \t]+/, '')
14
15
  This is some multiline text.
@@ -30,6 +31,8 @@ describe TextHelpers::Translation do
30
31
  email_key: "<#{@email_address}>",
31
32
  test_key: "*#{@scoped_text}*",
32
33
  list_key: "* #{@scoped_text}",
34
+ single_word_list_key: "* #{@single_word_text}",
35
+ prerendered_html_key: "<ul>\n <li> Get everything you ever wanted</li>\n <li> Practically-guaranteed</li>\n </ul>",
33
36
  interpolated_key: "Global? (!test_key!)",
34
37
  interpolated_scoped_key: "Global? (!test_scoped_key!)",
35
38
  interpol_arg_key: "Interpolate global? (!interpolated_key!)",
@@ -74,6 +77,22 @@ describe TextHelpers::Translation do
74
77
  assert_equal expected, @helper.html(:list_key)
75
78
  end
76
79
 
80
+ it "does not inject `&nbsp;` entities in HTML list items unnecessarily" do
81
+ expected = <<-EXPECTED.gsub(/^[ \t]+/, '')
82
+ <ul>
83
+ <li>#{@single_word_text}</li>
84
+ </ul>
85
+ EXPECTED
86
+
87
+ assert_equal expected, @helper.html(:single_word_list_key)
88
+ end
89
+
90
+ it "correctly handles orphans in HTML with erratic whitespace" do
91
+ expected = "<ul>\n <li> Get everything you ever&nbsp;wanted</li>\n <li> Practically-guaranteed</li>\n </ul>\n"
92
+
93
+ assert_equal expected, @helper.html(:prerendered_html_key)
94
+ end
95
+
77
96
  it "does not modify HTML tags" do
78
97
  expected = "<p><a href=\"mailto:#{@email_address}\">#{@email_address}</a></p>\n"
79
98
  assert_equal expected, @helper.html(:email_key)
@@ -100,12 +119,12 @@ describe TextHelpers::Translation do
100
119
  assert_equal "<em>#{@scoped_text}</em>\n", @helper.html(:test_key, inline: true, orphans: true)
101
120
  end
102
121
 
103
- it "renders internal links without a target" do
122
+ it "renders internal links without a target or rel" do
104
123
  assert_equal "<a href=\"/internal/path\">Internal&nbsp;link</a>\n", @helper.html(:internal_link, inline: true)
105
124
  end
106
125
 
107
- it "renders external links with target='_blank'" do
108
- assert_equal "<a href=\"http://external.com\" target=\"_blank\">External&nbsp;link</a>\n", @helper.html(:external_link, inline: true)
126
+ it "renders external links with target='_blank' and rel='noopener'" do
127
+ assert_equal "<a href=\"http://external.com\" target=\"_blank\" rel=\"noopener\">External&nbsp;link</a>\n", @helper.html(:external_link, inline: true)
109
128
  end
110
129
 
111
130
  it "interpolates values wrapped in !!" do
@@ -152,10 +171,32 @@ describe TextHelpers::Translation do
152
171
  assert_equal "This is what <b>Han</b> Solo said", @helper.text(:argument_key, user: "<b>Han</b> Solo".html_safe)
153
172
  end
154
173
 
155
- it "correctly handles non-string params" do
174
+ it "correctly handles pluralized keys" do
156
175
  assert_equal "A single piece of text", @helper.text(:pluralized_key, count: 1)
157
176
  assert_equal "2 pieces of text", @helper.text(:pluralized_key, count: 2)
158
177
  end
178
+
179
+ describe "when the pluralization backend is configured and the exception handler is enabled" do
180
+ before do
181
+ @original_backend = I18n.backend
182
+ new_backend = @original_backend.dup
183
+ new_backend.extend(I18n::Backend::Pluralization)
184
+ I18n.backend = new_backend
185
+
186
+ @original_exception_handler = I18n.exception_handler
187
+ I18n.exception_handler = TextHelpers::RaiseExceptionHandler.new
188
+ end
189
+
190
+ after do
191
+ I18n.backend = @original_backend
192
+ I18n.exception_handler = @original_exception_handler
193
+ end
194
+
195
+ it "correctly handles pluralized keys" do
196
+ assert_equal "A single piece of text", @helper.text(:pluralized_key, count: 1)
197
+ assert_equal "2 pieces of text", @helper.text(:pluralized_key, count: 2)
198
+ end
199
+ end
159
200
  end
160
201
 
161
202
  describe "when no valid scope is provided" do
@@ -201,6 +242,14 @@ describe TextHelpers::Translation do
201
242
  I18n.backend = @original_backend
202
243
  end
203
244
 
245
+ it "cascades the requested key by default" do
246
+ I18n.backend.store_translations(:en, {test_scoped_key: "a translation"})
247
+ assert_equal "a translation", @helper.text(:test_scoped_key, scope: "some.unnecessary.scope")
248
+
249
+ I18n.backend.store_translations(:en, {some: {test_scoped_key: "a scoped translation"}})
250
+ assert_equal "a scoped translation", @helper.text(:test_scoped_key, scope: "some.unnecessary.scope")
251
+ end
252
+
204
253
  it "cascades the interpolated key by default" do
205
254
  I18n.backend.store_translations(:en, {test_scoped_key: "a translation"})
206
255
 
@@ -3,6 +3,6 @@ require_relative "../../test_helper"
3
3
  describe TextHelpers do
4
4
 
5
5
  it "defines a version" do
6
- TextHelpers::VERSION.wont_be_nil
6
+ assert TextHelpers::VERSION
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: text_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Horner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-06 00:00:00.000000000 Z
11
+ date: 2020-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -89,6 +89,7 @@ extra_rdoc_files: []
89
89
  files:
90
90
  - ".gitignore"
91
91
  - ".travis.yml"
92
+ - CHANGELOG.md
92
93
  - Gemfile
93
94
  - LICENSE
94
95
  - README.md
@@ -108,7 +109,7 @@ homepage: https://github.com/ahorner/text-helpers
108
109
  licenses:
109
110
  - MIT
110
111
  metadata: {}
111
- post_install_message:
112
+ post_install_message:
112
113
  rdoc_options: []
113
114
  require_paths:
114
115
  - lib
@@ -123,9 +124,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
124
  - !ruby/object:Gem::Version
124
125
  version: '0'
125
126
  requirements: []
126
- rubyforge_project:
127
- rubygems_version: 2.4.5
128
- signing_key:
127
+ rubygems_version: 3.1.4
128
+ signing_key:
129
129
  specification_version: 4
130
130
  summary: TextHelpers is a gem which supplies some basic utilities for text localization
131
131
  in Rails projects. The library is intended to make it simple to keep your application's