bemer 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +12 -0
- data/.overcommit.yml +59 -0
- data/.rspec +4 -0
- data/.rubocop.yml +12 -1
- data/.rubocop_todo.yml +3 -6
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/LICENSE-RU +23 -0
- data/README.md +2 -10
- data/Rakefile +8 -1
- data/bemer.gemspec +19 -6
- data/lib/bemer.rb +93 -2
- data/lib/bemer/asset_matcher.rb +21 -0
- data/lib/bemer/builders.rb +23 -0
- data/lib/bemer/builders/tag/element.rb +22 -0
- data/lib/bemer/builders/template.rb +57 -0
- data/lib/bemer/builders/template_list.rb +56 -0
- data/lib/bemer/builders/tree.rb +35 -0
- data/lib/bemer/builders/tree/element.rb +22 -0
- data/lib/bemer/common_template.rb +29 -0
- data/lib/bemer/component.rb +19 -0
- data/lib/bemer/component_pack.rb +39 -0
- data/lib/bemer/configuration.rb +36 -0
- data/lib/bemer/context.rb +44 -0
- data/lib/bemer/context_extentions.rb +12 -0
- data/lib/bemer/context_extentions/structure.rb +32 -0
- data/lib/bemer/context_extentions/template.rb +15 -0
- data/lib/bemer/default_template_list.rb +35 -0
- data/lib/bemer/entity.rb +94 -0
- data/lib/bemer/entity_builder.rb +126 -0
- data/lib/bemer/helpers.rb +41 -0
- data/lib/bemer/mixin_list.rb +74 -0
- data/lib/bemer/modifier_list.rb +68 -0
- data/lib/bemer/pipeline.rb +85 -0
- data/lib/bemer/pipeline/handler.rb +132 -0
- data/lib/bemer/predicate.rb +63 -0
- data/lib/bemer/railtie.rb +36 -0
- data/lib/bemer/renderer.rb +15 -0
- data/lib/bemer/tag.rb +35 -0
- data/lib/bemer/tag_builder.rb +11 -0
- data/lib/bemer/template.rb +90 -0
- data/lib/bemer/template_catalog.rb +42 -0
- data/lib/bemer/template_catalog/drawer.rb +31 -0
- data/lib/bemer/template_list.rb +62 -0
- data/lib/bemer/tree.rb +143 -0
- data/lib/bemer/tree/base_node.rb +49 -0
- data/lib/bemer/tree/node.rb +129 -0
- data/lib/bemer/tree/text_node.rb +11 -0
- data/lib/bemer/version.rb +1 -1
- data/spec/bemer/entity_spec.rb +37 -0
- data/spec/bemer/mixin_list_spec.rb +99 -0
- data/spec/bemer/modifier_list_spec.rb +83 -0
- data/spec/bemer_spec.rb +36 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/jobs/application_job.rb +4 -0
- data/spec/dummy/app/mailers/application_mailer.rb +6 -0
- data/spec/dummy/app/models/application_record.rb +5 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +5 -0
- data/spec/dummy/bin/rails +6 -0
- data/spec/dummy/bin/rake +6 -0
- data/spec/dummy/bin/setup +39 -0
- data/spec/dummy/bin/update +31 -0
- data/spec/dummy/bin/yarn +13 -0
- data/spec/dummy/config.ru +7 -0
- data/spec/dummy/config/application.rb +27 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +51 -0
- data/spec/dummy/config/environments/production.rb +84 -0
- data/spec/dummy/config/environments/test.rb +44 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +7 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +8 -0
- data/spec/dummy/config/initializers/bemer.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/inflections.rb +17 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +58 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config/secrets.yml +32 -0
- data/spec/dummy/config/spring.rb +8 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/rails_helper.rb +37 -0
- data/spec/spec_helper.rb +41 -0
- metadata +301 -7
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
|
5
|
+
module Bemer
|
6
|
+
class TemplateList < DefaultTemplateList
|
7
|
+
def initialize(view, path, cached: false, prefix: true, **options)
|
8
|
+
super(view, cached)
|
9
|
+
|
10
|
+
@options = options
|
11
|
+
@path = build_full_path(prefix, path)
|
12
|
+
end
|
13
|
+
|
14
|
+
def compile
|
15
|
+
super
|
16
|
+
|
17
|
+
add_default_templates
|
18
|
+
|
19
|
+
output = view.render(template: template, locals: { **options })
|
20
|
+
|
21
|
+
remove_template_catalog!
|
22
|
+
|
23
|
+
output
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
attr_reader :options, :path
|
29
|
+
|
30
|
+
def add_default_templates
|
31
|
+
default_template = template('index.bemhtml')
|
32
|
+
|
33
|
+
return unless view.lookup_context.exists?(default_template)
|
34
|
+
|
35
|
+
view.render(template: default_template)
|
36
|
+
end
|
37
|
+
|
38
|
+
def template(name = 'index')
|
39
|
+
[path, name].join('/')
|
40
|
+
end
|
41
|
+
|
42
|
+
def build_full_path(prefix, path)
|
43
|
+
return path if prefix.blank?
|
44
|
+
|
45
|
+
path_prefix = prefix.instance_of?(TrueClass) ? default_path_prefix(path) : prefix
|
46
|
+
|
47
|
+
[path_prefix, path].reject(&:blank?).join('/')
|
48
|
+
end
|
49
|
+
|
50
|
+
def default_path_prefix(path)
|
51
|
+
return Bemer.default_path_prefix.to_s unless Bemer.default_path_prefix.respond_to?(:call)
|
52
|
+
|
53
|
+
Bemer.default_path_prefix.call(path.to_s, view)
|
54
|
+
end
|
55
|
+
|
56
|
+
def remove_template_catalog!
|
57
|
+
return unless template_catalog.owner.eql?(object_id)
|
58
|
+
|
59
|
+
view.remove_instance_variable(:@bemer_template_catalog)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/bemer/tree.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/string/output_safety'
|
4
|
+
require 'active_support/dependencies/autoload'
|
5
|
+
|
6
|
+
module Bemer
|
7
|
+
class Tree
|
8
|
+
extend ActiveSupport::Autoload
|
9
|
+
|
10
|
+
eager_autoload do
|
11
|
+
autoload :BaseNode
|
12
|
+
autoload :Node
|
13
|
+
autoload :TextNode
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :parent_node
|
17
|
+
attr_reader :node_metadata, :pipeline
|
18
|
+
|
19
|
+
def initialize(template_catalog, **params)
|
20
|
+
@node_metadata = {}
|
21
|
+
@params = params
|
22
|
+
@parent_node = nil
|
23
|
+
@pipeline = Pipeline.new(template_catalog)
|
24
|
+
@root_nodes = []
|
25
|
+
end
|
26
|
+
|
27
|
+
def render(&block)
|
28
|
+
return unless block_given?
|
29
|
+
|
30
|
+
builder = Builders::Tree.new(self)
|
31
|
+
output = ActiveSupport::SafeBuffer.new
|
32
|
+
|
33
|
+
output << block.binding.receiver.capture(builder, &block)
|
34
|
+
output << render_root_nodes
|
35
|
+
end
|
36
|
+
|
37
|
+
def replace(node) # rubocop:disable Metrics/AbcSize
|
38
|
+
siblings = parent_node.nil? ? root_nodes : parent_node.children
|
39
|
+
metadata = node_metadata.delete(node.object_id)
|
40
|
+
position = metadata[:position]
|
41
|
+
offset = position + node.replacers.length
|
42
|
+
|
43
|
+
insert_metadata(position, metadata[:last], node.replacers)
|
44
|
+
update_metadata(offset, siblings[position..-1])
|
45
|
+
|
46
|
+
siblings[position - 1...position] = node.replacers
|
47
|
+
end
|
48
|
+
|
49
|
+
def print
|
50
|
+
root_nodes.each(&:print)
|
51
|
+
end
|
52
|
+
|
53
|
+
def add(node)
|
54
|
+
if need_replace_parent_node?
|
55
|
+
parent_node.replacers << node
|
56
|
+
else
|
57
|
+
add_metadata(node.object_id)
|
58
|
+
|
59
|
+
parent_node.nil? ? root_nodes << node : parent_node.children << node
|
60
|
+
end
|
61
|
+
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_node(block = '', element = nil, bem_cascade: nil, **options, &content)
|
66
|
+
bem_cascade = inherited_bem_cascade if bem_cascade.nil?
|
67
|
+
new_options = { **params, bem_cascade: bem_cascade, **options }
|
68
|
+
|
69
|
+
add Node.new(self, block, element, new_options, &content)
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_text_node(content = nil, &callback)
|
73
|
+
add TextNode.new(self, content, &callback)
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
attr_reader :root_nodes, :params
|
79
|
+
|
80
|
+
def inherited_bem_cascade
|
81
|
+
parent_node.nil? ? params[:bem_cascade] : parent_node.bem_cascade
|
82
|
+
end
|
83
|
+
|
84
|
+
def need_replace_parent_node?
|
85
|
+
!parent_node.nil? && parent_node.need_replace?
|
86
|
+
end
|
87
|
+
|
88
|
+
def render_root_nodes
|
89
|
+
output = ActiveSupport::SafeBuffer.new
|
90
|
+
position = 0
|
91
|
+
|
92
|
+
while position < root_nodes.length
|
93
|
+
root_node = root_nodes[position]
|
94
|
+
|
95
|
+
pipeline.run!(root_node)
|
96
|
+
|
97
|
+
next replace(root_node) if root_node.need_replace?
|
98
|
+
|
99
|
+
position += 1
|
100
|
+
|
101
|
+
output << root_node.render
|
102
|
+
end
|
103
|
+
|
104
|
+
output
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_metadata(node_id)
|
108
|
+
siblings = parent_node.nil? ? root_nodes : parent_node.children
|
109
|
+
last_sibling = siblings.last
|
110
|
+
|
111
|
+
node_metadata[last_sibling.object_id][:last] = false if last_sibling
|
112
|
+
|
113
|
+
node_metadata[node_id] = { position: siblings.length + 1, last: true }
|
114
|
+
end
|
115
|
+
|
116
|
+
def insert_metadata(position, last, replacers)
|
117
|
+
index = 0
|
118
|
+
length = replacers.length
|
119
|
+
last_position = length - 1
|
120
|
+
|
121
|
+
while index < length
|
122
|
+
data = { position: position + index, last: last && last_position.eql?(index) }
|
123
|
+
|
124
|
+
node_metadata[replacers[index].object_id] = data
|
125
|
+
|
126
|
+
index += 1
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def update_metadata(offset, siblings)
|
131
|
+
index = 0
|
132
|
+
length = siblings.length
|
133
|
+
|
134
|
+
while index < length
|
135
|
+
sibling = siblings[index]
|
136
|
+
|
137
|
+
node_metadata[sibling.object_id][:position] = offset + index
|
138
|
+
|
139
|
+
index += 1
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Bemer
|
6
|
+
class Tree
|
7
|
+
class BaseNode
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
attr_reader :entity, :entity_builder, :tree
|
11
|
+
|
12
|
+
def_delegators :entity, :attrs, :bem, :bem_cascade, :block, :block?, :cls,
|
13
|
+
:content, :elem, :elem?, :element?, :js, :mix, :mods, :name, :tag
|
14
|
+
|
15
|
+
def initialize(tree, block = '', element = nil, **options, &content)
|
16
|
+
@entity = Entity.new(block, element, options, &content)
|
17
|
+
@entity_builder = EntityBuilder.new(block, element, options, &content)
|
18
|
+
@renderer = Renderer.new
|
19
|
+
@tree = tree
|
20
|
+
end
|
21
|
+
|
22
|
+
def render
|
23
|
+
entity_builder.content = capture_content
|
24
|
+
|
25
|
+
renderer.render(entity_builder)
|
26
|
+
end
|
27
|
+
|
28
|
+
def print(level = 0)
|
29
|
+
prefix = ' ' * level
|
30
|
+
|
31
|
+
puts [prefix, name, "(#{object_id})"].join
|
32
|
+
end
|
33
|
+
|
34
|
+
def need_replace?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
attr_reader :renderer
|
41
|
+
|
42
|
+
def capture_content
|
43
|
+
return content unless content.respond_to?(:call)
|
44
|
+
|
45
|
+
content.binding.receiver.capture(&content)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/string/output_safety'
|
4
|
+
|
5
|
+
module Bemer
|
6
|
+
class Tree
|
7
|
+
class Node < BaseNode
|
8
|
+
attr_accessor :content_replaced, :need_replace, :params
|
9
|
+
attr_reader :applied_modes, :children, :replacers
|
10
|
+
|
11
|
+
alias content_replaced? content_replaced
|
12
|
+
alias need_replace? need_replace
|
13
|
+
|
14
|
+
def initialize(tree, block = '', element = nil, **options, &content)
|
15
|
+
super(tree, block, element, options, &content)
|
16
|
+
|
17
|
+
@applied_modes = Pipeline::MODES.map { |mode| [mode, false] }.to_h
|
18
|
+
@children = []
|
19
|
+
@content_replaced = false
|
20
|
+
@need_replace = false
|
21
|
+
@params = tree.parent_node.nil? ? {} : Hash[tree.parent_node.params]
|
22
|
+
@replacers = []
|
23
|
+
end
|
24
|
+
|
25
|
+
def last?
|
26
|
+
tree.node_metadata[object_id][:last]
|
27
|
+
end
|
28
|
+
|
29
|
+
def first?
|
30
|
+
position.eql?(1)
|
31
|
+
end
|
32
|
+
|
33
|
+
def position
|
34
|
+
tree.node_metadata[object_id][:position]
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_child_nodes
|
38
|
+
return content unless content.respond_to?(:call)
|
39
|
+
|
40
|
+
builder = Builders::Tree::Element.new(tree, block) if block?
|
41
|
+
|
42
|
+
content.binding.receiver.capture(builder, &content)
|
43
|
+
end
|
44
|
+
|
45
|
+
def replace_parent_and_execute
|
46
|
+
return unless block_given?
|
47
|
+
|
48
|
+
old_parent_node = tree.parent_node
|
49
|
+
tree.parent_node = self
|
50
|
+
|
51
|
+
output = yield
|
52
|
+
|
53
|
+
tree.parent_node = old_parent_node
|
54
|
+
|
55
|
+
output
|
56
|
+
end
|
57
|
+
|
58
|
+
def print(level = 0)
|
59
|
+
super(level)
|
60
|
+
|
61
|
+
children.each do |node|
|
62
|
+
node.print(level + 1)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def apply_next(template, **params)
|
67
|
+
tree.pipeline.apply_next(template, self, params)
|
68
|
+
end
|
69
|
+
|
70
|
+
def apply(mode, template, **params)
|
71
|
+
tree.pipeline.apply(mode, template, self, params)
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def capture_content
|
77
|
+
output = ActiveSupport::SafeBuffer.new
|
78
|
+
plain_text = replace_parent_and_execute { add_child_nodes } if need_add_child_nodes?
|
79
|
+
|
80
|
+
output << entity_builder.content if need_include_builder_content?
|
81
|
+
output << plain_text
|
82
|
+
output << render_child_nodes
|
83
|
+
end
|
84
|
+
|
85
|
+
def need_include_builder_content?
|
86
|
+
!entity_builder.content.respond_to?(:call) && !need_replace?
|
87
|
+
end
|
88
|
+
|
89
|
+
def need_add_child_nodes?
|
90
|
+
content.respond_to?(:call) && children.empty? && !content_replaced
|
91
|
+
end
|
92
|
+
|
93
|
+
def render_child_nodes # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
94
|
+
return if children.empty?
|
95
|
+
|
96
|
+
position = 0
|
97
|
+
output = ActiveSupport::SafeBuffer.new
|
98
|
+
|
99
|
+
replace_parent_and_execute do
|
100
|
+
while position < children.length
|
101
|
+
node = children[position]
|
102
|
+
|
103
|
+
tree.pipeline.run!(node)
|
104
|
+
|
105
|
+
next tree.replace(node) if node.need_replace?
|
106
|
+
|
107
|
+
position += 1
|
108
|
+
|
109
|
+
output << node.render
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
output
|
114
|
+
end
|
115
|
+
|
116
|
+
def initialize_copy(original)
|
117
|
+
@applied_modes = Hash[original.applied_modes]
|
118
|
+
@children = []
|
119
|
+
@content_replaced = false
|
120
|
+
@entity = original.entity.dup
|
121
|
+
@entity_builder = original.entity_builder.dup
|
122
|
+
@entity_builder.content = @entity.content
|
123
|
+
@need_replace = false
|
124
|
+
@params = Hash[original.params]
|
125
|
+
@replacers = []
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/bemer/version.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Bemer::Entity do
|
4
|
+
subject(:entity) { described_class.new(:block, cls: 'class-1 class_2', class: [:class_3, 'class_4']) }
|
5
|
+
|
6
|
+
describe '#cls' do
|
7
|
+
it { expect(entity.cls).to match_array(%w[class-1 class_2 class-3 class_4]) }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'when a block' do
|
11
|
+
subject(:block) { described_class.new(:block) }
|
12
|
+
|
13
|
+
it { is_expected.to be_block }
|
14
|
+
|
15
|
+
describe '#name' do
|
16
|
+
it { expect(block.name).to eq 'block' }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#bem_class' do
|
20
|
+
it { expect(block.bem_class).to eq 'block' }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when an element' do
|
25
|
+
subject(:elem) { described_class.new('', :elem) }
|
26
|
+
|
27
|
+
it { is_expected.to be_element }
|
28
|
+
|
29
|
+
describe '#name' do
|
30
|
+
it { expect(elem.name).to eq '__elem' }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#bem_class' do
|
34
|
+
it { expect(elem.bem_class).to eq '' }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Bemer::MixinList, focus: true do
|
4
|
+
describe 'mixins from an empty params' do
|
5
|
+
subject(:mixin_list) { described_class.new([nil, '', {}]) }
|
6
|
+
|
7
|
+
it 'returns an empty string' do
|
8
|
+
expect(mixin_list.to_s).to be_empty
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns an empty array' do
|
12
|
+
expect(mixin_list.to_a).to be_empty
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'mixins from an empty array' do
|
17
|
+
subject(:mixin_list) { described_class.new([]) }
|
18
|
+
|
19
|
+
it 'returns an empty string' do
|
20
|
+
expect(mixin_list.to_s).to be_empty
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'returns an empty array' do
|
24
|
+
expect(mixin_list.to_a).to be_empty
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'mixins from an empty hash' do
|
29
|
+
subject(:mixin_list) { described_class.new({}) }
|
30
|
+
|
31
|
+
it 'returns an empty string' do
|
32
|
+
expect(mixin_list.to_s).to be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns an empty array' do
|
36
|
+
expect(mixin_list.to_a).to be_empty
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'mixins from an array' do
|
41
|
+
subject(:mixin_list) { described_class.new([:block_name, { block_name: %i[elem_name1 elem_name2] }, block: :elem]) }
|
42
|
+
|
43
|
+
it 'returns mixins as a string' do
|
44
|
+
expect(mixin_list.to_s).to eq 'block-name block-name__elem-name1 block-name__elem-name2 block__elem'
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'returns mixins as an array' do
|
48
|
+
expect(mixin_list.to_a).to match_array %w[block-name block-name__elem-name1 block-name__elem-name2 block__elem]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'mixins from a hash' do
|
53
|
+
subject(:mixin_list) { described_class.new(block_name: [nil, :elem_name1, :elem_name2], block: :elem) }
|
54
|
+
|
55
|
+
it 'returns mixins as a string' do
|
56
|
+
expect(mixin_list.to_s).to eq 'block-name block-name__elem-name1 block-name__elem-name2 block__elem'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'returns mixins as an array' do
|
60
|
+
expect(mixin_list.to_a).to match_array %w[block-name block-name__elem-name1 block-name__elem-name2 block__elem]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'mixins from a symbol' do
|
65
|
+
subject(:mixin_list) { described_class.new(:block_name) }
|
66
|
+
|
67
|
+
it 'returns mixins as a string' do
|
68
|
+
expect(mixin_list.to_s).to eq 'block-name'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'returns mixins as an array' do
|
72
|
+
expect(mixin_list.to_a).to match_array %w[block-name]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'mixins from a string' do
|
77
|
+
subject(:mixin_list) { described_class.new('block_name block__elem') }
|
78
|
+
|
79
|
+
it 'returns mixins as a string' do
|
80
|
+
expect(mixin_list.to_s).to eq 'block_name block__elem'
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'returns mixins as an array' do
|
84
|
+
expect(mixin_list.to_a).to match_array %w[block_name block__elem]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'mixins from a hash with string values' do
|
89
|
+
subject(:mixin_list) { described_class.new('BlockName' => [nil, 'ElemName', :elem_name], 'Block' => 'ElemName') }
|
90
|
+
|
91
|
+
it 'returns mixins as a string' do
|
92
|
+
expect(mixin_list.to_s).to eq 'BlockName BlockName__ElemName BlockName__elem-name Block__ElemName'
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns mixins as an array' do
|
96
|
+
expect(mixin_list.to_a).to match_array %w[BlockName BlockName__ElemName BlockName__elem-name Block__ElemName]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|