trenni 3.8.0 → 3.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bake/trenni/entities.rb +57 -0
- data/bake/trenni/parsers.rb +66 -0
- data/ext/tmp/x86_64-linux/lib/trenni/trenni.so +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/Makefile +263 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/escape.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/markup.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/mkmf.log +108 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/tag.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/template.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/trenni.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.4.0/trenni.so +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/Makefile +266 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/escape.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/markup.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/mkmf.log +113 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/query.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/tag.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/template.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/trenni.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.0/trenni.so +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/Makefile +266 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/escape.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/markup.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/mkmf.log +113 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/query.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/tag.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/template.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/trenni.o +0 -0
- data/ext/tmp/x86_64-linux/trenni/2.7.1/trenni.so +0 -0
- data/ext/trenni/markup.c +85 -85
- data/ext/trenni/markup.rl +11 -11
- data/ext/trenni/query.c +619 -0
- data/ext/trenni/query.h +6 -0
- data/ext/trenni/query.rl +82 -0
- data/ext/trenni/tag.c +8 -6
- data/ext/trenni/template.c +57 -57
- data/ext/trenni/template.rl +4 -4
- data/ext/trenni/trenni.c +9 -1
- data/ext/trenni/trenni.h +8 -3
- data/lib/trenni.rb +2 -0
- data/lib/trenni/builder.rb +79 -15
- data/lib/trenni/entities.rb +2082 -2084
- data/lib/trenni/entities.trenni +1 -3
- data/lib/trenni/{parse_error.rb → error.rb} +4 -1
- data/lib/trenni/fallback/markup.rb +1622 -1576
- data/lib/trenni/fallback/markup.rl +2 -2
- data/lib/trenni/fallback/markup.rl.dot +278 -0
- data/lib/trenni/fallback/markup.rl.pdf +0 -0
- data/lib/trenni/fallback/query.rb +565 -0
- data/lib/trenni/fallback/query.rl +105 -0
- data/lib/trenni/fallback/query.rl.dot +54 -0
- data/lib/trenni/fallback/query.rl.pdf +0 -0
- data/lib/trenni/fallback/template.rb +756 -748
- data/lib/trenni/fallback/template.rl +1 -1
- data/lib/trenni/fallback/template.rl.dot +270 -0
- data/lib/trenni/fallback/template.rl.pdf +0 -0
- data/lib/trenni/native.rb +1 -1
- data/lib/trenni/parsers.rb +1 -0
- data/lib/trenni/query.rb +94 -0
- data/lib/trenni/reference.rb +125 -0
- data/lib/trenni/strings.rb +15 -4
- data/lib/trenni/template.rb +23 -22
- data/lib/trenni/trenni.so +0 -0
- data/lib/trenni/uri.rb +1 -0
- data/lib/trenni/version.rb +1 -1
- data/parsers/trenni/query.rl +23 -0
- data/spec/trenni/builder_spec.rb +103 -60
- data/spec/trenni/markup_performance_spec.rb +14 -2
- data/spec/trenni/parsers_performance_spec.rb +31 -0
- data/spec/trenni/query_spec.rb +51 -0
- data/spec/trenni/reference_spec.rb +87 -0
- data/spec/trenni/template_spec/builder.trenni +2 -2
- metadata +91 -59
- data/.gitignore +0 -19
- data/.rspec +0 -5
- data/.simplecov +0 -9
- data/.travis.yml +0 -23
- data/Gemfile +0 -21
- data/README.md +0 -312
- data/Rakefile +0 -21
- data/benchmark/call_vs_yield.rb +0 -52
- data/benchmark/interpolation_vs_concat.rb +0 -30
- data/benchmark/io_vs_string.rb +0 -91
- data/entities.json +0 -2233
- data/tasks/entities.rake +0 -34
- data/tasks/parsers.rake +0 -44
- data/trenni.gemspec +0 -36
data/lib/trenni/strings.rb
CHANGED
@@ -30,7 +30,11 @@ module Trenni
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.to_quoted_string(string)
|
33
|
-
|
33
|
+
string = string.gsub('"', '\\"')
|
34
|
+
string.gsub!(/\r/, "\\r")
|
35
|
+
string.gsub!(/\n/, "\\n")
|
36
|
+
|
37
|
+
return "\"#{string}\""
|
34
38
|
end
|
35
39
|
|
36
40
|
# `value` must already be escaped.
|
@@ -43,11 +47,18 @@ module Trenni
|
|
43
47
|
end
|
44
48
|
|
45
49
|
def self.to_title(string)
|
46
|
-
string.gsub(/(^|[ \-_])(.)/){" " + $2.upcase}
|
50
|
+
string = string.gsub(/(^|[ \-_])(.)/){" " + $2.upcase}
|
51
|
+
string.strip!
|
52
|
+
|
53
|
+
return string
|
47
54
|
end
|
48
|
-
|
55
|
+
|
49
56
|
def self.to_snake(string)
|
50
|
-
string.gsub("::", "")
|
57
|
+
string = string.gsub("::", "")
|
58
|
+
string.gsub!(/([A-Z]+)/){"_" + $1.downcase}
|
59
|
+
string.sub!(/^_+/, "")
|
60
|
+
|
61
|
+
return string
|
51
62
|
end
|
52
63
|
end
|
53
64
|
end
|
data/lib/trenni/template.rb
CHANGED
@@ -29,36 +29,27 @@ module Trenni
|
|
29
29
|
BINDING = binding
|
30
30
|
|
31
31
|
class Builder
|
32
|
-
def
|
33
|
-
|
34
|
-
Template.buffer(block.binding) << self
|
35
|
-
return nil
|
36
|
-
else
|
37
|
-
return self
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def capture(*args, &block)
|
42
|
-
self.append Template.capture(*args, &block)
|
32
|
+
def capture(*arguments, &block)
|
33
|
+
Template.capture(*arguments, output: self, &block)
|
43
34
|
end
|
44
35
|
end
|
45
36
|
|
46
37
|
class Template
|
47
38
|
# Returns the output produced by calling the given block.
|
48
|
-
def self.capture(*
|
39
|
+
def self.capture(*arguments, output: nil, &block)
|
49
40
|
scope = block.binding
|
50
|
-
|
41
|
+
previous_output = scope.local_variable_get(OUT)
|
51
42
|
|
52
|
-
|
53
|
-
scope.local_variable_set(OUT,
|
43
|
+
output ||= previous_output.class.new(encoding: previous_output.encoding)
|
44
|
+
scope.local_variable_set(OUT, output)
|
54
45
|
|
55
46
|
begin
|
56
|
-
block.call(*
|
47
|
+
block.call(*arguments)
|
57
48
|
ensure
|
58
|
-
scope.local_variable_set(OUT,
|
49
|
+
scope.local_variable_set(OUT, previous_output)
|
59
50
|
end
|
60
51
|
|
61
|
-
return
|
52
|
+
return output
|
62
53
|
end
|
63
54
|
|
64
55
|
# Returns the buffer used for capturing output.
|
@@ -125,7 +116,7 @@ module Trenni
|
|
125
116
|
end
|
126
117
|
|
127
118
|
def to_proc(scope = @binding.dup)
|
128
|
-
@compiled_proc ||= eval("\#
|
119
|
+
@compiled_proc ||= eval("\# frozen_string_literal: true\nproc{|#{OUT}|;#{code}}", scope, @buffer.path, 0).freeze
|
129
120
|
end
|
130
121
|
|
131
122
|
protected
|
@@ -154,9 +145,19 @@ module Trenni
|
|
154
145
|
class MarkupTemplate < Template
|
155
146
|
class Assembler < Template::Assembler
|
156
147
|
# Output a string interpolation.
|
157
|
-
def expression(
|
158
|
-
@code << "
|
148
|
+
def expression(code)
|
149
|
+
@code << "#{OUT}<<(#{code});"
|
159
150
|
end
|
151
|
+
|
152
|
+
# Output raw text to the template.
|
153
|
+
def text(text)
|
154
|
+
text = text.gsub("'", "\\\\'")
|
155
|
+
@code << "#{OUT}.raw('#{text}');"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_string(scope = Object.new, output = nil)
|
160
|
+
super.output
|
160
161
|
end
|
161
162
|
|
162
163
|
protected
|
@@ -168,7 +169,7 @@ module Trenni
|
|
168
169
|
|
169
170
|
# The output of the markup template is encoded markup (e.g. with entities, tags, etc).
|
170
171
|
def output_buffer
|
171
|
-
|
172
|
+
Builder.new(encoding: code.encoding)
|
172
173
|
end
|
173
174
|
end
|
174
175
|
end
|
Binary file
|
data/lib/trenni/uri.rb
CHANGED
data/lib/trenni/version.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
%%{
|
2
|
+
machine query;
|
3
|
+
|
4
|
+
# An application/x-www-form-urlencoded parser based on the definition by WhatWG.
|
5
|
+
# Based on https://url.spec.whatwg.org/#application/x-www-form-urlencoded
|
6
|
+
pchar = any - [&=\[\]%+];
|
7
|
+
echar = pchar | ('+' | '%' xdigit xdigit) >encoded;
|
8
|
+
|
9
|
+
integer = ([0-9]+) >integer_begin %integer_end;
|
10
|
+
string = (echar+ - integer) >string_begin %string_end;
|
11
|
+
|
12
|
+
value = (echar*) >value_begin %value_end;
|
13
|
+
|
14
|
+
index = string (
|
15
|
+
'[' (integer | string) ']'
|
16
|
+
)* ('[]' %append)?;
|
17
|
+
|
18
|
+
pair = (
|
19
|
+
index ('=' value)?
|
20
|
+
) %pair;
|
21
|
+
|
22
|
+
main := ((pair '&')* pair)?;
|
23
|
+
}%%
|
data/spec/trenni/builder_spec.rb
CHANGED
@@ -21,22 +21,34 @@
|
|
21
21
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
22
|
# THE SOFTWARE.
|
23
23
|
|
24
|
-
require 'trenni'
|
24
|
+
require 'trenni/builder'
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
subject
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
RSpec.describe Trenni::Builder do
|
27
|
+
it "should produce valid html" do
|
28
|
+
subject.doctype
|
29
|
+
subject.tag('html') do
|
30
|
+
subject.tag('head') do
|
31
|
+
subject.inline('title') do
|
32
|
+
subject.text('Hello World')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
subject.tag('body') do
|
36
|
+
end
|
34
37
|
end
|
38
|
+
|
39
|
+
expect(subject.output).to be == <<~HTML.chomp
|
40
|
+
<!DOCTYPE html>
|
41
|
+
<html>
|
42
|
+
<head>
|
43
|
+
<title>Hello World</title>
|
44
|
+
</head>
|
45
|
+
<body>
|
46
|
+
</body>
|
47
|
+
</html>
|
48
|
+
HTML
|
35
49
|
end
|
36
50
|
|
37
|
-
describe '
|
38
|
-
let(:builder) {Trenni::Builder.new}
|
39
|
-
|
51
|
+
describe '.fragment' do
|
40
52
|
it "should use an existing builder" do
|
41
53
|
result = Trenni::Builder.fragment do |builder|
|
42
54
|
end
|
@@ -47,49 +59,59 @@ module Trenni::BuilderSpec
|
|
47
59
|
it "should use an existing builder" do
|
48
60
|
expect(Trenni::Builder).to receive(:new).and_call_original
|
49
61
|
|
50
|
-
result = Trenni::Builder.fragment(
|
62
|
+
result = Trenni::Builder.fragment(subject) do |builder|
|
51
63
|
end
|
52
64
|
|
53
|
-
expect(result).
|
65
|
+
expect(result).to be_nil
|
54
66
|
end
|
55
67
|
end
|
56
68
|
|
57
|
-
describe
|
58
|
-
it
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'should append existing markup' do
|
63
|
-
subject.tag("outer") do
|
64
|
-
subject.append("<inner>\n\t<nested/>\n</inner>")
|
65
|
-
end
|
66
|
-
|
67
|
-
expect(subject.output).to be == "<outer>\n\t<inner>\n\t\t<nested/>\n\t</inner>\n</outer>"
|
68
|
-
end
|
69
|
-
|
70
|
-
it "should produce valid html" do
|
71
|
-
subject.doctype
|
72
|
-
subject.tag('html') do
|
73
|
-
subject.tag('head') do
|
74
|
-
subject.inline('title') do
|
75
|
-
subject.text('Hello World')
|
76
|
-
end
|
77
|
-
end
|
78
|
-
subject.tag('body') do
|
79
|
-
end
|
80
|
-
end
|
69
|
+
describe '#tag' do
|
70
|
+
it "should format nested attributes" do
|
71
|
+
subject.tag('div', data: {id: 10})
|
81
72
|
|
82
|
-
expect(subject.output).to be ==
|
73
|
+
expect(subject.output).to be == '<div data-id="10"/>'
|
83
74
|
end
|
84
75
|
|
85
76
|
it "should indent self-closing tag correctly" do
|
86
77
|
builder = Trenni::Builder.new
|
87
78
|
|
88
|
-
builder.tag('foo') {
|
79
|
+
builder.tag('foo') {builder.tag('bar')}
|
89
80
|
|
90
|
-
expect(builder.output).to be ==
|
81
|
+
expect(builder.output).to be == <<~HTML.chomp
|
82
|
+
<foo>
|
83
|
+
<bar/>
|
84
|
+
</foo>
|
85
|
+
HTML
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should support compact attributes" do
|
89
|
+
subject.tag :option, :required => true
|
90
|
+
expect(subject.output).to be == %Q{<option required/>}
|
91
91
|
end
|
92
92
|
|
93
|
+
it "should output without changing escaped characters" do
|
94
|
+
subject.tag "section", :'data-text' => 'foo\nbar'
|
95
|
+
expect(subject.output).to be == '<section data-text="foo\nbar"/>'
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should order array attributes as specified" do
|
99
|
+
subject.tag :t, [[:a, 10], [:b, 20]]
|
100
|
+
expect(subject.output).to be == %Q{<t a="10" b="20"/>}
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should order hash attributes as specified" do
|
104
|
+
subject.tag :t, :b => 20, :a => 10
|
105
|
+
expect(subject.output).to be == %Q{<t b="20" a="10"/>}
|
106
|
+
end
|
107
|
+
|
108
|
+
it "shouldn't output attributes with nil value" do
|
109
|
+
subject.tag :t, [[:a, 10], [:b, nil]]
|
110
|
+
expect(subject.output).to be == %Q{<t a="10"/>}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#inline' do
|
93
115
|
it "should produce inline html" do
|
94
116
|
subject.inline("div") do
|
95
117
|
subject.tag("strong") do
|
@@ -102,6 +124,20 @@ module Trenni::BuilderSpec
|
|
102
124
|
expect(subject.output).to be == "<div><strong>Hello</strong>World!</div>"
|
103
125
|
end
|
104
126
|
|
127
|
+
it "can inline fragments" do
|
128
|
+
subject.inline! do
|
129
|
+
subject.inline('a') do
|
130
|
+
subject << "Hello"
|
131
|
+
end
|
132
|
+
|
133
|
+
subject.inline('a') do
|
134
|
+
subject << "World"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
expect(subject.output).to be == "<a>Hello</a><a>World</a>"
|
139
|
+
end
|
140
|
+
|
105
141
|
it "escapes attributes and text correctly" do
|
106
142
|
subject.inline :foo, :bar => %Q{"Hello World"} do
|
107
143
|
subject.text %Q{if x < 10}
|
@@ -109,30 +145,37 @@ module Trenni::BuilderSpec
|
|
109
145
|
|
110
146
|
expect(subject.output).to be == %Q{<foo bar=""Hello World"">if x < 10</foo>}
|
111
147
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
it "should output without changing escaped characters" do
|
119
|
-
subject.tag "section", :'data-text' => 'foo\nbar'
|
120
|
-
expect(subject.output).to be == '<section data-text="foo\nbar"/>'
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#<<' do
|
151
|
+
it 'can append text' do
|
152
|
+
subject << 'text'
|
153
|
+
expect(subject.output).to be == "text"
|
121
154
|
end
|
122
155
|
|
123
|
-
it "
|
124
|
-
subject
|
125
|
-
expect(subject.output).to be ==
|
156
|
+
it "doesn't append nil" do
|
157
|
+
subject << nil
|
158
|
+
expect(subject.output).to be == ""
|
126
159
|
end
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#append' do
|
163
|
+
it 'should be able to append nil' do
|
164
|
+
expect{subject.append(nil)}.to_not raise_error
|
131
165
|
end
|
132
166
|
|
133
|
-
it
|
134
|
-
subject.tag
|
135
|
-
|
167
|
+
it 'should append existing markup' do
|
168
|
+
subject.tag("outer") do
|
169
|
+
subject.append("<inner>\n\t<nested/>\n</inner>")
|
170
|
+
end
|
171
|
+
|
172
|
+
expect(subject.output).to be == <<~HTML.chomp
|
173
|
+
<outer>
|
174
|
+
<inner>
|
175
|
+
<nested/>
|
176
|
+
</inner>
|
177
|
+
</outer>
|
178
|
+
HTML
|
136
179
|
end
|
137
180
|
end
|
138
181
|
end
|
@@ -9,13 +9,25 @@ RSpec.describe Trenni::Markup do
|
|
9
9
|
|
10
10
|
it "should be fast to parse large documents" do
|
11
11
|
Benchmark.ips do |x|
|
12
|
-
x.report("
|
12
|
+
x.report("CGI.escapeHTML(general_string)") do |times|
|
13
|
+
while (times -= 1) >= 0
|
14
|
+
CGI.escapeHTML(general_string)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
x.report("CGI.escapeHTML(code_string)") do |times|
|
19
|
+
while (times -= 1) >= 0
|
20
|
+
CGI.escapeHTML(code_string)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
x.report("Trenni::Markup.escape_string(general_string)") do |times|
|
13
25
|
while (times -= 1) >= 0
|
14
26
|
Trenni::Markup.escape_string(general_string)
|
15
27
|
end
|
16
28
|
end
|
17
29
|
|
18
|
-
x.report("
|
30
|
+
x.report("Trenni::Markup.escape_string(code_string)") do |times|
|
19
31
|
while (times -= 1) >= 0
|
20
32
|
Trenni::Markup.escape_string(code_string)
|
21
33
|
end
|
@@ -4,6 +4,9 @@ require 'benchmark/ips'
|
|
4
4
|
require 'trenni/parsers'
|
5
5
|
require 'trenni/entities'
|
6
6
|
|
7
|
+
require 'trenni/query'
|
8
|
+
require 'rack/utils'
|
9
|
+
|
7
10
|
require 'nokogiri'
|
8
11
|
|
9
12
|
RSpec.describe Trenni::Parsers do
|
@@ -71,4 +74,32 @@ RSpec.describe Trenni::Parsers do
|
|
71
74
|
end
|
72
75
|
end
|
73
76
|
end
|
77
|
+
|
78
|
+
describe '#parse_query' do
|
79
|
+
let(:string) {"foo=hi%20there&bar[blah]=123&bar[quux][0]=1&bar[quux][1]=2&bar[quux][2]=3"}
|
80
|
+
|
81
|
+
it "should be fast to parse large query strings" do
|
82
|
+
# query = Trenni::Query.new
|
83
|
+
# query.parse(Trenni::Buffer.new string)
|
84
|
+
# pp query
|
85
|
+
#
|
86
|
+
# pp Rack::Utils.parse_nested_query(string)
|
87
|
+
|
88
|
+
Benchmark.ips do |x|
|
89
|
+
x.report("Large (Trenni)") do |times|
|
90
|
+
while (times -= 1) >= 0
|
91
|
+
Trenni::Query.new.parse(Trenni::Buffer.new string)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
x.report("Large (Rack)") do |times|
|
96
|
+
while (times -= 1) >= 0
|
97
|
+
Rack::Utils.parse_nested_query(string)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
x.compare!
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
74
105
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'trenni/query'
|
24
|
+
|
25
|
+
RSpec.describe Trenni::Query do
|
26
|
+
def parse(string)
|
27
|
+
subject.parse(Trenni::Buffer.new(string))
|
28
|
+
|
29
|
+
return subject
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can parse query string with integer key" do
|
33
|
+
expect(parse "q[0]=0").to be == {q: {0 => "0"}}
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can parse query string with mixed integer/string key" do
|
37
|
+
expect(parse "q[2d]=3d").to be == {q: {:'2d' => "3d"}}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "can parse query string appending items to array" do
|
41
|
+
expect(parse "q[]=a&q[]=b").to be == {q: ["a", "b"]}
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can decode encoded keys" do
|
45
|
+
expect(parse "hello+world=true").to be == {:"hello world" => "true"}
|
46
|
+
end
|
47
|
+
|
48
|
+
it "can decode encoded values" do
|
49
|
+
expect(parse "message=hello+world").to be == {message: "hello world"}
|
50
|
+
end
|
51
|
+
end
|