bemer 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +229 -6
- data/docs//320/232/320/276/320/275/321/202/320/265/320/272/321/201/321/202-/321/203/320/267/320/273/320/260.md +1 -1
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_attrs_for.md +58 -0
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-bem_mix.md +0 -6
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-block_tag.md +10 -4
- data/docs//320/245/320/265/320/273/320/277/320/265/321/200-elem_tag.md +1 -1
- data/lib/bemer.rb +4 -3
- data/lib/bemer/configuration.rb +2 -0
- data/lib/bemer/entity.rb +1 -1
- data/lib/bemer/entity_builder.rb +44 -9
- data/lib/bemer/helpers.rb +10 -1
- data/lib/bemer/mixes.rb +43 -0
- data/lib/bemer/predicate.rb +1 -1
- data/lib/bemer/version.rb +1 -1
- data/spec/action_view/helpers/bem_attrs_for_spec.rb +35 -0
- data/spec/action_view/helpers/block_tag_spec.rb +1 -1
- data/spec/action_view/helpers/elem_tag_spec.rb +166 -0
- data/spec/rails_helper.rb +2 -0
- metadata +48 -31
- data/lib/bemer/mixin_list.rb +0 -74
- data/spec/bemer/mixin_list_spec.rb +0 -99
- data/spec/support/shared_examples/an_html_entity_tree_builder_method.rb +0 -21
data/lib/bemer/configuration.rb
CHANGED
@@ -18,8 +18,10 @@ module Bemer
|
|
18
18
|
def initialize # rubocop:disable Metrics/MethodLength
|
19
19
|
@asset_paths = []
|
20
20
|
@bem = false
|
21
|
+
# https://github.com/heartcombo/devise/blob/b52e642c0131f7b0d9f2dd24d8607a186f18223e/lib/devise.rb#L301
|
21
22
|
# Gem::Version.new('0.4.1') > Gem::Version.new('0.10.1')
|
22
23
|
# Здесь вроде также используют https://github.com/rspec/rspec-rails/blob/9b7ab39c027a8cb25e2ebe9e0e985756025b0549/Gemfile#L45
|
24
|
+
# https://github.com/JuanitoFatas/fast-ruby/blob/38f49f95fc7574d929de60b71791d09129c2588c/code/string/%3D%3D%3D-vs-%3D~-vs-match.rb#L20
|
23
25
|
@can_use_new_matcher = RUBY_VERSION >= '2.4.0'
|
24
26
|
@default_block_tag = :div
|
25
27
|
@default_element_tag = :div
|
data/lib/bemer/entity.rb
CHANGED
@@ -59,7 +59,7 @@ module Bemer
|
|
59
59
|
@bem_cascade = options.delete(:bem_cascade)
|
60
60
|
@css_classes = [options.delete(:class), options.delete(:cls)]
|
61
61
|
@js = options.delete(:js)
|
62
|
-
@mixins =
|
62
|
+
@mixins = Mixes.new(options.delete(:mix))
|
63
63
|
@modifiers = ModifierList.new(block, element, options.delete(:mods))
|
64
64
|
@tag = build_tag(options.delete(:tag))
|
65
65
|
@html_attrs = options
|
data/lib/bemer/entity_builder.rb
CHANGED
@@ -4,14 +4,20 @@ require 'active_support/core_ext/object/blank'
|
|
4
4
|
require 'active_support/core_ext/string/filters'
|
5
5
|
|
6
6
|
module Bemer
|
7
|
-
class EntityBuilder < Entity
|
7
|
+
class EntityBuilder < Entity # rubocop:disable Metrics/ClassLength
|
8
|
+
DATA_BEM_KEY = :'data-bem'
|
9
|
+
|
8
10
|
def attrs
|
9
11
|
attributes = Hash[super]
|
10
12
|
attributes[:class] = cls if cls.present?
|
11
13
|
|
12
14
|
return attributes unless bem?
|
13
15
|
|
14
|
-
|
16
|
+
data_bem = js
|
17
|
+
|
18
|
+
data_bem[DATA_BEM_KEY] = data_bem[DATA_BEM_KEY].to_json if data_bem.key?(DATA_BEM_KEY)
|
19
|
+
|
20
|
+
attributes.merge!(data_bem)
|
15
21
|
end
|
16
22
|
|
17
23
|
def attrs=(new_attrs, save = true)
|
@@ -39,9 +45,9 @@ module Bemer
|
|
39
45
|
def cls
|
40
46
|
return super unless bem?
|
41
47
|
|
42
|
-
|
48
|
+
i_bem = 'i-bem' if need_data_bem? || need_mixed_data_bem?
|
43
49
|
|
44
|
-
[bem_class, mods, mix, super,
|
50
|
+
[bem_class, mods, mix, super, i_bem].flatten.reject(&:blank?).uniq.join(' ')
|
45
51
|
end
|
46
52
|
|
47
53
|
def cls=(new_cls, save = true)
|
@@ -55,11 +61,18 @@ module Bemer
|
|
55
61
|
end
|
56
62
|
|
57
63
|
def js
|
58
|
-
|
64
|
+
need_data_bem = need_data_bem?
|
65
|
+
need_mixed_data_bem = need_mixed_data_bem?
|
59
66
|
|
60
|
-
|
67
|
+
return {} unless need_data_bem || need_mixed_data_bem
|
61
68
|
|
62
|
-
|
69
|
+
if !need_data_bem && need_mixed_data_bem
|
70
|
+
mixed_data_bem
|
71
|
+
else
|
72
|
+
data_bem = @js.instance_of?(TrueClass) ? {} : super
|
73
|
+
|
74
|
+
{ DATA_BEM_KEY => { name => data_bem }.merge!(mixed_data_bem[DATA_BEM_KEY]) }
|
75
|
+
end
|
63
76
|
end
|
64
77
|
|
65
78
|
def js=(new_js, save = true)
|
@@ -67,9 +80,15 @@ module Bemer
|
|
67
80
|
end
|
68
81
|
|
69
82
|
def mix=(new_mix, save = true)
|
70
|
-
|
83
|
+
new_mixes = Mixes.new(new_mix)
|
84
|
+
new_mix = new_mixes.to_a
|
71
85
|
|
72
|
-
save
|
86
|
+
if save
|
87
|
+
@mixins = new_mixes
|
88
|
+
@mix = new_mix
|
89
|
+
else
|
90
|
+
new_mix
|
91
|
+
end
|
73
92
|
end
|
74
93
|
|
75
94
|
def mods
|
@@ -93,8 +112,24 @@ module Bemer
|
|
93
112
|
save ? @tag = new_tag : new_tag
|
94
113
|
end
|
95
114
|
|
115
|
+
def need_data_bem?
|
116
|
+
bem? && @js.present? && bem_class.present?
|
117
|
+
end
|
118
|
+
|
119
|
+
def need_mixed_data_bem?
|
120
|
+
bem? && mixins.entities.any?(&:need_data_bem?)
|
121
|
+
end
|
122
|
+
|
96
123
|
protected
|
97
124
|
|
125
|
+
def mixed_data_bem
|
126
|
+
mixins.entities.each_with_object(DATA_BEM_KEY => {}) do |entity, data_bem|
|
127
|
+
next unless entity.need_data_bem?
|
128
|
+
|
129
|
+
data_bem[DATA_BEM_KEY][entity.name] = entity.js[DATA_BEM_KEY][entity.name]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
98
133
|
def bem_via_option?
|
99
134
|
!@bem.nil?
|
100
135
|
end
|
data/lib/bemer/helpers.rb
CHANGED
@@ -12,13 +12,16 @@ module Bemer
|
|
12
12
|
|
13
13
|
# Использовать mix
|
14
14
|
# Использовать mixs
|
15
|
+
# mixes
|
15
16
|
# Использовать bemer_mix
|
16
17
|
def bem_mix(*mix)
|
17
|
-
Bemer::
|
18
|
+
Bemer::Mixes.new(mix).to_s
|
18
19
|
end
|
19
20
|
|
20
21
|
# Использовать mods
|
21
22
|
# Использовать mod
|
23
|
+
# modifier
|
24
|
+
# modifiers
|
22
25
|
# Использовать bemer_mods
|
23
26
|
def bem_mods(*block_and_element, mods)
|
24
27
|
block, element = *block_and_element
|
@@ -51,5 +54,11 @@ module Bemer
|
|
51
54
|
def component_partial_path(name)
|
52
55
|
Bemer::PathResolver.new(self).resolve(name, true)
|
53
56
|
end
|
57
|
+
|
58
|
+
def bem_attrs_for(block = '', element = nil, **options)
|
59
|
+
js = options[:js].nil? ? true : options.delete(:js)
|
60
|
+
|
61
|
+
Bemer::EntityBuilder.new(block, element, options.merge(bem: true, js: js)).attrs
|
62
|
+
end
|
54
63
|
end
|
55
64
|
end
|
data/lib/bemer/mixes.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
require 'active_support/core_ext/array/wrap'
|
5
|
+
require 'active_support/core_ext/hash/slice'
|
6
|
+
|
7
|
+
module Bemer
|
8
|
+
class Mixes
|
9
|
+
def initialize(*mixes)
|
10
|
+
@mixes = Array.wrap(mixes).flatten
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_a
|
14
|
+
@to_a ||= entities.map { |e| [e.bem_class, e.mods] }.flatten.reject(&:blank?).uniq
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@to_s ||= to_a.join(' ')
|
19
|
+
end
|
20
|
+
|
21
|
+
def entities # rubocop:disable Metrics/MethodLength
|
22
|
+
@entities ||= mixes.flat_map do |mix|
|
23
|
+
if mix.is_a?(Hash)
|
24
|
+
options = mix.extract!(:js, :mods)
|
25
|
+
|
26
|
+
mix.flat_map do |block, elems|
|
27
|
+
if elems.nil?
|
28
|
+
EntityBuilder.new(block, **options, bem: true)
|
29
|
+
else
|
30
|
+
Array(elems).map { |elem| EntityBuilder.new(block, elem, **options, bem: true) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
Array(mix).flat_map { |block| EntityBuilder.new(block) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
attr_reader :mixes
|
42
|
+
end
|
43
|
+
end
|
data/lib/bemer/predicate.rb
CHANGED
@@ -7,7 +7,7 @@ module Bemer
|
|
7
7
|
@condition = options[:condition].nil? ? true : options[:condition]
|
8
8
|
@element = options[:elem]
|
9
9
|
@mask = build_mask(options[:block], options[:elem])
|
10
|
-
@mixins =
|
10
|
+
@mixins = Mixes.new(options[:mix])
|
11
11
|
@modifiers = ModifierList.new(:block, :elem, options[:mods])
|
12
12
|
@wildcard = nil
|
13
13
|
end
|
data/lib/bemer/version.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe 'bem_attrs_for helper' do
|
4
|
+
delegate :bem_attrs_for, to: :view
|
5
|
+
|
6
|
+
context 'when a block and element have no name' do
|
7
|
+
it { expect(bem_attrs_for).to be_empty }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when only a block name is specified' do
|
11
|
+
it { expect(bem_attrs_for(:block)).to include(class: 'block i-bem', 'data-bem': '{"block":{}}') }
|
12
|
+
it { expect(bem_attrs_for(:block, mods: :enabled)).to include(class: 'block block_enabled i-bem', 'data-bem': '{"block":{}}') }
|
13
|
+
it { expect(bem_attrs_for(:block, mix: { block1: :elem })).to include(class: 'block block1__elem i-bem', 'data-bem': '{"block":{}}') }
|
14
|
+
it { expect(bem_attrs_for(:block, js: { key: :val })).to include(class: 'block i-bem', 'data-bem': '{"block":{"key":"val"}}') }
|
15
|
+
it { expect(bem_attrs_for(:block, js: false)).to include(class: 'block') }
|
16
|
+
|
17
|
+
['', false].each do |elem|
|
18
|
+
it { expect(bem_attrs_for(:block, elem)).to be_empty }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when only an element name is specified' do
|
23
|
+
['', nil, false].each do |block|
|
24
|
+
it { expect(bem_attrs_for(block, :elem)).to be_empty }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when a name is specified for a block and element' do
|
29
|
+
it { expect(bem_attrs_for(:block, :elem)).to include(class: 'block__elem i-bem', 'data-bem': '{"block__elem":{}}') }
|
30
|
+
it { expect(bem_attrs_for(:block, :elem, mods: :enabled)).to include(class: 'block__elem block__elem_enabled i-bem', 'data-bem': '{"block__elem":{}}') }
|
31
|
+
it { expect(bem_attrs_for(:block, :elem, mix: :block_2)).to include(class: 'block__elem block-2 i-bem', 'data-bem': '{"block__elem":{}}') }
|
32
|
+
it { expect(bem_attrs_for(:block, :elem, js: { key: :val })).to include(class: 'block__elem i-bem', 'data-bem': '{"block__elem":{"key":"val"}}') }
|
33
|
+
it { expect(bem_attrs_for(:block, :elem, js: false)).to include(class: 'block__elem') }
|
34
|
+
end
|
35
|
+
end
|
@@ -38,7 +38,7 @@ RSpec.describe 'block_tag helper' do
|
|
38
38
|
# it_behaves_like 'a BEM entity', '<div></div>'
|
39
39
|
# it_behaves_like 'a block entity builder method', 'Helloo', :yeyeye
|
40
40
|
# it_behaves_like 'an entity builder method', 'html'
|
41
|
-
it_behaves_like 'an HTML entity tree builder method', :hello, { tag: :strong }, 'html'
|
41
|
+
# it_behaves_like 'an HTML entity tree builder method', :hello, { tag: :strong }, 'html'
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe 'elem_tag helper' do
|
4
|
+
delegate :elem_tag, to: :view
|
5
|
+
|
6
|
+
context 'when the `default_element_tag` is set to `span`' do
|
7
|
+
before do
|
8
|
+
Bemer.config.default_element_tag = :span
|
9
|
+
end
|
10
|
+
|
11
|
+
it { expect(elem_tag(:block, :elem)).to have_empty_tag(:span, with: { class: 'block__elem' }, count: 1) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when the `element_name_separator` is set to `___`' do
|
15
|
+
before do
|
16
|
+
Bemer.config.element_name_separator = '___'
|
17
|
+
end
|
18
|
+
|
19
|
+
it { expect(elem_tag(:block, :elem)).to have_empty_tag(:div, with: { class: 'block___elem' }, count: 1) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when the `modifier_name_separator` is set to `--`' do
|
23
|
+
before do
|
24
|
+
Bemer.config.modifier_name_separator = '--'
|
25
|
+
end
|
26
|
+
|
27
|
+
it { expect(elem_tag(:block, :elem, mods: :enabled)).to have_empty_tag(:div, with: { class: 'block__elem block__elem--enabled' }, count: 1) }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when the `modifier_value_separator` is set to `___`' do
|
31
|
+
before do
|
32
|
+
Bemer.config.modifier_value_separator = '___'
|
33
|
+
end
|
34
|
+
|
35
|
+
it { expect(elem_tag(:block, :elem, mods: { theme: :gray })).to have_empty_tag(:div, with: { class: 'block__elem block__elem_theme___gray' }, count: 1) }
|
36
|
+
end
|
37
|
+
|
38
|
+
# The bem parameter from the configuration does not affect the operation of elem_tag in any way.
|
39
|
+
[true, false].each do |bem|
|
40
|
+
context "when the `bem` is globally set to `#{bem}`" do
|
41
|
+
before do
|
42
|
+
Bemer.config.bem = bem
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when a block and element have no name' do
|
46
|
+
it { expect(elem_tag).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
47
|
+
it { expect(elem_tag(bem: true)).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
48
|
+
it { expect(elem_tag(js: true)).to(have_empty_tag(:div, without: { class: 'i-bem' }, count: 1)) { without_tag 'div[data-bem]' } }
|
49
|
+
|
50
|
+
['', nil, false].repeated_permutation(2).each do |block, elem|
|
51
|
+
it { expect(elem_tag(block, elem, bem: true)).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
52
|
+
it { expect(elem_tag(block, elem, js: true)).to(have_empty_tag(:div, without: { class: 'i-bem' }, count: 1)) { without_tag 'div[data-bem]' } }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when only a block name is specified' do
|
57
|
+
it { expect(elem_tag(:block, nil, bem: true)).to have_empty_tag(:div, with: { class: 'block' }, count: 1) }
|
58
|
+
it { expect(elem_tag(:block, nil, js: true)).to have_empty_tag(:div, with: { class: 'block i-bem', 'data-bem': '{"block":{}}' }, count: 1) }
|
59
|
+
|
60
|
+
['', false].each do |elem|
|
61
|
+
it { expect(elem_tag(:block, elem, bem: true)).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
62
|
+
it { expect(elem_tag(:block, elem, js: true)).to(have_empty_tag(:div, without: { class: 'i-bem' }, count: 1)) { without_tag 'div[data-bem]' } }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when only an element name is specified' do
|
67
|
+
['', nil, false].each do |block|
|
68
|
+
it { expect(elem_tag(block, :elem)).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
69
|
+
it { expect(elem_tag(block, :elem, bem: true)).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
70
|
+
it { expect(elem_tag(block, :elem, js: true)).to(have_empty_tag(:div, without: { class: 'i-bem' }, count: 1)) { without_tag 'div[data-bem]' } }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when a name is specified for a block and element' do
|
75
|
+
# Entity name
|
76
|
+
it { expect(elem_tag(:block_name, :elem_name)).to have_empty_tag(:div, with: { class: 'block-name__elem-name' }, count: 1) }
|
77
|
+
it { expect(elem_tag('Block_Name', 'Elem_Name')).to have_empty_tag(:div, with: { class: 'Block_Name__Elem_Name' }, count: 1) }
|
78
|
+
it { expect(elem_tag(:Block_Name, :Elem_Name)).to have_empty_tag(:div, with: { class: 'Block-Name__Elem-Name' }, count: 1) }
|
79
|
+
it { expect(elem_tag('BlockName', 'ElemName')).to have_empty_tag(:div, with: { class: 'BlockName__ElemName' }, count: 1) }
|
80
|
+
|
81
|
+
# bem parameter
|
82
|
+
it { expect(elem_tag(:block, :elem, mix: :css_mixin, mods: :enabled, js: true, cls: :css_class)).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled css-mixin css-class i-bem', 'data-bem': '{"block__elem":{}}' }, count: 1) }
|
83
|
+
it { expect(elem_tag(:block, :elem, bem: true, mix: :css_mixin, mods: :enabled, js: true, cls: :css_class)).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled css-mixin css-class i-bem', 'data-bem': '{"block__elem":{}}' }, count: 1) }
|
84
|
+
it { expect(elem_tag(:block, :elem, bem: false, mix: :css_mixin, mods: :enabled, js: true, cls: :css_class)).to(have_empty_tag(:div, with: { class: 'css-class' }, without: { class: 'block__elem block__elem_enabled css-mixin i-bem' }, count: 1)) { without_tag 'div[data-bem]' } }
|
85
|
+
|
86
|
+
# bem_cascade parameter
|
87
|
+
it { expect(elem_tag(:block, :elem, bem_cascade: false)).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
88
|
+
it { expect(elem_tag(:block, :elem, bem: true, bem_cascade: false)).to have_empty_tag(:div, with: { class: 'block__elem' }, count: 1) }
|
89
|
+
it { expect(elem_tag(:block, :elem, bem: false, bem_cascade: true)).to(have_empty_tag(:div, count: 1)) { without_tag 'div[class]' } }
|
90
|
+
|
91
|
+
# cls and class parameters
|
92
|
+
it { expect(elem_tag(:block, :elem, cls: :css_class)).to have_empty_tag(:div, with: { class: 'block__elem css-class' }, count: 1) }
|
93
|
+
it { expect(elem_tag(:block, :elem, class: :css_class)).to have_empty_tag(:div, with: { class: 'block__elem css-class' }, count: 1) }
|
94
|
+
it { expect(elem_tag(:block, :elem, class: :css_class1, cls: :css_class2)).to have_empty_tag(:div, with: { class: 'block__elem css-class1 css-class2' }, count: 1) }
|
95
|
+
it { expect(elem_tag(:block, :elem, class: 'css_class1', cls: 'css_class2')).to have_empty_tag(:div, with: { class: 'block__elem css_class1 css_class2' }, count: 1) }
|
96
|
+
it { expect(elem_tag(:block, :elem, class: ['css_class1', :css_class2])).to have_empty_tag(:div, with: { class: 'block__elem css_class1 css-class2' }, count: 1) }
|
97
|
+
it { expect(elem_tag(:block, :elem, cls: ['css_class1', :css_class2])).to have_empty_tag(:div, with: { class: 'block__elem css_class1 css-class2' }, count: 1) }
|
98
|
+
|
99
|
+
# js parameter
|
100
|
+
it { expect(elem_tag(:block, :elem, js: true)).to have_empty_tag(:div, with: { class: 'block__elem i-bem', 'data-bem': '{"block__elem":{}}' }, count: 1) }
|
101
|
+
it { expect(elem_tag(:block, :elem, js: [1, 2])).to have_empty_tag(:div, with: { class: 'block__elem i-bem', 'data-bem': '{"block__elem":[1,2]}' }, count: 1) }
|
102
|
+
it { expect(elem_tag(:block, :elem, js: { key: :val })).to have_empty_tag(:div, with: { class: 'block__elem i-bem', 'data-bem': '{"block__elem":{"key":"val"}}' }, count: 1) }
|
103
|
+
|
104
|
+
# mix parameter
|
105
|
+
it { expect(elem_tag(:block, :elem, mix: :css_mixin)).to have_empty_tag(:div, with: { class: 'block__elem css-mixin' }, count: 1) }
|
106
|
+
it { expect(elem_tag(:block, :elem, mix: ['css_mixin', :block_name, block2: :elem])).to have_empty_tag(:div, with: { class: 'block__elem css_mixin block-name block2__elem' }, count: 1) }
|
107
|
+
it { expect(elem_tag(:block, :elem, mix: { block_name: :elem })).to have_empty_tag(:div, with: { class: 'block__elem block-name__elem' }, count: 1) }
|
108
|
+
it { expect(elem_tag(:block, :elem, mix: { block_name: :elem, js: true })).to have_empty_tag(:div, with: { class: 'block__elem block-name__elem i-bem', 'data-bem': '{"block-name__elem":{}}' }, count: 1) }
|
109
|
+
it { expect(elem_tag(:block, :elem, js: true, mix: { block_1: :elem, js: { key: :val } })).to have_empty_tag(:div, with: { class: 'block__elem block-1__elem i-bem', 'data-bem': '{"block__elem":{},"block-1__elem":{"key":"val"}}' }, count: 1) }
|
110
|
+
it { expect(elem_tag(:block, :elem, js: true, mix: { block: :elem, js: { key: :val } })).to have_empty_tag(:div, with: { class: 'block__elem i-bem', 'data-bem': '{"block__elem":{"key":"val"}}' }, count: 1) }
|
111
|
+
it { expect(elem_tag(:block, :elem, mix: { block_name: :elem, mods: :enabled })).to have_empty_tag(:div, with: { class: 'block__elem block-name__elem block-name__elem_enabled' }, count: 1) }
|
112
|
+
it { expect(elem_tag(:block, :elem, mix: [:mix, block_name: :elem, js: true])).to have_empty_tag(:div, with: { class: 'block__elem mix block-name__elem i-bem', 'data-bem': '{"block-name__elem":{}}' }, count: 1) }
|
113
|
+
it { expect(elem_tag(:block, :elem, mix: [{ block_1: nil, mods: :enabled, js: { key: :val } }, { block_name: :elem, js: true }])).to have_empty_tag(:div, with: { class: 'block__elem block-1 block-1_enabled block-name__elem i-bem', 'data-bem': '{"block-1":{"key":"val"},"block-name__elem":{}}' }, count: 1) }
|
114
|
+
it { expect(elem_tag(:block, :elem, mix: [:block_1, block2: %i[elem1 elem2], js: true])).to have_empty_tag(:div, with: { class: 'block__elem block-1 block2__elem1 block2__elem2 i-bem', 'data-bem': '{"block2__elem1":{},"block2__elem2":{}}' }, count: 1) }
|
115
|
+
it { expect(elem_tag(:block, :elem, mix: { block2: %i[elem1 elem2], js: true })).to have_empty_tag(:div, with: { class: 'block__elem block2__elem1 block2__elem2 i-bem', 'data-bem': '{"block2__elem1":{},"block2__elem2":{}}' }, count: 1) }
|
116
|
+
|
117
|
+
# mods parameter
|
118
|
+
it { expect(elem_tag(:block, :elem, mods: :enabled)).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled' }, count: 1) }
|
119
|
+
it { expect(elem_tag(:block, :elem, mods: { enabled: true })).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled' }, count: 1) }
|
120
|
+
it { expect(elem_tag(:block, :elem, mods: { enabled: 'true' })).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled_true' }, count: 1) }
|
121
|
+
it { expect(elem_tag(:block, :elem, mods: { enabled: false })).to have_empty_tag(:div, with: { class: 'block__elem' }, without: { class: 'block__elem_enabled' }, count: 1) }
|
122
|
+
it { expect(elem_tag(:block, :elem, mods: { enabled: 'false' })).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled_false' }, count: 1) }
|
123
|
+
it { expect(elem_tag(:block, :elem, mods: { enabled: '' })).to have_empty_tag(:div, with: { class: 'block__elem' }, without: { class: 'block__elem_enabled' }, count: 1) }
|
124
|
+
it { expect(elem_tag(:block, :elem, mods: { enabled: nil })).to have_empty_tag(:div, with: { class: 'block__elem' }, without: { class: 'block__elem_enabled' }, count: 1) }
|
125
|
+
it { expect(elem_tag(:block, :elem, mods: { enabled: 'nil' })).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled_nil' }, count: 1) }
|
126
|
+
it { expect(elem_tag(:block, :elem, mods: [:enabled, size: :small])).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled block__elem_size_small' }, count: 1) }
|
127
|
+
it { expect(elem_tag(:block, :elem, mods: [:enabled, %i[size small], %i[size large]])).to have_empty_tag(:div, with: { class: 'block__elem block__elem_enabled block__elem_size_large' }, count: 1) }
|
128
|
+
|
129
|
+
# tag parameter
|
130
|
+
it { expect(elem_tag(:block, :elem, tag: :span)).to have_empty_tag(:span, with: { class: 'block__elem' }, count: 1) }
|
131
|
+
it { expect(elem_tag(:block, :elem, tag: '', content: 'Content')).to eq 'Content' }
|
132
|
+
it { expect(elem_tag(:block, :elem, tag: '', content: '')).to eq '' }
|
133
|
+
# got: nil
|
134
|
+
# it { expect(elem_tag(:block, :elem, tag: '')).to eq '' }
|
135
|
+
it { expect(elem_tag(:block, :elem, tag: false, content: 'Content')).to eq 'Content' }
|
136
|
+
it { expect(elem_tag(:block, :elem, tag: false, content: '')).to eq '' }
|
137
|
+
# got: nil
|
138
|
+
# it { expect(elem_tag(:block, :elem, tag: false)).to eq '' }
|
139
|
+
it { expect(elem_tag(:block, :elem, tag: nil, content: 'Content')).to have_tag(:div, with: { class: 'block__elem' }, text: 'Content', count: 1) }
|
140
|
+
|
141
|
+
# attributes
|
142
|
+
it { expect(elem_tag(:block, :elem, data: { key: :val })).to have_empty_tag(:div, with: { class: 'block__elem', 'data-key': 'val' }, count: 1) }
|
143
|
+
it { expect(elem_tag(:block, :elem, 'data-key': :val)).to have_empty_tag(:div, with: { class: 'block__elem', 'data-key': 'val' }, count: 1) }
|
144
|
+
it { expect(elem_tag(:block, :elem, data: { key: :val }, 'data-key2': :val)).to have_empty_tag(:div, with: { class: 'block__elem', 'data-key': 'val', 'data-key2': 'val' }, count: 1) }
|
145
|
+
it { expect(elem_tag(:block, :elem, tag: :a, href: '#')).to have_empty_tag(:a, with: { class: 'block__elem', href: '#' }, count: 1) }
|
146
|
+
|
147
|
+
# content parameter
|
148
|
+
it { expect(elem_tag(:block, :elem, content: 'Content')).to have_tag(:div, with: { class: 'block__elem' }, text: 'Content', count: 1) }
|
149
|
+
|
150
|
+
it do # rubocop:disable RSpec/ExampleLength
|
151
|
+
html = elem_tag :block, :elem do
|
152
|
+
elem_tag :block, :elem1, content: 'Content' do
|
153
|
+
'<div></div>'.html_safe
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
expect(html).to have_tag(:div, with: { class: 'block__elem' }, count: 1) do
|
158
|
+
with_tag :div, with: { class: 'block__elem1' }, count: 1 do
|
159
|
+
with_tag :div, without: { class: 'block__elem1' }, blank: true, count: 1
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
data/spec/rails_helper.rb
CHANGED
@@ -7,6 +7,7 @@ require_relative 'dummy/config/environment'
|
|
7
7
|
require 'rspec/rails'
|
8
8
|
require 'spec_helper'
|
9
9
|
require 'fuubar'
|
10
|
+
require 'rspec-html-matchers'
|
10
11
|
|
11
12
|
RSpec.configure do |config|
|
12
13
|
# RSpec Rails can automatically mix in different behaviours to your tests
|
@@ -36,4 +37,5 @@ RSpec.configure do |config|
|
|
36
37
|
end
|
37
38
|
|
38
39
|
config.include Bemer::Test::ConfigurationHelpers
|
40
|
+
config.include RSpecHtmlMatchers
|
39
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bemer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Grigorev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 2.2.0
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.16'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.16'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: bundler-audit
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,14 +86,14 @@ dependencies:
|
|
100
86
|
requirements:
|
101
87
|
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: 12.3.
|
89
|
+
version: 12.3.3
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
94
|
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: 12.3.
|
96
|
+
version: 12.3.3
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: rspec
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +108,20 @@ dependencies:
|
|
122
108
|
- - "~>"
|
123
109
|
- !ruby/object:Gem::Version
|
124
110
|
version: 3.9.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec-html-matchers
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.9.2
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.9.2
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: rspec-rails
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,28 +142,42 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 0.
|
145
|
+
version: 0.68.1
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.68.1
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop-performance
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 1.3.0
|
146
160
|
type: :development
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
164
|
- - "~>"
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
166
|
+
version: 1.3.0
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: rubocop-rspec
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
171
|
- - "~>"
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: 1.
|
173
|
+
version: 1.38.1
|
160
174
|
type: :development
|
161
175
|
prerelease: false
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
178
|
- - "~>"
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: 1.
|
180
|
+
version: 1.38.1
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: wwtd
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -192,7 +206,8 @@ dependencies:
|
|
192
206
|
- - ">="
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: 3.2.22
|
195
|
-
description: Build reusable UI components for Rails applications
|
209
|
+
description: Build reusable UI components for Rails applications with the ability
|
210
|
+
to use the BEM methodology.
|
196
211
|
email: vill@rubyinventory.org
|
197
212
|
executables: []
|
198
213
|
extensions: []
|
@@ -205,6 +220,7 @@ extra_rdoc_files:
|
|
205
220
|
- docs/Режимы.md
|
206
221
|
- docs/Создание-и-использование-UI-компонент.md
|
207
222
|
- docs/Файловая-структура.md
|
223
|
+
- docs/Хелпер-bem_attrs_for.md
|
208
224
|
- docs/Хелпер-bem_mix.md
|
209
225
|
- docs/Хелпер-bem_mods.md
|
210
226
|
- docs/Хелпер-block_tag.md
|
@@ -228,6 +244,7 @@ files:
|
|
228
244
|
- docs/Режимы.md
|
229
245
|
- docs/Создание-и-использование-UI-компонент.md
|
230
246
|
- docs/Файловая-структура.md
|
247
|
+
- docs/Хелпер-bem_attrs_for.md
|
231
248
|
- docs/Хелпер-bem_mix.md
|
232
249
|
- docs/Хелпер-bem_mods.md
|
233
250
|
- docs/Хелпер-block_tag.md
|
@@ -260,7 +277,7 @@ files:
|
|
260
277
|
- lib/bemer/entity.rb
|
261
278
|
- lib/bemer/entity_builder.rb
|
262
279
|
- lib/bemer/helpers.rb
|
263
|
-
- lib/bemer/
|
280
|
+
- lib/bemer/mixes.rb
|
264
281
|
- lib/bemer/modifier_list.rb
|
265
282
|
- lib/bemer/path_resolver.rb
|
266
283
|
- lib/bemer/pipeline.rb
|
@@ -280,10 +297,11 @@ files:
|
|
280
297
|
- lib/bemer/tree/node.rb
|
281
298
|
- lib/bemer/tree/text_node.rb
|
282
299
|
- lib/bemer/version.rb
|
300
|
+
- spec/action_view/helpers/bem_attrs_for_spec.rb
|
283
301
|
- spec/action_view/helpers/block_tag_spec.rb
|
302
|
+
- spec/action_view/helpers/elem_tag_spec.rb
|
284
303
|
- spec/bemer/entity_builder_spec.rb
|
285
304
|
- spec/bemer/entity_spec.rb
|
286
|
-
- spec/bemer/mixin_list_spec.rb
|
287
305
|
- spec/bemer/modifier_list_spec.rb
|
288
306
|
- spec/bemer/railtie_spec.rb
|
289
307
|
- spec/bemer_spec.rb
|
@@ -301,7 +319,6 @@ files:
|
|
301
319
|
- spec/rails_helper.rb
|
302
320
|
- spec/spec_helper.rb
|
303
321
|
- spec/support/bemer.rb
|
304
|
-
- spec/support/shared_examples/an_html_entity_tree_builder_method.rb
|
305
322
|
homepage:
|
306
323
|
licenses:
|
307
324
|
- MIT
|
@@ -325,16 +342,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
325
342
|
- !ruby/object:Gem::Version
|
326
343
|
version: 2.2.0
|
327
344
|
requirements: []
|
328
|
-
|
329
|
-
rubygems_version: 2.7.7
|
345
|
+
rubygems_version: 3.0.3
|
330
346
|
signing_key:
|
331
347
|
specification_version: 4
|
332
|
-
summary: Build reusable UI components for Rails applications
|
348
|
+
summary: Build reusable UI components for Rails applications with the ability to use
|
349
|
+
the BEM methodology.
|
333
350
|
test_files:
|
351
|
+
- spec/action_view/helpers/bem_attrs_for_spec.rb
|
334
352
|
- spec/action_view/helpers/block_tag_spec.rb
|
353
|
+
- spec/action_view/helpers/elem_tag_spec.rb
|
335
354
|
- spec/bemer/entity_builder_spec.rb
|
336
355
|
- spec/bemer/entity_spec.rb
|
337
|
-
- spec/bemer/mixin_list_spec.rb
|
338
356
|
- spec/bemer/modifier_list_spec.rb
|
339
357
|
- spec/bemer/railtie_spec.rb
|
340
358
|
- spec/bemer_spec.rb
|
@@ -352,4 +370,3 @@ test_files:
|
|
352
370
|
- spec/rails_helper.rb
|
353
371
|
- spec/spec_helper.rb
|
354
372
|
- spec/support/bemer.rb
|
355
|
-
- spec/support/shared_examples/an_html_entity_tree_builder_method.rb
|