@@ -9,6 +9,10 @@ module LiquidDroppable |
||
9 | 9 |
@object = object |
10 | 10 |
end |
11 | 11 |
|
12 |
+ def to_s |
|
13 |
+ @object.to_s |
|
14 |
+ end |
|
15 |
+ |
|
12 | 16 |
def each |
13 | 17 |
(public_instance_methods - Drop.public_instance_methods).each { |name| |
14 | 18 |
yield [name, __send__(name)] |
@@ -23,4 +27,20 @@ module LiquidDroppable |
||
23 | 27 |
def to_liquid |
24 | 28 |
self.class::Drop.new(self) |
25 | 29 |
end |
30 |
+ |
|
31 |
+ require 'uri' |
|
32 |
+ |
|
33 |
+ class URIDrop < Drop |
|
34 |
+ URI::Generic::COMPONENT.each { |attr| |
|
35 |
+ define_method(attr) { |
|
36 |
+ @object.__send__(attr) |
|
37 |
+ } |
|
38 |
+ } |
|
39 |
+ end |
|
40 |
+ |
|
41 |
+ class ::URI::Generic |
|
42 |
+ def to_liquid |
|
43 |
+ URIDrop.new(self) |
|
44 |
+ end |
|
45 |
+ end |
|
26 | 46 |
end |
@@ -116,6 +116,22 @@ module LiquidInterpolatable |
||
116 | 116 |
CGI.escape(string) rescue string |
117 | 117 |
end |
118 | 118 |
|
119 |
+ # Parse an input into a URI object, optionally resolving it |
|
120 |
+ # against a base URI if given. |
|
121 |
+ # |
|
122 |
+ # A URI object will have the following properties: scheme, |
|
123 |
+ # userinfo, host, port, registry, path, opaque, query, and |
|
124 |
+ # fragment. |
|
125 |
+ def to_uri(uri, base_uri = nil) |
|
126 |
+ if base_uri |
|
127 |
+ URI(base_uri) + uri.to_s |
|
128 |
+ else |
|
129 |
+ URI(uri.to_s) |
|
130 |
+ end |
|
131 |
+ rescue URI::Error |
|
132 |
+ nil |
|
133 |
+ end |
|
134 |
+ |
|
119 | 135 |
# Escape a string for use in XPath expression |
120 | 136 |
def to_xpath(string) |
121 | 137 |
subs = string.to_s.scan(/\G(?:\A\z|[^"]+|[^']+)/).map { |x| |
@@ -0,0 +1,34 @@ |
||
1 |
+require 'spec_helper' |
|
2 |
+ |
|
3 |
+describe LiquidDroppable do |
|
4 |
+ before do |
|
5 |
+ class DroppableTest |
|
6 |
+ include LiquidDroppable |
|
7 |
+ |
|
8 |
+ def initialize(value) |
|
9 |
+ @value = value |
|
10 |
+ end |
|
11 |
+ |
|
12 |
+ attr_reader :value |
|
13 |
+ |
|
14 |
+ def to_s |
|
15 |
+ "[value:#{value}]" |
|
16 |
+ end |
|
17 |
+ end |
|
18 |
+ |
|
19 |
+ class DroppableTestDrop |
|
20 |
+ def value |
|
21 |
+ @object.value |
|
22 |
+ end |
|
23 |
+ end |
|
24 |
+ end |
|
25 |
+ |
|
26 |
+ describe 'test class' do |
|
27 |
+ it 'should be droppable' do |
|
28 |
+ five = DroppableTest.new(5) |
|
29 |
+ five.to_liquid.class.should == DroppableTestDrop |
|
30 |
+ Liquid::Template.parse('{{ x.value | plus:3 }}').render('x' => five).should == '8' |
|
31 |
+ Liquid::Template.parse('{{ x }}').render('x' => five).should == '[value:5]' |
|
32 |
+ end |
|
33 |
+ end |
|
34 |
+end |
@@ -59,4 +59,41 @@ describe LiquidInterpolatable::Filters do |
||
59 | 59 |
@filter.to_xpath_roundtrip(1).should == '1' |
60 | 60 |
end |
61 | 61 |
end |
62 |
+ |
|
63 |
+ describe 'to_uri' do |
|
64 |
+ before do |
|
65 |
+ @agent = Agents::InterpolatableAgent.new(name: "test", options: { 'foo' => '{% assign u = s | to_uri %}{{ u.path }}' }) |
|
66 |
+ @agent.interpolation_context['s'] = 'http://example.com/dir/1?q=test' |
|
67 |
+ end |
|
68 |
+ |
|
69 |
+ it 'should parse an abosule URI' do |
|
70 |
+ @filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html') |
|
71 |
+ end |
|
72 |
+ |
|
73 |
+ it 'should parse an abosule URI with a base URI specified' do |
|
74 |
+ @filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html') |
|
75 |
+ end |
|
76 |
+ |
|
77 |
+ it 'should parse a relative URI with a base URI specified' do |
|
78 |
+ @filter.to_uri('foo/index.html', 'http://example.com/dir/1').should == URI('http://example.com/dir/foo/index.html') |
|
79 |
+ end |
|
80 |
+ |
|
81 |
+ it 'should parse an abosule URI with a base URI specified' do |
|
82 |
+ @filter.to_uri('http://example.net/index.html', 'http://example.com/dir/1').should == URI('http://example.net/index.html') |
|
83 |
+ end |
|
84 |
+ |
|
85 |
+ it 'should stringify a non-string operand' do |
|
86 |
+ @filter.to_uri(123, 'http://example.com/dir/1').should == URI('http://example.com/dir/123') |
|
87 |
+ end |
|
88 |
+ |
|
89 |
+ it 'should return a URI value in interpolation' do |
|
90 |
+ @agent.interpolated['foo'].should == '/dir/1' |
|
91 |
+ end |
|
92 |
+ |
|
93 |
+ it 'should return a URI value resolved against a base URI in interpolation' do |
|
94 |
+ @agent.options['foo'] = '{% assign u = s | to_uri:"http://example.com/dir/1" %}{{ u.path }}' |
|
95 |
+ @agent.interpolation_context['s'] = 'foo/index.html' |
|
96 |
+ @agent.interpolated['foo'].should == '/dir/foo/index.html' |
|
97 |
+ end |
|
98 |
+ end |
|
62 | 99 |
end |