-
-
Save danieldocki/ca81f8f67cdf9a30a2bd7f38111378d6 to your computer and use it in GitHub Desktop.
Revisions
-
serradura revised this gist
Feb 11, 2019 . 1 changed file with 9 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -190,7 +190,7 @@ def test_component_composition # -- Feature: global aliases -- class UI::Button < UI::Component set name: :button, global: true template { button { data } } end @@ -212,7 +212,7 @@ class UI::Button2 < UI::Component end class UI::Button4 < UI::Component set name: :button4 template { button { data } } end @@ -236,11 +236,17 @@ class UI::Button4 < UI::Component class UI::Button5 < UI::Component namespace :foo set name: :button5 template { button { data } } end # class UI::Button5 < UI::Component # set name: :button5, namespace: :foo # template { button { data } } # end UI.button5 # => raises NoMethodError UI[:foo].button5.call('My button') # => "<button>My Button</button>\n" -
serradura revised this gist
Feb 11, 2019 . 1 changed file with 15 additions and 20 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -79,9 +79,10 @@ def build_html_with(data) end def apply_defaults_to(data) return data || @defaults unless data.is_a?(Hash) return @defaults.merge(data) if @defaults.is_a?(Hash) data.empty? ? @defaults : data end end end @@ -104,9 +105,9 @@ class HelloWorld < UI::Component end def test_hello_world_component expected = "<span class=\"bar\" id=\"foo\">Hello World</span>\n" assert expected == HelloWorld.call end class Greet < UI::Component @@ -122,15 +123,15 @@ class Greet < UI::Component def test_greet_component expected_default_name = "<span class=\"bar\" id=\"foo\">Hello John Doe</span>\n" assert(expected_default_name == Greet.call) expected_rodrigo_name = "<span class=\"bar\" id=\"foo\">Hello Rodrigo</span>\n" assert(expected_rodrigo_name == Greet.call(name: 'Rodrigo')) expected_collection = [expected_default_name, expected_rodrigo_name] assert(expected_collection == [{}, {name: 'Rodrigo'}].map(&Greet)) end class Number < UI::Component @@ -144,33 +145,27 @@ class Number < UI::Component def test_number_component expected_number_zero = "<strong>0</strong>\n" assert(expected_number_zero == Number.call) expected_number_one = "<strong>1</strong>\n" assert(expected_number_one == Number.call(1)) expected_collection = [expected_number_zero, expected_number_one] assert(expected_collection == [nil, 1].map(&Number)) end def test_fn_component number = UI::Component.fn do strong { text(data) } end expected_number_one = "<strong>1</strong>\n" assert(expected_number_one == number.call(1)) assert([expected_number_one] == [1].map(&number)) end def test_component_composition @@ -180,9 +175,9 @@ def test_component_composition strong { text(content) } end assert("<div><strong>1</strong>\n</div>\n" == container.call(number.(content: 1))) assert(["<div><strong>1</strong>\n</div>\n"] == [content: 1].map(&number).map(&container)) end end -
serradura revised this gist
Feb 11, 2019 . 1 changed file with 10 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -216,15 +216,25 @@ class UI::Button2 < UI::Component template { button.btn3! { data } } end class UI::Button4 < UI::Component name :button4 template { button { data } } end UI::Components.add UI::Button4 UI.button.call('My button') # => "<button>My Button</button>\n" UI.button1.call('My button') # => "<button>My Button</button>\n" UI.button2.call('My button') # => "<button class=\"btn2\">My Button</button>\n" UI.button3.call('My button') # => "<button id=\"btn3\">My Button</button>\n" UI.button4.call('My button') # => "<button>My Button</button>\n" UI.button { 'My button' } # => "<button>My Button</button>\n" UI.button1 { 'My button' } # => "<button>My Button</button>\n" UI.button2 { 'My button' } # => "<button class=\"btn2\">My Button</button>\n" UI.button3 { 'My button' } # => "<button id=\"btn3\">My Button</button>\n" UI.button4 { 'My button' } # => "<button>My Button</button>\n" # -- Feature: Namespace -- -
serradura revised this gist
Feb 11, 2019 . 1 changed file with 97 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -21,6 +21,10 @@ def data=(value) end def data; @data; end def content @data[:content] || @data['content'.freeze] if @data.respond_to?(:[]) end end end @@ -173,17 +177,105 @@ def test_component_composition container = UI.component { div data } number = UI.component do strong { text(content) } end assert "<div><strong>1</strong>\n</div>\n", container.call(number.(content: 1)) assert ["<div><strong>1</strong>\n</div>\n"], [content: 1].map(&number).map(&container) end end # == test runner == Microtest.call # == ideas == # -- Feature: global aliases -- class UI::Button < UI::Component name :button, global: true template { button { data } } end class UI::Button1 < UI::Component global_name :button template { button { data } } end class UI::Button2 < UI::Component template { button.btn2 { data } } end UI::Components.add :button2, UI::Button2 UI::Components.add :button3 do template { button.btn3! { data } } end UI.button.call('My button') # => "<button>My Button</button>\n" UI.button1.call('My button') # => "<button>My Button</button>\n" UI.button2.call('My button') # => "<button class=\"btn2\">My Button</button>\n" UI.button3.call('My button') # => "<button id=\"btn3\">My Button</button>\n" UI.button { 'My button' } # => "<button>My Button</button>\n" UI.button1 { 'My button' } # => "<button>My Button</button>\n" UI.button2 { 'My button' } # => "<button class=\"btn2\">My Button</button>\n" UI.button3 { 'My button' } # => "<button id=\"btn3\">My Button</button>\n" # -- Feature: Namespace -- class UI::Button5 < UI::Component namespace :foo name :button5 template { button { data } } end UI.button5 # => raises NoMethodError UI[:foo].button5.call('My button') # => "<button>My Button</button>\n" UI[:foo].button5 { 'My button' } # => "<button>My Button</button>\n" foo_components = UI[:foo] foo_components.button5 # => "<button>My Button</button>\n" # -- Feature: SETUP -- class UI::Hello1 < UI::Component template { span data[:name] } setup do |data| data[:name] = upcase(data[:name]) end def upcase(value) String(value).upcase end end hello1 = UI::Hello1.new hello1.call name: :foo # => "<span>FOO</span>\n" hello1.upcase :foo # => 'FOO' class UI::Hello2 < UI::Component template { span data[:name] } def setup(data) data[:name] = upcase(data[:name]) end private def upcase(value) String(value).upcase end end hello2 = UI::Hello2.new hello2.call name: :foo # => "<span>FOO</span>\n" hello2.upcase :foo # NoMethodError (private method) -
serradura revised this gist
Feb 10, 2019 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,3 @@ # frozen_string_literal: true # == Gemfile == -
serradura revised this gist
Feb 10, 2019 . 1 changed file with 8 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -83,6 +83,12 @@ def apply_defaults_to(data) end end module UI def self.component(&block) UI::Component.fn(&block) end end # == test == class UITest < Microtest::Test @@ -165,9 +171,9 @@ def test_fn_component end def test_component_composition container = UI.component { div data } number = UI.component do strong { text(data) } end -
serradura revised this gist
Feb 10, 2019 . 3 changed files with 184 additions and 221 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,184 @@ # frozen_string_literal: true # == Gemfile == require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'u-test', '0.9.0' gem 'nokogiri', '>= 1.5' end # == lib == module UI module DataAccessor def data=(value) @data = value end def data; @data; end end end module UI require 'cgi' require 'nokogiri/html' class Component def self.fn(&block) new(block) end def self.call(data = {}) new.call(data) end def self.to_proc -> (data = {}) { call(data) } end def self.template(&block) define_method(:__template) { block } end def self.defaults(data = {}) define_method(:__defaults) { data } end def initialize(fn = nil) @fn = fn || __template @defaults = respond_to?(:__defaults) ? __defaults : {} end def call(data = nil) CGI.unescapeHTML(build_html_with(data)) end def to_proc -> (data) { call(data) } end private def build_html_with(data) builder = Nokogiri::HTML::Builder.new builder.context = builder builder.extend(DataAccessor) builder.data = apply_defaults_to(data) builder.instance_eval(&@fn) builder.to_html.sub!(/<!DOCTYPE.*[^>]/, '') end def apply_defaults_to(data) return @defaults.merge(data) if [data, @defaults].all?(Hash) data || @defaults end end end # == test == class UITest < Microtest::Test class HelloWorld < UI::Component template do span.bar.foo! { text("Hello World") } end end def test_hello_world_component expected = "<span class=\"bold\">Hello world</span>\n" assert expected, HelloWorld.call end class Greet < UI::Component defaults name: 'John Doe' template do span.bar.foo! { text("Hello #{data[:name]}") } end end def test_greet_component expected_default_name = "<span class=\"bar\" id=\"foo\">Hello John Doe</span>\n" assert expected_default_name, Greet.call expected_rodrigo_name = "<span class=\"bar\" id=\"foo\">Hello Rodrigo</span>\n" assert expected_rodrigo_name, Greet.call(name: 'Rodrigo') expected_collection = [expected_default_name, expected_rodrigo_name] assert expected_collection, [{}, {name: 'Rodrigo'}].map(&Greet) end class Number < UI::Component defaults 0 template do strong { text(data) } end end def test_number_component expected_number_zero = "<strong>0</strong>\n" assert expected_number_zero, Number.call expected_number_one = "<strong>1</strong>\n" assert expected_number_one, Number.call(1) expected_collection = [expected_number_zero, expected_number_one] assert expected_collection, [nil, 1].map(&Number) end def test_fn_component number = UI::Component.fn do strong { text(data) } end expected_number_zero = "<strong>0</strong>\n" assert expected_number_zero, number.call expected_number_one = "<strong>1</strong>\n" assert expected_number_one, number.call(1) expected_collection = [expected_number_zero, expected_number_one] assert expected_collection, [nil, 1].map(&number) end def test_component_composition container = UI::Component.fn { div data } number = UI::Component.fn do strong { text(data) } end assert "<div><strong>0</strong>\n</div>\n", container.call(number.call) assert "<div><strong>1</strong>\n</div>\n", container.call(number.(1)) assert ["<div><strong>1</strong>\n</div>\n"], [1].map(&number).map(&container) end end # == test runner == Microtest.call This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,110 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,111 +0,0 @@ -
serradura revised this gist
Feb 10, 2019 . 1 changed file with 17 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,7 @@ class UComponent2 require 'cgi' require 'nokogiri/html' module DataAccessor def data=(value) @data = value @@ -34,12 +37,7 @@ def initialize(fn = nil) end def call(data) CGI.unescapeHTML(build_html_with(data)) end def to_proc @@ -48,6 +46,15 @@ def to_proc private def build_html_with(data) builder = Nokogiri::HTML::Builder.new builder.context = builder builder.extend(DataAccessor) builder.data = apply_defaults_to(data) builder.instance_eval(&@fn) builder.to_html.sub!(/<!DOCTYPE.*[^>]/, '') end def apply_defaults_to(data) return @defaults.merge(data) if data.is_a?(Hash) @@ -97,4 +104,7 @@ class NumberV2 < UComponent2 number_v2.call 1 [1,2,3,4].map(&number_v2) [1,2,3,4].map(&number_v2).map(&UComponent2.fn { div data }) -
serradura revised this gist
Feb 10, 2019 . 2 changed files with 173 additions and 73 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,111 +1,100 @@ class UComponent2 module DataAccessor def data=(value) @data = value end def data; @data; end end def self.fn(&block) new(block) end def self.call(data = {}) new.call(data) end def self.to_proc -> (data = {}) { call(data) } end def self.template(&block) define_method(:__template) { block } end def self.defaults(data = {}) define_method(:__defaults) { data } end def initialize(fn = nil) @fn = fn || __template @defaults = respond_to?(:__defaults) ? __defaults : {} end def call(data) builder = Nokogiri::HTML::Builder.new builder.context = @builder builder.extend(DataAccessor) builder.data = apply_defaults_to(data) builder.instance_eval(&@fn) builder.to_html.sub!(/<!DOCTYPE.*[^>]/, '') end def to_proc -> (data) { call(data) } end private def apply_defaults_to(data) return @defaults.merge(data) if data.is_a?(Hash) data || @defaults end end class HelloWorldV2 < UComponent2 template do span.bar.foo! { text("Hello World") } end end HelloWorldV2.call class GreetV2 < UComponent2 defaults name: 'John Doe' template do span.bar.foo! { text("Hello #{data[:name]}") } end end GreetV2.call GreetV2.call name: 'Rodrigo' [{name: 'Rodrigo'}, {name: 'Talita'}, {}].map(&GreetV2) class NumberV2 < UComponent2 template do strong { text(data) } end end NumberV2.call 1 [1,2,3,4].map(&NumberV2) number_v2 = UComponent2.fn do strong { text(data) } end number_v2.call 1 [1,2,3,4].map(&number_v2) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ class UComponent def self.defaults {} end def self.build(_doc, _options) raise NotImplementedError end def self.call(*args) fn = args[0].is_a?(Proc) ? args[0] : method(:build) options = args[0].is_a?(Hash) ? args[0] : (args[1] || {}) new.call(options, fn) end def self.to_proc -> (*args) { call(*args) } end def initialize(fn = nil) @fn = fn end def call(opt = {}, fn = nil) func = @fn || fn options = opt.is_a?(Hash) ? self.class.defaults.merge(opt) : opt builder = Nokogiri::HTML::Builder.new do |doc| func.arity == 1 ? func.(doc) : func.(doc, options) end builder.to_html.sub!(/<!DOCTYPE.*[^>]/, '') end def to_proc -> (options) { call(options) } end end class HelloWorld < UComponent def self.build(doc) doc.span.bold { doc.text("Hello world") } end end class HelloWorld2 < UComponent def self.build(doc, message:) doc.span.bold { doc.text(message) } end end class Greet < UComponent def self.defaults { name: 'John Doe' } end def self.build(doc, name:) doc.span.bar.foo! { doc.text("Hello #{name}") } end end # == Examples == HelloWorld.call #=> "<span class=\"bold\">Hello world</span>\n" HelloWorld2.call message: 'Olá mundo' #=> "<span class=\"bold\">Olá mundo</span>\n" UComponent.call -> doc { doc.span.bold { doc.text("Hello world") } } #=> "<span class=\"bold\">Hello world</span>\n" UComponent.call( -> doc, message { doc.span.bold { doc.text(message) } }, 'Olá mundo' ) #=> "<span class=\"bold\">Olá mundo</span>\n" Greet.call #=> "<span class=\"bar\" id=\"foo\">Hello John Doe</span>\n" Greet.call name: 'Serradura' #=> "<span class=\"bar\" id=\"foo\">Hello Serradura</span>\n" [{name: 'Rodrigo'}, {name: 'Talita'}, {}].map(&Greet) #=> ["<span class=\"bar\" id=\"foo\">Hello Rodrigo</span>\n", "<span class=\"bar\" id=\"foo\">Hello Talita</span>\n", "<span class=\"bar\" id=\"foo\">Hello John Doe</span>\n"] greet = UComponent.new(-> (doc, name:) do doc.span.bar.foo! { doc.text("Hello #{name}") } end) greet.call(name: 'Bella') #=> "<span class=\"bar\" id=\"foo\">Hello Bella</span>\n" [{name: 'Rodrigo'}, {name: 'Talita'}].map(&greet) #=> ["<span class=\"bar\" id=\"foo\">Hello Rodrigo</span>\n", "<span class=\"bar\" id=\"foo\">Hello Talita</span>\n"] number = UComponent.new(-> (doc, n) do doc.strong { doc.text(n) } end) [1,2,3,4].map(&number) #=> ["<strong>1</strong>\n", "<strong>2</strong>\n", "<strong>3</strong>\n", "<strong>4</strong>\n"] -
serradura revised this gist
Feb 9, 2019 . 1 changed file with 45 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,33 +1,40 @@ class UComponent def self.defaults {} end def self.build(_doc, _options) raise NotImplementedError end def self.call(*args) fn = args[0].is_a?(Proc) ? args[0] : method(:build) options = args[0].is_a?(Hash) ? args[0] : (args[1] || {}) new.call(options, fn) end def self.to_proc -> (*args) { call(*args) } end def initialize(fn = nil) @fn = fn end def call(opt = {}, fn = nil) func = @fn || fn options = opt.is_a?(Hash) ? self.class.defaults.merge(opt) : opt builder = Nokogiri::HTML::Builder.new do |doc| func.arity == 1 ? func.(doc) : func.(doc, options) end builder.to_html.sub!(/<!DOCTYPE.*[^>]/, '') end def to_proc -> (options) { call(options) } end end class HelloWorld < UComponent @@ -58,20 +65,47 @@ def self.build(doc, name:) end end # == Examples == HelloWorld.call #=> "<span class=\"bold\">Hello world</span>\n" HelloWorld2.call message: 'Olá mundo' #=> "<span class=\"bold\">Olá mundo</span>\n" UComponent.call -> doc { doc.span.bold { doc.text("Hello world") } } #=> "<span class=\"bold\">Hello world</span>\n" UComponent.call( -> doc, message { doc.span.bold { doc.text(message) } }, 'Olá mundo' ) #=> "<span class=\"bold\">Olá mundo</span>\n" Greet.call #=> "<span class=\"bar\" id=\"foo\">Hello John Doe</span>\n" Greet.call name: 'Serradura' #=> "<span class=\"bar\" id=\"foo\">Hello Serradura</span>\n" [{name: 'Rodrigo'}, {name: 'Talita'}, {}].map(&Greet) #=> ["<span class=\"bar\" id=\"foo\">Hello Rodrigo</span>\n", "<span class=\"bar\" id=\"foo\">Hello Talita</span>\n", "<span class=\"bar\" id=\"foo\">Hello John Doe</span>\n"] greet = UComponent.new(-> (doc, name:) do doc.span.bar.foo! { doc.text("Hello #{name}") } end) greet.call(name: 'Bella') #=> "<span class=\"bar\" id=\"foo\">Hello Bella</span>\n" [{name: 'Rodrigo'}, {name: 'Talita'}].map(&greet) #=> ["<span class=\"bar\" id=\"foo\">Hello Rodrigo</span>\n", "<span class=\"bar\" id=\"foo\">Hello Talita</span>\n"] number = UComponent.new(-> (doc, n) do doc.strong { doc.text(n) } end) [1,2,3,4].map(&number) #=> ["<strong>1</strong>\n", "<strong>2</strong>\n", "<strong>3</strong>\n", "<strong>4</strong>\n"] -
serradura created this gist
Feb 9, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,77 @@ class UComponent def self.call(*args) fn = args[0].is_a?(Proc) ? args[0] : method(:build) options = args[0].is_a?(Hash) ? args[0] : (args[1] || {}) new.call(options, fn) end def self.defaults {} end def self.build(_doc, _options) raise NotImplementedError end def initialize(fn = nil) @fn = fn end def call(options = {}, fn = nil) func = @fn || fn func_options = self.class.defaults.merge(options) builder = Nokogiri::HTML::Builder.new do |doc| func.arity == 1 ? func.(doc) : func.(doc, func_options) end builder.to_html.sub!(/<!DOCTYPE.*[^>]/, '') end end class HelloWorld < UComponent def self.build(doc) doc.span.bold { doc.text("Hello world") } end end class HelloWorld2 < UComponent def self.build(doc, message:) doc.span.bold { doc.text(message) } end end class Greet < UComponent def self.defaults { name: 'John Doe' } end def self.build(doc, name:) doc.span.bar.foo! { doc.text("Hello #{name}") } end end HelloWorld.call HelloWorld2.call message: 'Olá mundo' UComponent.call -> doc { doc.span.bold { doc.text("Hello world") } } Greet.call Greet.call name: 'Serradura' greet = UComponent.new(-> (doc, name:) do doc.span.bar.foo! { doc.text("Hello #{name}") } end) greet.call(name: 'Bella')