bemer 0.0.0 → 0.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.
- 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
|