text_helpers 0.7.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.

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