action_component 0.1.1 → 0.2.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 +5 -5
- data/.gitignore +1 -0
- data/Gemfile.lock +66 -60
- data/README.md +5 -1
- data/action_component.gemspec +6 -4
- data/lib/action_component/base.rb +23 -1
- data/lib/action_component/callbacks.rb +29 -0
- data/lib/action_component/element_builder.rb +64 -0
- data/lib/action_component/elements.rb +7 -7
- data/lib/action_component/version.rb +1 -1
- data/lib/action_component.rb +10 -1
- data/spec/action_component/base_spec.rb +26 -2
- data/spec/action_component/callbacks_spec.rb +38 -0
- data/spec/action_component/element_builder_spec.rb +53 -0
- data/spec/action_component/elements_spec.rb +22 -8
- metadata +35 -14
- data/spec/examples.txt +0 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: b62740fabb047d12511ea452f934c17219d5f3ad7576cd6b30285b9bb4165931
|
|
4
|
+
data.tar.gz: 325d11efdc3f2a5462647c778b8b67558174e19d5e8bf7b1e0b4d24f6b10c83e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4dd0655be2c7ab277216d7eb9faf91b390b5b0a5f9e2541754af5121de6680aba924648419ea5189641ce88ad62fb5867facf0373900750ed012f82ffee478c2
|
|
7
|
+
data.tar.gz: 61a9808b49e1ebff6b3ddb7a1c50f6c53df135190d23de2c5d926bbc264965e2cf2393f74025ea2f35519e7549d7d659ffc4fa48160f198117f13714dc5c3e67
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,83 +1,89 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
action_component (0.1.
|
|
5
|
-
actionpack (>= 4)
|
|
6
|
-
activesupport (>= 4)
|
|
7
|
-
railties (>= 4)
|
|
4
|
+
action_component (0.1.4)
|
|
5
|
+
actionpack (>= 4, < 7)
|
|
6
|
+
activesupport (>= 4, < 7)
|
|
7
|
+
railties (>= 4, < 7)
|
|
8
8
|
|
|
9
9
|
GEM
|
|
10
10
|
remote: http://rubygems.org/
|
|
11
11
|
specs:
|
|
12
|
-
actionpack (
|
|
13
|
-
actionview (=
|
|
14
|
-
activesupport (=
|
|
15
|
-
rack (~> 2.0)
|
|
16
|
-
rack-test (
|
|
12
|
+
actionpack (6.1.4.1)
|
|
13
|
+
actionview (= 6.1.4.1)
|
|
14
|
+
activesupport (= 6.1.4.1)
|
|
15
|
+
rack (~> 2.0, >= 2.0.9)
|
|
16
|
+
rack-test (>= 0.6.3)
|
|
17
17
|
rails-dom-testing (~> 2.0)
|
|
18
|
-
rails-html-sanitizer (~> 1.0, >= 1.0
|
|
19
|
-
actionview (
|
|
20
|
-
activesupport (=
|
|
18
|
+
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
19
|
+
actionview (6.1.4.1)
|
|
20
|
+
activesupport (= 6.1.4.1)
|
|
21
21
|
builder (~> 3.1)
|
|
22
|
-
|
|
22
|
+
erubi (~> 1.4)
|
|
23
23
|
rails-dom-testing (~> 2.0)
|
|
24
|
-
rails-html-sanitizer (~> 1.
|
|
25
|
-
activesupport (
|
|
24
|
+
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
25
|
+
activesupport (6.1.4.1)
|
|
26
26
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
27
|
-
i18n (
|
|
28
|
-
minitest (
|
|
29
|
-
tzinfo (~>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
i18n (>= 1.6, < 2)
|
|
28
|
+
minitest (>= 5.1)
|
|
29
|
+
tzinfo (~> 2.0)
|
|
30
|
+
zeitwerk (~> 2.3)
|
|
31
|
+
builder (3.2.4)
|
|
32
|
+
concurrent-ruby (1.1.9)
|
|
33
|
+
crass (1.0.6)
|
|
34
|
+
diff-lcs (1.4.4)
|
|
35
|
+
erubi (1.10.0)
|
|
36
|
+
i18n (1.8.10)
|
|
37
|
+
concurrent-ruby (~> 1.0)
|
|
38
|
+
loofah (2.12.0)
|
|
39
|
+
crass (~> 1.0.2)
|
|
36
40
|
nokogiri (>= 1.5.9)
|
|
37
|
-
method_source (0.
|
|
38
|
-
mini_portile2 (2.1
|
|
39
|
-
minitest (5.
|
|
40
|
-
nokogiri (1.
|
|
41
|
-
mini_portile2 (~> 2.1
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
method_source (1.0.0)
|
|
42
|
+
mini_portile2 (2.6.1)
|
|
43
|
+
minitest (5.14.4)
|
|
44
|
+
nokogiri (1.12.4)
|
|
45
|
+
mini_portile2 (~> 2.6.1)
|
|
46
|
+
racc (~> 1.4)
|
|
47
|
+
racc (1.5.2)
|
|
48
|
+
rack (2.2.3)
|
|
49
|
+
rack-test (1.1.0)
|
|
50
|
+
rack (>= 1.0, < 3)
|
|
51
|
+
rails-dom-testing (2.0.3)
|
|
52
|
+
activesupport (>= 4.2.0)
|
|
53
|
+
nokogiri (>= 1.6)
|
|
54
|
+
rails-html-sanitizer (1.4.2)
|
|
55
|
+
loofah (~> 2.3)
|
|
56
|
+
railties (6.1.4.1)
|
|
57
|
+
actionpack (= 6.1.4.1)
|
|
58
|
+
activesupport (= 6.1.4.1)
|
|
53
59
|
method_source
|
|
54
|
-
rake (>= 0.
|
|
55
|
-
thor (
|
|
56
|
-
rake (
|
|
57
|
-
rspec (3.
|
|
58
|
-
rspec-core (~> 3.
|
|
59
|
-
rspec-expectations (~> 3.
|
|
60
|
-
rspec-mocks (~> 3.
|
|
61
|
-
rspec-core (3.
|
|
62
|
-
rspec-support (~> 3.
|
|
63
|
-
rspec-expectations (3.
|
|
60
|
+
rake (>= 0.13)
|
|
61
|
+
thor (~> 1.0)
|
|
62
|
+
rake (13.0.6)
|
|
63
|
+
rspec (3.10.0)
|
|
64
|
+
rspec-core (~> 3.10.0)
|
|
65
|
+
rspec-expectations (~> 3.10.0)
|
|
66
|
+
rspec-mocks (~> 3.10.0)
|
|
67
|
+
rspec-core (3.10.1)
|
|
68
|
+
rspec-support (~> 3.10.0)
|
|
69
|
+
rspec-expectations (3.10.1)
|
|
64
70
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
65
|
-
rspec-support (~> 3.
|
|
66
|
-
rspec-mocks (3.
|
|
71
|
+
rspec-support (~> 3.10.0)
|
|
72
|
+
rspec-mocks (3.10.2)
|
|
67
73
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
68
|
-
rspec-support (~> 3.
|
|
69
|
-
rspec-support (3.
|
|
70
|
-
thor (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
rspec-support (~> 3.10.0)
|
|
75
|
+
rspec-support (3.10.2)
|
|
76
|
+
thor (1.1.0)
|
|
77
|
+
tzinfo (2.0.4)
|
|
78
|
+
concurrent-ruby (~> 1.0)
|
|
79
|
+
zeitwerk (2.4.2)
|
|
74
80
|
|
|
75
81
|
PLATFORMS
|
|
76
82
|
ruby
|
|
77
83
|
|
|
78
84
|
DEPENDENCIES
|
|
79
85
|
action_component!
|
|
80
|
-
rspec
|
|
86
|
+
rspec (~> 3.5)
|
|
81
87
|
|
|
82
88
|
BUNDLED WITH
|
|
83
|
-
|
|
89
|
+
2.2.17
|
data/README.md
CHANGED
|
@@ -86,6 +86,10 @@ class PostComponent < ActionComponent::Base
|
|
|
86
86
|
div(class: 'post') do
|
|
87
87
|
h2 @post.title
|
|
88
88
|
|
|
89
|
+
# This renders a div with a class of 'published-at'
|
|
90
|
+
# Note the underscore has been replaced with a dash.
|
|
91
|
+
e.div.published_at "Published at #{l @post.published_at}"
|
|
92
|
+
|
|
89
93
|
component AuthorComponent, author: @post.author
|
|
90
94
|
|
|
91
95
|
insert simple_format(@post.content)
|
|
@@ -97,7 +101,7 @@ end
|
|
|
97
101
|
## More documentation to come
|
|
98
102
|
|
|
99
103
|
ActionComponent is new. It works just fine, but at the moment if you need more information than is given above,
|
|
100
|
-
please dive into the (
|
|
104
|
+
please dive into the (small) codebase to learn more.
|
|
101
105
|
|
|
102
106
|
## Contributing
|
|
103
107
|
|
data/action_component.gemspec
CHANGED
|
@@ -13,11 +13,13 @@ Gem::Specification.new do |s|
|
|
|
13
13
|
s.summary = %q{React-style components for Rails}
|
|
14
14
|
s.description = %q{React-style components for Rails, mixing together the controller and a DSL language for HTML views.}
|
|
15
15
|
|
|
16
|
-
s.
|
|
17
|
-
s.add_dependency "activesupport", ">= 4"
|
|
18
|
-
s.add_dependency "railties", ">= 4"
|
|
16
|
+
s.required_ruby_version = '>= 2.0'
|
|
19
17
|
|
|
20
|
-
s.
|
|
18
|
+
s.add_dependency "actionpack", [">= 4", "< 7"]
|
|
19
|
+
s.add_dependency "activesupport", [">= 4", "< 7"]
|
|
20
|
+
s.add_dependency "railties", [">= 4", "< 7"]
|
|
21
|
+
|
|
22
|
+
s.add_development_dependency "rspec", "~> 3.5"
|
|
21
23
|
|
|
22
24
|
s.files = `git ls-files`.split("\n")
|
|
23
25
|
s.test_files = `git ls-files -- spec/*`.split("\n")
|
|
@@ -8,13 +8,14 @@ module ActionComponent
|
|
|
8
8
|
class Base
|
|
9
9
|
include ActionComponent::Constraints
|
|
10
10
|
include ActionComponent::Elements
|
|
11
|
+
prepend ActionComponent::Callbacks
|
|
11
12
|
|
|
12
13
|
delegate :concat, to: :@_view
|
|
13
14
|
|
|
14
15
|
def self.render(view, opts = {})
|
|
15
16
|
component = new(view, opts)
|
|
16
17
|
component.load
|
|
17
|
-
component.
|
|
18
|
+
component.render_view
|
|
18
19
|
nil
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -35,6 +36,10 @@ module ActionComponent
|
|
|
35
36
|
raise ActionComponent::ViewMissingError, "#{self.class.name} must define a view method to be a valid component"
|
|
36
37
|
end
|
|
37
38
|
|
|
39
|
+
def render_view
|
|
40
|
+
view
|
|
41
|
+
end
|
|
42
|
+
|
|
38
43
|
private
|
|
39
44
|
|
|
40
45
|
def method_missing(method, *args, &block)
|
|
@@ -45,6 +50,15 @@ module ActionComponent
|
|
|
45
50
|
end
|
|
46
51
|
end
|
|
47
52
|
|
|
53
|
+
def text(content = nil, &block)
|
|
54
|
+
@_view.concat content if content
|
|
55
|
+
@_view.concat block.call if block
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
alias_method :text_node, :text
|
|
60
|
+
alias_method :insert, :text
|
|
61
|
+
|
|
48
62
|
def render(*args)
|
|
49
63
|
@_view.concat(@_view.render(*args))
|
|
50
64
|
end
|
|
@@ -54,5 +68,13 @@ module ActionComponent
|
|
|
54
68
|
end
|
|
55
69
|
|
|
56
70
|
alias_method :render_component, :component
|
|
71
|
+
|
|
72
|
+
def form_for(*args, &block)
|
|
73
|
+
text @_view.form_for(*args, &block)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def form_tag(*args, &block)
|
|
77
|
+
text @_view.form_tag(*args, &block)
|
|
78
|
+
end
|
|
57
79
|
end
|
|
58
80
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module ActionComponent
|
|
2
|
+
module Callbacks
|
|
3
|
+
def self.prepended(base)
|
|
4
|
+
base.class_attribute :before_render_callback_methods, :after_render_callback_methods
|
|
5
|
+
|
|
6
|
+
base.before_render_callback_methods = []
|
|
7
|
+
base.after_render_callback_methods = []
|
|
8
|
+
|
|
9
|
+
base.extend ClassMethods
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ClassMethods
|
|
13
|
+
def before_render(*methods)
|
|
14
|
+
self.before_render_callback_methods += methods
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def after_render(*methods)
|
|
18
|
+
self.after_render_callback_methods += methods
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def render_view
|
|
23
|
+
before_render_callback_methods.each { |method| send(method) }
|
|
24
|
+
result = super
|
|
25
|
+
after_render_callback_methods.each { |method| send(method) }
|
|
26
|
+
result
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module ActionComponent
|
|
2
|
+
class ElementBuilder
|
|
3
|
+
def initialize(base, element_name = nil, classes = nil, id = nil)
|
|
4
|
+
@base = base
|
|
5
|
+
@element_name = element_name
|
|
6
|
+
@classes = classes
|
|
7
|
+
@id = id
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def method_missing(method, *args, &block)
|
|
11
|
+
element_name = @element_name
|
|
12
|
+
classes = @classes
|
|
13
|
+
id = @id
|
|
14
|
+
|
|
15
|
+
command = method.to_s
|
|
16
|
+
|
|
17
|
+
command = command[-1] == '?' ? command[0..-2] : command.gsub('_', '-')
|
|
18
|
+
|
|
19
|
+
if element_name
|
|
20
|
+
if command[-1] == '!'
|
|
21
|
+
id = command[0..-2]
|
|
22
|
+
else
|
|
23
|
+
classes = classes ? "#{classes} #{command}" : command
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
element_name = command
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if !args.empty? || block
|
|
30
|
+
first, second = args
|
|
31
|
+
|
|
32
|
+
if second.is_a?(Hash)
|
|
33
|
+
build_options(classes, id, second)
|
|
34
|
+
elsif first.is_a?(Hash)
|
|
35
|
+
build_options(classes, id, first)
|
|
36
|
+
elsif first
|
|
37
|
+
second = build_options(classes, id)
|
|
38
|
+
else
|
|
39
|
+
first = build_options(classes, id)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
@base.send(:element, element_name, first, second, &block)
|
|
43
|
+
else
|
|
44
|
+
self.class.new(@base, element_name, classes, id)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def build_options(classes, id, options = {})
|
|
51
|
+
if classes
|
|
52
|
+
if options[:class]
|
|
53
|
+
options[:class] = "#{options[:class]} #{classes}"
|
|
54
|
+
else
|
|
55
|
+
options[:class] = classes
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
options[:id] = id if id
|
|
60
|
+
|
|
61
|
+
options
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -21,9 +21,6 @@ module ActionComponent
|
|
|
21
21
|
|
|
22
22
|
included do
|
|
23
23
|
define_tags *ELEMENTS
|
|
24
|
-
|
|
25
|
-
alias_method :text_node, :text
|
|
26
|
-
alias_method :insert, :text
|
|
27
24
|
end
|
|
28
25
|
|
|
29
26
|
class_methods do
|
|
@@ -40,10 +37,6 @@ module ActionComponent
|
|
|
40
37
|
|
|
41
38
|
private
|
|
42
39
|
|
|
43
|
-
def text(content)
|
|
44
|
-
@_view.concat content
|
|
45
|
-
end
|
|
46
|
-
|
|
47
40
|
def doctype(text = "html")
|
|
48
41
|
@_view.concat("<!doctype #{h(text)}>".html_safe)
|
|
49
42
|
end
|
|
@@ -51,6 +44,9 @@ module ActionComponent
|
|
|
51
44
|
def element(name, first = nil, second = nil, &block)
|
|
52
45
|
if first.is_a?(Hash)
|
|
53
46
|
opts = first
|
|
47
|
+
elsif second.is_a?(String) || second.is_a?(Symbol)
|
|
48
|
+
opts = {class: second.to_s}
|
|
49
|
+
text = first
|
|
54
50
|
else
|
|
55
51
|
opts = second
|
|
56
52
|
text = first
|
|
@@ -70,5 +66,9 @@ module ActionComponent
|
|
|
70
66
|
|
|
71
67
|
nil
|
|
72
68
|
end
|
|
69
|
+
|
|
70
|
+
def e
|
|
71
|
+
ElementBuilder.new(self)
|
|
72
|
+
end
|
|
73
73
|
end
|
|
74
74
|
end
|
data/lib/action_component.rb
CHANGED
|
@@ -3,10 +3,19 @@ end
|
|
|
3
3
|
|
|
4
4
|
require 'action_component/version'
|
|
5
5
|
|
|
6
|
+
# Rails integration
|
|
7
|
+
|
|
6
8
|
require 'action_component/action_controller_rendering'
|
|
7
9
|
require 'action_component/action_view_rendering'
|
|
10
|
+
require 'action_component/railtie'
|
|
11
|
+
|
|
12
|
+
# Base dependencies
|
|
13
|
+
|
|
14
|
+
require 'action_component/callbacks'
|
|
8
15
|
require 'action_component/constraints'
|
|
9
16
|
require 'action_component/elements'
|
|
17
|
+
require 'action_component/element_builder'
|
|
18
|
+
|
|
19
|
+
# Base
|
|
10
20
|
|
|
11
21
|
require 'action_component/base'
|
|
12
|
-
require 'action_component/railtie'
|
|
@@ -10,7 +10,7 @@ RSpec.describe ActionComponent::Base do
|
|
|
10
10
|
it "makes a new component, then calls load and view, returning nil" do
|
|
11
11
|
component = instance_double(ActionComponent::Base)
|
|
12
12
|
expect(component).to receive(:load).ordered
|
|
13
|
-
expect(component).to receive(:
|
|
13
|
+
expect(component).to receive(:render_view).ordered
|
|
14
14
|
|
|
15
15
|
expect(ActionComponent::Base).to receive(:new)
|
|
16
16
|
.with(view, {option: 'value'})
|
|
@@ -47,6 +47,12 @@ RSpec.describe ActionComponent::Base do
|
|
|
47
47
|
|
|
48
48
|
div datetime_formatter(@post.posted_at), class: "datetime"
|
|
49
49
|
|
|
50
|
+
text "!"
|
|
51
|
+
|
|
52
|
+
text do
|
|
53
|
+
"block return"
|
|
54
|
+
end
|
|
55
|
+
|
|
50
56
|
render "some_view"
|
|
51
57
|
|
|
52
58
|
component AuthorComponent, author: @post.author
|
|
@@ -58,7 +64,7 @@ RSpec.describe ActionComponent::Base do
|
|
|
58
64
|
double(
|
|
59
65
|
title: "Test Post",
|
|
60
66
|
author: "Roger Nesbitt",
|
|
61
|
-
posted_at: Time.
|
|
67
|
+
posted_at: Time.new(2016, 11, 28, 11, 9, 20),
|
|
62
68
|
)
|
|
63
69
|
end
|
|
64
70
|
|
|
@@ -74,6 +80,8 @@ RSpec.describe ActionComponent::Base do
|
|
|
74
80
|
[:concat, "content_tag [\"h2\", \"Test Post\", nil]"],
|
|
75
81
|
[:content_tag, "div", "28 November 2016 11:09", {:class=>"datetime"}],
|
|
76
82
|
[:concat, "content_tag [\"div\", \"28 November 2016 11:09\", {:class=>\"datetime\"}]"],
|
|
83
|
+
[:concat, "!"],
|
|
84
|
+
[:concat, "block return"],
|
|
77
85
|
[:render, "some_view"],
|
|
78
86
|
[:concat, "render [\"some_view\"]"],
|
|
79
87
|
[:content_tag, "div", "Roger Nesbitt", nil],
|
|
@@ -82,4 +90,20 @@ RSpec.describe ActionComponent::Base do
|
|
|
82
90
|
]
|
|
83
91
|
end
|
|
84
92
|
end
|
|
93
|
+
|
|
94
|
+
describe "auto-inserting methods" do
|
|
95
|
+
let(:view) { double }
|
|
96
|
+
|
|
97
|
+
%w(form_for form_tag).each do |method|
|
|
98
|
+
it "forwards #{method} to the view and inserts its value" do
|
|
99
|
+
expect(view).to receive(method).with(1, 2).and_yield.and_return("result")
|
|
100
|
+
expect(view).to receive(:concat).with("result")
|
|
101
|
+
|
|
102
|
+
called = false
|
|
103
|
+
subject.send(method, 1, 2) { called = true }
|
|
104
|
+
|
|
105
|
+
expect(called).to be true
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
85
109
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe ActionComponent::Callbacks do
|
|
4
|
+
class FakeComponent
|
|
5
|
+
prepend ActionComponent::Callbacks
|
|
6
|
+
|
|
7
|
+
before_render :test1
|
|
8
|
+
before_render :test2
|
|
9
|
+
after_render :test3
|
|
10
|
+
|
|
11
|
+
def test1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test2
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test3
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def view
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def render_view
|
|
24
|
+
view
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
subject { FakeComponent.new }
|
|
29
|
+
|
|
30
|
+
it "calls the before and after callbacks" do
|
|
31
|
+
expect(subject).to receive(:test1).ordered
|
|
32
|
+
expect(subject).to receive(:test2).ordered
|
|
33
|
+
expect(subject).to receive(:view).ordered.and_return('result')
|
|
34
|
+
expect(subject).to receive(:test3).ordered
|
|
35
|
+
|
|
36
|
+
expect(subject.render_view).to eq 'result'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe ActionComponent::ElementBuilder do
|
|
4
|
+
class FakeBase
|
|
5
|
+
def element(*args, &block)
|
|
6
|
+
[*args, block]
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
let(:base) { FakeBase.new }
|
|
11
|
+
|
|
12
|
+
subject { ActionComponent::ElementBuilder.new(base) }
|
|
13
|
+
|
|
14
|
+
it "builds a simple element" do
|
|
15
|
+
expect(subject.simple("test")).to eq ['simple', 'test', {}, nil]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "builds an element with a class" do
|
|
19
|
+
expect(subject.simple.blue("test")).to eq ['simple', 'test', {class: 'blue'}, nil]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "builds an element with two classes" do
|
|
23
|
+
expect(subject.simple.blue.loud("test")).to eq ['simple', 'test', {class: 'blue loud'}, nil]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "builds an element with an id" do
|
|
27
|
+
expect(subject.simple.blue!("test")).to eq ['simple', 'test', {id: 'blue'}, nil]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "converts underscores to dashes" do
|
|
31
|
+
expect(subject.simple.strong_blue("test")).to eq ['simple', 'test', {class: 'strong-blue'}, nil]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "does not convert underscores to dashes if the method ends in a ?" do
|
|
35
|
+
expect(subject.simple.strong_blue?("test")).to eq ['simple', 'test', {class: 'strong_blue'}, nil]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "merges classes with ones specified in the hash" do
|
|
39
|
+
expect(subject.simple.blue("test", testy: "very", class: "strong")).to eq ['simple', 'test', {testy: "very", class: 'strong blue'}, nil]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "passes just a block" do
|
|
43
|
+
block = -> {}
|
|
44
|
+
|
|
45
|
+
expect(subject.simple.blue(&block)).to eq ['simple', {class: 'blue'}, nil, block]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "passes a block with a hash" do
|
|
49
|
+
block = -> {}
|
|
50
|
+
|
|
51
|
+
expect(subject.simple.blue(testy: "very", &block)).to eq ['simple', {testy: "very", class: 'blue'}, nil, block]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -23,14 +23,6 @@ RSpec.describe ActionComponent::Elements do
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
describe "#text" do
|
|
27
|
-
it "concats the supplied text" do
|
|
28
|
-
subject.send(:text, "some content")
|
|
29
|
-
|
|
30
|
-
expect(view.calls).to eq [[:concat, 'some content']]
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
26
|
describe "#doctype" do
|
|
35
27
|
it "concats a doctype tag" do
|
|
36
28
|
subject.send(:doctype)
|
|
@@ -112,5 +104,27 @@ RSpec.describe ActionComponent::Elements do
|
|
|
112
104
|
}.to raise_error ActionComponent::RenderError
|
|
113
105
|
end
|
|
114
106
|
end
|
|
107
|
+
|
|
108
|
+
context "when the second argument is a string" do
|
|
109
|
+
it "converts the second argument into a hash with the class set" do
|
|
110
|
+
subject.send(:element, :name, 'text', 'blue')
|
|
111
|
+
|
|
112
|
+
expect(view.calls.first).to eq [:content_tag, :name, 'text', {class: 'blue'}]
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "when the second argument is a symbol" do
|
|
117
|
+
it "converts the second argument into a hash with the class set" do
|
|
118
|
+
subject.send(:element, :name, 'text', :blue)
|
|
119
|
+
|
|
120
|
+
expect(view.calls.first).to eq [:content_tag, :name, 'text', {class: 'blue'}]
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe "#e" do
|
|
126
|
+
it "returns an ElementBuilder" do
|
|
127
|
+
expect(subject.send(:e)).to be_a ActionComponent::ElementBuilder
|
|
128
|
+
end
|
|
115
129
|
end
|
|
116
130
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: action_component
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Roger Nesbitt
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-09-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionpack
|
|
@@ -17,6 +17,9 @@ dependencies:
|
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '4'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '7'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -24,6 +27,9 @@ dependencies:
|
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
29
|
version: '4'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: activesupport
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -31,6 +37,9 @@ dependencies:
|
|
|
31
37
|
- - ">="
|
|
32
38
|
- !ruby/object:Gem::Version
|
|
33
39
|
version: '4'
|
|
40
|
+
- - "<"
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '7'
|
|
34
43
|
type: :runtime
|
|
35
44
|
prerelease: false
|
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -38,6 +47,9 @@ dependencies:
|
|
|
38
47
|
- - ">="
|
|
39
48
|
- !ruby/object:Gem::Version
|
|
40
49
|
version: '4'
|
|
50
|
+
- - "<"
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '7'
|
|
41
53
|
- !ruby/object:Gem::Dependency
|
|
42
54
|
name: railties
|
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -45,6 +57,9 @@ dependencies:
|
|
|
45
57
|
- - ">="
|
|
46
58
|
- !ruby/object:Gem::Version
|
|
47
59
|
version: '4'
|
|
60
|
+
- - "<"
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '7'
|
|
48
63
|
type: :runtime
|
|
49
64
|
prerelease: false
|
|
50
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -52,20 +67,23 @@ dependencies:
|
|
|
52
67
|
- - ">="
|
|
53
68
|
- !ruby/object:Gem::Version
|
|
54
69
|
version: '4'
|
|
70
|
+
- - "<"
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '7'
|
|
55
73
|
- !ruby/object:Gem::Dependency
|
|
56
74
|
name: rspec
|
|
57
75
|
requirement: !ruby/object:Gem::Requirement
|
|
58
76
|
requirements:
|
|
59
|
-
- - "
|
|
77
|
+
- - "~>"
|
|
60
78
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
79
|
+
version: '3.5'
|
|
62
80
|
type: :development
|
|
63
81
|
prerelease: false
|
|
64
82
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
83
|
requirements:
|
|
66
|
-
- - "
|
|
84
|
+
- - "~>"
|
|
67
85
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
86
|
+
version: '3.5'
|
|
69
87
|
description: React-style components for Rails, mixing together the controller and
|
|
70
88
|
a DSL language for HTML views.
|
|
71
89
|
email:
|
|
@@ -84,21 +102,24 @@ files:
|
|
|
84
102
|
- lib/action_component/action_controller_rendering.rb
|
|
85
103
|
- lib/action_component/action_view_rendering.rb
|
|
86
104
|
- lib/action_component/base.rb
|
|
105
|
+
- lib/action_component/callbacks.rb
|
|
87
106
|
- lib/action_component/constraints.rb
|
|
107
|
+
- lib/action_component/element_builder.rb
|
|
88
108
|
- lib/action_component/elements.rb
|
|
89
109
|
- lib/action_component/railtie.rb
|
|
90
110
|
- lib/action_component/version.rb
|
|
91
111
|
- spec/action_component/base_spec.rb
|
|
112
|
+
- spec/action_component/callbacks_spec.rb
|
|
92
113
|
- spec/action_component/constraints_spec.rb
|
|
114
|
+
- spec/action_component/element_builder_spec.rb
|
|
93
115
|
- spec/action_component/elements_spec.rb
|
|
94
|
-
- spec/examples.txt
|
|
95
116
|
- spec/fake_view.rb
|
|
96
117
|
- spec/spec_helper.rb
|
|
97
118
|
homepage: https://github.com/mogest/action_component
|
|
98
119
|
licenses:
|
|
99
120
|
- MIT
|
|
100
121
|
metadata: {}
|
|
101
|
-
post_install_message:
|
|
122
|
+
post_install_message:
|
|
102
123
|
rdoc_options: []
|
|
103
124
|
require_paths:
|
|
104
125
|
- lib
|
|
@@ -106,22 +127,22 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
106
127
|
requirements:
|
|
107
128
|
- - ">="
|
|
108
129
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: '0'
|
|
130
|
+
version: '2.0'
|
|
110
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
132
|
requirements:
|
|
112
133
|
- - ">="
|
|
113
134
|
- !ruby/object:Gem::Version
|
|
114
135
|
version: '0'
|
|
115
136
|
requirements: []
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
signing_key:
|
|
137
|
+
rubygems_version: 3.1.6
|
|
138
|
+
signing_key:
|
|
119
139
|
specification_version: 4
|
|
120
140
|
summary: React-style components for Rails
|
|
121
141
|
test_files:
|
|
122
142
|
- spec/action_component/base_spec.rb
|
|
143
|
+
- spec/action_component/callbacks_spec.rb
|
|
123
144
|
- spec/action_component/constraints_spec.rb
|
|
145
|
+
- spec/action_component/element_builder_spec.rb
|
|
124
146
|
- spec/action_component/elements_spec.rb
|
|
125
|
-
- spec/examples.txt
|
|
126
147
|
- spec/fake_view.rb
|
|
127
148
|
- spec/spec_helper.rb
|
data/spec/examples.txt
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
example_id | status | run_time |
|
|
2
|
-
------------------------------------------------- | ------ | --------------- |
|
|
3
|
-
./spec/action_component/base_spec.rb[1:1:1] | passed | 0.01317 seconds |
|
|
4
|
-
./spec/action_component/base_spec.rb[1:2:1] | passed | 0.00018 seconds |
|
|
5
|
-
./spec/action_component/base_spec.rb[1:3:1] | passed | 0.00012 seconds |
|
|
6
|
-
./spec/action_component/base_spec.rb[1:4:1] | passed | 0.00139 seconds |
|
|
7
|
-
./spec/action_component/constraints_spec.rb[1:1] | passed | 0.00006 seconds |
|
|
8
|
-
./spec/action_component/constraints_spec.rb[1:2] | passed | 0.00012 seconds |
|
|
9
|
-
./spec/action_component/constraints_spec.rb[1:3] | passed | 0.00017 seconds |
|
|
10
|
-
./spec/action_component/constraints_spec.rb[1:4] | passed | 0.00202 seconds |
|
|
11
|
-
./spec/action_component/elements_spec.rb[1:1:1] | passed | 0.00017 seconds |
|
|
12
|
-
./spec/action_component/elements_spec.rb[1:2:1] | passed | 0.00009 seconds |
|
|
13
|
-
./spec/action_component/elements_spec.rb[1:3:1] | passed | 0.00015 seconds |
|
|
14
|
-
./spec/action_component/elements_spec.rb[1:3:2] | passed | 0.00448 seconds |
|
|
15
|
-
./spec/action_component/elements_spec.rb[1:4:1] | passed | 0.00014 seconds |
|
|
16
|
-
./spec/action_component/elements_spec.rb[1:5:1:1] | passed | 0.00015 seconds |
|
|
17
|
-
./spec/action_component/elements_spec.rb[1:5:2:1] | passed | 0.0001 seconds |
|
|
18
|
-
./spec/action_component/elements_spec.rb[1:5:3:1] | passed | 0.00019 seconds |
|
|
19
|
-
./spec/action_component/elements_spec.rb[1:5:4:1] | passed | 0.00014 seconds |
|
|
20
|
-
./spec/action_component/elements_spec.rb[1:5:5:1] | passed | 0.00148 seconds |
|
|
21
|
-
./spec/action_component/elements_spec.rb[1:5:6:1] | passed | 0.00024 seconds |
|