burlap 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +38 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +16 -0
- data/Rakefile +31 -0
- data/burlap.gemspec +32 -0
- data/lib/active_support/ordered_hash.rb +179 -0
- data/lib/burlap/array.rb +18 -0
- data/lib/burlap/base_tag.rb +105 -0
- data/lib/burlap/call.rb +38 -0
- data/lib/burlap/core_ext/array.rb +7 -0
- data/lib/burlap/core_ext/boolean.rb +11 -0
- data/lib/burlap/core_ext/float.rb +5 -0
- data/lib/burlap/core_ext/hash.rb +5 -0
- data/lib/burlap/core_ext/integer.rb +10 -0
- data/lib/burlap/core_ext/nil.rb +5 -0
- data/lib/burlap/core_ext/object.rb +13 -0
- data/lib/burlap/core_ext/string.rb +5 -0
- data/lib/burlap/core_ext/symbol.rb +6 -0
- data/lib/burlap/core_ext/time.rb +5 -0
- data/lib/burlap/core_ext.rb +10 -0
- data/lib/burlap/default_resolver.rb +100 -0
- data/lib/burlap/error.rb +3 -0
- data/lib/burlap/fault.rb +6 -0
- data/lib/burlap/hash.rb +72 -0
- data/lib/burlap/listener.rb +34 -0
- data/lib/burlap/node.rb +48 -0
- data/lib/burlap/version.rb +3 -0
- data/lib/burlap.rb +47 -0
- data/lib/core_ext/time_burlap_iso8601.rb +32 -0
- data/spec/burlap/array_spec.rb +28 -0
- data/spec/burlap/call_spec.rb +126 -0
- data/spec/burlap/core_ext/array_spec.rb +123 -0
- data/spec/burlap/core_ext/class_spec.rb +24 -0
- data/spec/burlap/core_ext/false_class_spec.rb +17 -0
- data/spec/burlap/core_ext/float_spec.rb +15 -0
- data/spec/burlap/core_ext/hash_spec.rb +15 -0
- data/spec/burlap/core_ext/integer_spec.rb +28 -0
- data/spec/burlap/core_ext/nil_class_spec.rb +15 -0
- data/spec/burlap/core_ext/object_spec.rb +62 -0
- data/spec/burlap/core_ext/string_spec.rb +27 -0
- data/spec/burlap/core_ext/symbol_spec.rb +15 -0
- data/spec/burlap/core_ext/time_spec.rb +23 -0
- data/spec/burlap/core_ext/true_class_spec.rb +17 -0
- data/spec/burlap/default_resolver_spec.rb +140 -0
- data/spec/burlap/error_spec.rb +7 -0
- data/spec/burlap/hash_spec.rb +234 -0
- data/spec/burlap/listener_spec.rb +31 -0
- data/spec/burlap/node_spec.rb +39 -0
- data/spec/burlap_spec.rb +55 -0
- data/spec/data/no_such_method.burlap +1 -0
- data/spec/data/record_not_found.burlap +1 -0
- data/spec/spec_helper.rb +13 -0
- metadata +224 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
require "time"
|
2
|
+
require "ostruct"
|
3
|
+
|
4
|
+
module Burlap
|
5
|
+
class DefaultResolver
|
6
|
+
def mappings(*names, &block)
|
7
|
+
# Default's to a hash
|
8
|
+
@mappings ||= {}
|
9
|
+
# return early, return often. Or is that release?
|
10
|
+
return @mappings if names.empty?
|
11
|
+
|
12
|
+
# Set said block for each name
|
13
|
+
names.each do |name|
|
14
|
+
@mappings[name] = proc(&block)
|
15
|
+
end
|
16
|
+
|
17
|
+
@mappings
|
18
|
+
end
|
19
|
+
|
20
|
+
# obj is expected to respond to #name, #value and #children
|
21
|
+
# (eg, an instance of BaseTag)
|
22
|
+
def convert_to_native obj
|
23
|
+
mapping = mappings[obj.name] || raise(Error, "couldn't handle tag #{obj.name.inspect}")
|
24
|
+
mapping.call(obj)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# And set ourselves as the default
|
29
|
+
self.resolver ||= DefaultResolver.new
|
30
|
+
end
|
31
|
+
|
32
|
+
Burlap.resolver.mappings "burlap:reply" do |tag|
|
33
|
+
tag.children.first.to_ruby if tag.children.first
|
34
|
+
end
|
35
|
+
|
36
|
+
Burlap.resolver.mappings "map" do |tag|
|
37
|
+
# Pop the first element off
|
38
|
+
t = tag.children.shift.to_ruby
|
39
|
+
|
40
|
+
# then parse the rest of the children as key/values
|
41
|
+
values = tag.parse_matched_pairs
|
42
|
+
|
43
|
+
Burlap::Hash[values, t]
|
44
|
+
end
|
45
|
+
|
46
|
+
Burlap.resolver.mappings "fault" do |tag|
|
47
|
+
# Parse the children as key/values
|
48
|
+
values = tag.parse_matched_pairs
|
49
|
+
|
50
|
+
# and then turn it into an open struct
|
51
|
+
if RUBY_VERSION > '1.9'
|
52
|
+
Burlap::Fault.new(Hash[values])
|
53
|
+
else
|
54
|
+
Burlap::Fault.new(values)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
Burlap.resolver.mappings "type", "string" do |tag|
|
59
|
+
tag.value.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
Burlap.resolver.mappings "int", "length" do |tag|
|
63
|
+
tag.value.to_i
|
64
|
+
end
|
65
|
+
|
66
|
+
Burlap.resolver.mappings "double" do |tag|
|
67
|
+
tag.value.to_f
|
68
|
+
end
|
69
|
+
|
70
|
+
Burlap.resolver.mappings "null" do |tag|
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
Burlap.resolver.mappings "date" do |tag|
|
75
|
+
::Time.parse(tag.value) if tag.value
|
76
|
+
end
|
77
|
+
|
78
|
+
Burlap.resolver.mappings "list" do |tag|
|
79
|
+
# We don't actually care about the type or length of the
|
80
|
+
# array in ruby, but we shift it out the way so we can ignore it.
|
81
|
+
t = tag.children.shift.to_ruby
|
82
|
+
length = tag.children.shift.to_ruby
|
83
|
+
|
84
|
+
# Parse the rest of the children as key/values
|
85
|
+
values = tag.children.map &:to_ruby
|
86
|
+
|
87
|
+
Burlap::Array[*values]
|
88
|
+
end
|
89
|
+
|
90
|
+
Burlap.resolver.mappings "ref" do |tag|
|
91
|
+
tag.value
|
92
|
+
end
|
93
|
+
|
94
|
+
Burlap.resolver.mappings "boolean" do |tag|
|
95
|
+
tag.value.to_i == 1
|
96
|
+
end
|
97
|
+
|
98
|
+
Burlap.resolver.mappings "base64" do |tag|
|
99
|
+
Base64.decode64(tag.value.to_s)
|
100
|
+
end
|
data/lib/burlap/error.rb
ADDED
data/lib/burlap/fault.rb
ADDED
data/lib/burlap/hash.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require "active_support/ordered_hash"
|
2
|
+
|
3
|
+
module Burlap
|
4
|
+
# todo: subclass ::Hash once this is 1.9.2 only
|
5
|
+
class Hash < ActiveSupport::OrderedHash
|
6
|
+
attr_writer :__type__
|
7
|
+
|
8
|
+
# We override this to allow a type to be set upon object initialization.
|
9
|
+
# As we subclass Hash and call super it should behave exactly the same
|
10
|
+
# as Hash#[].
|
11
|
+
#
|
12
|
+
# NB: we actually subclass ActiveSupport::OrderedHash for ordered hash support
|
13
|
+
# in ruby 1.8.x, which means we don't behave exactly like Hash#[] on 1.8.x. Sucks.
|
14
|
+
#
|
15
|
+
# Examples:
|
16
|
+
#
|
17
|
+
# Burlap::Hash[:one => :two] # => {:one => :two}, type == ""
|
18
|
+
# Burlap::Hash[{:one => :two}, "fred"] # => {:one => :two}, type == "fred"
|
19
|
+
#
|
20
|
+
def self.[] *args
|
21
|
+
if args.size == 2 && args[1].is_a?(::String)
|
22
|
+
h = super(args[0].to_a)
|
23
|
+
h.__type__ = args[1]
|
24
|
+
h
|
25
|
+
elsif args.size == 1 && args[0].is_a?(::Hash)
|
26
|
+
super(args[0].to_a)
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Accessor for the type attribute, defaults to an empty string
|
33
|
+
def __type__
|
34
|
+
@__type__ ||= ""
|
35
|
+
end
|
36
|
+
|
37
|
+
# Build a string for ourselves, including both __type__ and the hash
|
38
|
+
def inspect
|
39
|
+
# we have to build our hash string manually so it's ordered, can't call #to_h.inspect under 1.8
|
40
|
+
# as that returns an _un_ordered hash.
|
41
|
+
"#<#{self.class} __type__=#{__type__.inspect} {#{map {|k,v| "#{k.inspect}=>#{v.inspect}"}.join(", ")}}>"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Return ourselves as a plain old ruby Hash
|
45
|
+
def to_h
|
46
|
+
::Hash[self]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Converts the hash into a string of XML, calling #to_burlap on all keys &
|
50
|
+
# values. Builds a <map> element, with type set then all key/values following.
|
51
|
+
def to_burlap
|
52
|
+
# Build the node for the type
|
53
|
+
contents = [Burlap::Node.new(
|
54
|
+
:name => "type",
|
55
|
+
:value => self.__type__
|
56
|
+
)]
|
57
|
+
|
58
|
+
# Build nodes for all the content
|
59
|
+
contents += self.map do |k,v|
|
60
|
+
[k, v]
|
61
|
+
end.flatten(1)
|
62
|
+
|
63
|
+
content = contents.map(&:to_burlap).join("")
|
64
|
+
|
65
|
+
Burlap::Node.new(
|
66
|
+
:name => "map",
|
67
|
+
:value => content
|
68
|
+
).to_burlap
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
|
3
|
+
module Burlap
|
4
|
+
class Listener < Nokogiri::XML::SAX::Document
|
5
|
+
attr_accessor :result
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@result = nil
|
9
|
+
@open = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_element name, attrs=[]
|
13
|
+
@open.push BaseTag.new(:name => name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def characters contents
|
17
|
+
@open.last.value += contents if @open.last
|
18
|
+
end
|
19
|
+
|
20
|
+
def end_element name
|
21
|
+
last = @open.pop
|
22
|
+
if @open.empty?
|
23
|
+
@result = last.to_ruby
|
24
|
+
else
|
25
|
+
@open.last.children.push last
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
attr_writer :data
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/lib/burlap/node.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Burlap
|
2
|
+
class Node
|
3
|
+
attr_accessor :name, :value
|
4
|
+
|
5
|
+
# name is the element name to go in the <>
|
6
|
+
# and value is a string to go in the node
|
7
|
+
def initialize params={}
|
8
|
+
params.each do |k,v|
|
9
|
+
meffod = :"#{k}="
|
10
|
+
send(meffod, v) #if respond_to?(meffod)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Packs this object into nokogiri nodes and returns the XML as a string
|
15
|
+
def to_burlap
|
16
|
+
doc = Nokogiri::XML::Document.new
|
17
|
+
root = Nokogiri::XML::Node.new(self.name, doc)
|
18
|
+
|
19
|
+
if self.value.to_s == ""
|
20
|
+
root.children = self.value.to_s
|
21
|
+
else
|
22
|
+
root << self.value.to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
convert_hex_entities_to_decimal root.to_xml(nokogiri_xml_options)
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
def nokogiri_xml_options
|
30
|
+
{:indent => 0, :indent_text => "", :save_with => Nokogiri::XML::Node::SaveOptions::AS_HTML}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Converts all hex entities into decimal entities.
|
34
|
+
#
|
35
|
+
# eg: å into å
|
36
|
+
#
|
37
|
+
# @param [String, #gsub] string string to convert entities in
|
38
|
+
# @return [String] string with decimal entities
|
39
|
+
def convert_hex_entities_to_decimal string
|
40
|
+
string.gsub(/&#x[0-9a-f]+;/i) do |match|
|
41
|
+
# Extract the hex value and convert to decimal
|
42
|
+
dec = match[/x([0-9a-f]+;)/i, 1].to_i(16)
|
43
|
+
|
44
|
+
"&##{dec};"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/burlap.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module Burlap
|
2
|
+
# Stores the resolver object for parsing burlap
|
3
|
+
class << self
|
4
|
+
attr_accessor :resolver
|
5
|
+
end
|
6
|
+
|
7
|
+
# Turns a burlap string read from `io_handle` into native
|
8
|
+
# ruby objects.
|
9
|
+
def self.parse(io_handle, strict = false)
|
10
|
+
listener = Listener.new
|
11
|
+
parser = Nokogiri::XML::SAX::Parser.new(listener)
|
12
|
+
|
13
|
+
if strict && io_handle.encoding != Encoding::UTF_8
|
14
|
+
io_handle.encode!(Encoding::UTF_8)
|
15
|
+
end
|
16
|
+
|
17
|
+
parser.parse(io_handle)
|
18
|
+
listener.result
|
19
|
+
end
|
20
|
+
|
21
|
+
# Turns `obj` into a burlap XML representation
|
22
|
+
def self.dump obj
|
23
|
+
if obj.respond_to?(:to_burlap)
|
24
|
+
obj.to_burlap
|
25
|
+
else
|
26
|
+
raise Error, "couldn't dump #{obj.inspect}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require "base64"
|
32
|
+
require "erb"
|
33
|
+
require "core_ext/time_burlap_iso8601"
|
34
|
+
|
35
|
+
require "burlap/default_resolver"
|
36
|
+
# burlap/version already got included by gemspec
|
37
|
+
require "burlap/error"
|
38
|
+
require "burlap/array"
|
39
|
+
require "burlap/hash"
|
40
|
+
|
41
|
+
require "burlap/node"
|
42
|
+
require "burlap/core_ext" # todo: make optional?
|
43
|
+
require "burlap/base_tag"
|
44
|
+
require "burlap/fault"
|
45
|
+
|
46
|
+
require "burlap/call"
|
47
|
+
require "burlap/listener"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "time"
|
2
|
+
|
3
|
+
module TimeBurlapIso8601
|
4
|
+
# Burlap needs #iso8601 without any dashes or colons. It mimics the 1.8 implementation
|
5
|
+
# of #iso8601, including not having a dependency on #strftime.
|
6
|
+
#
|
7
|
+
# @param [Integer] fraction_digits number of digits of milliseconds wanted
|
8
|
+
# @return [String]
|
9
|
+
#
|
10
|
+
def burlap_iso8601 fraction_digits=0
|
11
|
+
sprintf("%d%02d%02dT%02d%02d%02d", year, mon, day, hour, min, sec) + \
|
12
|
+
|
13
|
+
case fraction_digits
|
14
|
+
when 0
|
15
|
+
""
|
16
|
+
when 1..6
|
17
|
+
sprintf(".%06d", usec)[0..3]
|
18
|
+
else
|
19
|
+
sprintf(".%06d", usec) + "0" * (fraction_digits - 6)
|
20
|
+
end + \
|
21
|
+
|
22
|
+
if utc?
|
23
|
+
'Z'
|
24
|
+
else
|
25
|
+
off = utc_offset
|
26
|
+
sign = off < 0 ? '-' : '+'
|
27
|
+
sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Time.send(:include, TimeBurlapIso8601)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Burlap::Array do
|
4
|
+
describe "#to_burlap" do
|
5
|
+
subject(:burlap) { array.to_burlap }
|
6
|
+
|
7
|
+
let(:array) { described_class["some", mock_obj] }
|
8
|
+
let(:mock_obj) { instance_double(Object, to_burlap: "<mock>my stuff here</mock>") }
|
9
|
+
|
10
|
+
it "returns a string" do
|
11
|
+
expect(burlap).to be_a_kind_of(String)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "is correct" do
|
15
|
+
xml_string = <<-XML
|
16
|
+
<list>
|
17
|
+
<type></type>
|
18
|
+
<length>2</length>
|
19
|
+
<string>some</string>
|
20
|
+
<mock>my stuff here</mock>
|
21
|
+
</list>
|
22
|
+
XML
|
23
|
+
|
24
|
+
format_xml_as_burlap(xml_string)
|
25
|
+
expect(burlap).to eq(xml_string)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Burlap::Call do
|
4
|
+
subject(:caller) { described_class.new(caller_args) }
|
5
|
+
|
6
|
+
let(:caller_args) { { method: "updateUser" } }
|
7
|
+
|
8
|
+
describe "#headers" do
|
9
|
+
it "defaults to an array" do
|
10
|
+
expect(caller.headers).to eq({})
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#arguments" do
|
15
|
+
it "defaults to a hash" do
|
16
|
+
expect(caller.arguments).to eq([])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#method" do
|
21
|
+
subject(:caller) { described_class.new({}) }
|
22
|
+
|
23
|
+
it "is required" do
|
24
|
+
expect { caller }.to raise_error(ArgumentError, "method is required")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#to_burlap" do
|
29
|
+
subject(:burlap) { caller.to_burlap }
|
30
|
+
|
31
|
+
before { Timecop.freeze(Time.local(2010, 9, 11, 10, 0, 0)) }
|
32
|
+
|
33
|
+
after { Timecop.return }
|
34
|
+
|
35
|
+
context "single dimensional" do
|
36
|
+
let(:caller_args) { { method: "updateUser", arguments: ["one", 2, 3.0, nil, true, Time.now] } }
|
37
|
+
|
38
|
+
it "has a burlap:call root" do
|
39
|
+
expect(burlap).to match(/\A<burlap:call>/)
|
40
|
+
expect(burlap).to match(%r{</burlap:call>\z})
|
41
|
+
end
|
42
|
+
|
43
|
+
it "has a method element" do
|
44
|
+
expect(burlap).to match(%r{<method>updateUser</method>})
|
45
|
+
end
|
46
|
+
|
47
|
+
it "has a string argument element" do
|
48
|
+
expect(burlap).to match(%r{<string>one</string>})
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has an int argument element" do
|
52
|
+
expect(burlap).to match(%r{<int>2</int>})
|
53
|
+
end
|
54
|
+
|
55
|
+
it "has a double argument element" do
|
56
|
+
expect(burlap).to match(%r{<double>3.0</double>})
|
57
|
+
end
|
58
|
+
|
59
|
+
it "has a null argument element" do
|
60
|
+
expect(burlap).to match(%r{<null></null>})
|
61
|
+
end
|
62
|
+
|
63
|
+
it "has a boolean argument element" do
|
64
|
+
expect(burlap).to match(%r{<boolean>1</boolean>})
|
65
|
+
end
|
66
|
+
|
67
|
+
it "has a date argument element" do
|
68
|
+
expect(burlap).to match(%r{<date>#{Regexp.escape(Time.now.burlap_iso8601(3))}</date>})
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "multi-dimensional" do
|
73
|
+
let(:caller_args) { { method: "updateUser", arguments: ["one", contact] } }
|
74
|
+
let(:contact) do
|
75
|
+
Burlap::Hash[
|
76
|
+
[
|
77
|
+
["number", 101],
|
78
|
+
["street", "auckland road"],
|
79
|
+
%w[town elizabethtown],
|
80
|
+
%w[country finland],
|
81
|
+
["foreign", true]
|
82
|
+
],
|
83
|
+
"burlap.user"
|
84
|
+
]
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns a string" do
|
88
|
+
expect(burlap).to be_a_kind_of(String)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "generates the right burlap" do
|
92
|
+
# TODO: add headers
|
93
|
+
xml_string = <<-XML
|
94
|
+
<burlap:call>
|
95
|
+
<method>updateUser</method>
|
96
|
+
|
97
|
+
<string>one</string>
|
98
|
+
|
99
|
+
<map>
|
100
|
+
<type>burlap.user</type>
|
101
|
+
|
102
|
+
<string>number</string>
|
103
|
+
<int>101</int>
|
104
|
+
|
105
|
+
<string>street</string>
|
106
|
+
<string>auckland road</string>
|
107
|
+
|
108
|
+
<string>town</string>
|
109
|
+
<string>elizabethtown</string>
|
110
|
+
|
111
|
+
<string>country</string>
|
112
|
+
<string>finland</string>
|
113
|
+
|
114
|
+
<string>foreign</string>
|
115
|
+
<boolean>1</boolean>
|
116
|
+
</map>
|
117
|
+
|
118
|
+
</burlap:call>
|
119
|
+
XML
|
120
|
+
|
121
|
+
format_xml_as_burlap(xml_string)
|
122
|
+
expect(burlap).to eq(xml_string)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Array do
|
4
|
+
describe "#to_burlap" do
|
5
|
+
subject(:burlap) { array.to_burlap }
|
6
|
+
|
7
|
+
context "with 0 elements" do
|
8
|
+
let(:array) { [] }
|
9
|
+
|
10
|
+
it "returns a string" do
|
11
|
+
expect(burlap).to be_a_kind_of(String)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a list root" do
|
15
|
+
expect(burlap).to match(/^<list>/)
|
16
|
+
expect(burlap).to match(%r{</list>$})
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has a type element" do
|
20
|
+
expect(burlap).to match(%r{<type></type>})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "has a length element" do
|
24
|
+
expect(burlap).to match(%r{<length>#{array.size}</length>})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "creates a Burlap::Array instance from itself and delegate #to_burlap to it" do
|
28
|
+
mock_burlap_array = instance_double(Burlap::Array)
|
29
|
+
expect(Burlap::Array).to receive(:[]).with(no_args).and_return(mock_burlap_array)
|
30
|
+
expect(mock_burlap_array).to receive(:to_burlap).and_return("<burlap>array</burlap>")
|
31
|
+
|
32
|
+
expect(array.to_burlap).to eq("<burlap>array</burlap>")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with 1 element" do
|
37
|
+
let(:array) { [:one] }
|
38
|
+
|
39
|
+
it "returns a string" do
|
40
|
+
expect(burlap).to be_a_kind_of(String)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "has a list root" do
|
44
|
+
expect(burlap).to match(/^<list>/)
|
45
|
+
expect(burlap).to match(%r{</list>$})
|
46
|
+
end
|
47
|
+
|
48
|
+
it "has a type element" do
|
49
|
+
expect(burlap).to match(%r{<type></type>})
|
50
|
+
end
|
51
|
+
|
52
|
+
it "has a length element" do
|
53
|
+
expect(burlap).to match(%r{<length>#{array.size}</length>})
|
54
|
+
end
|
55
|
+
|
56
|
+
it "creates a Burlap::Array instance from itself and delegate #to_burlap to it" do
|
57
|
+
mock_burlap_array = instance_double(Burlap::Array)
|
58
|
+
expect(Burlap::Array).to receive(:[]).with(*array).and_return(mock_burlap_array)
|
59
|
+
expect(mock_burlap_array).to receive(:to_burlap).and_return("<burlap>array</burlap>")
|
60
|
+
|
61
|
+
expect(array.to_burlap).to eq("<burlap>array</burlap>")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with 2 elements" do
|
66
|
+
let(:array) { [:one, "two"] }
|
67
|
+
|
68
|
+
it "returns a string" do
|
69
|
+
expect(burlap).to be_a_kind_of(String)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "has a list root" do
|
73
|
+
expect(burlap).to match(/^<list>/)
|
74
|
+
expect(burlap).to match(%r{</list>$})
|
75
|
+
end
|
76
|
+
|
77
|
+
it "has a type element" do
|
78
|
+
expect(burlap).to match(%r{<type></type>})
|
79
|
+
end
|
80
|
+
|
81
|
+
it "has a length element" do
|
82
|
+
expect(burlap).to match(%r{<length>#{array.size}</length>})
|
83
|
+
end
|
84
|
+
|
85
|
+
it "creates a Burlap::Array instance from itself and delegate #to_burlap to it" do
|
86
|
+
mock_burlap_array = instance_double(Burlap::Array)
|
87
|
+
expect(Burlap::Array).to receive(:[]).with(*array).and_return(mock_burlap_array)
|
88
|
+
expect(mock_burlap_array).to receive(:to_burlap).and_return("<burlap>array</burlap>")
|
89
|
+
|
90
|
+
expect(array.to_burlap).to eq("<burlap>array</burlap>")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "with 3 elements" do
|
95
|
+
let(:array) { [:one, "two", 3] }
|
96
|
+
|
97
|
+
it "returns a string" do
|
98
|
+
expect(burlap).to be_a_kind_of(String)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "has a list root" do
|
102
|
+
expect(burlap).to match(/^<list>/)
|
103
|
+
expect(burlap).to match(%r{</list>$})
|
104
|
+
end
|
105
|
+
|
106
|
+
it "has a type element" do
|
107
|
+
expect(burlap).to match(%r{<type></type>})
|
108
|
+
end
|
109
|
+
|
110
|
+
it "has a length element" do
|
111
|
+
expect(burlap).to match(%r{<length>#{array.size}</length>})
|
112
|
+
end
|
113
|
+
|
114
|
+
it "creates a Burlap::Array instance from itself and delegate #to_burlap to it" do
|
115
|
+
mock_burlap_array = instance_double(Burlap::Array)
|
116
|
+
expect(Burlap::Array).to receive(:[]).with(*array).and_return(mock_burlap_array)
|
117
|
+
expect(mock_burlap_array).to receive(:to_burlap).and_return("<burlap>array</burlap>")
|
118
|
+
|
119
|
+
expect(array.to_burlap).to eq("<burlap>array</burlap>")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Class do
|
4
|
+
describe "#to_burlap" do
|
5
|
+
subject(:burlap) { described_class.new.to_burlap }
|
6
|
+
|
7
|
+
# FIXME: The comment "we can't dump anonymous classes" implies this
|
8
|
+
# shouldn't work or it shouldn't work as it currently does
|
9
|
+
# but the intent has been lost. This test confirms the
|
10
|
+
# current behaviour as implemented.
|
11
|
+
#
|
12
|
+
it "doesn't raise an error" do
|
13
|
+
expect { burlap }.not_to raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns a string" do
|
17
|
+
expect(burlap).to be_a_kind_of(String)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "is returning a string..." do
|
21
|
+
expect(burlap).to eq("<map><type>Class</type></map>")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe FalseClass do
|
4
|
+
describe "#to_burlap" do
|
5
|
+
before do
|
6
|
+
@result = false.to_burlap
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns a string" do
|
10
|
+
expect(@result).to be_a_kind_of(String)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is correct" do
|
14
|
+
expect(@result).to eq("<boolean>0</boolean>")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe Float do
|
4
|
+
describe "#to_burlap" do
|
5
|
+
subject(:burlap) { 5.0.to_burlap }
|
6
|
+
|
7
|
+
it "returns a string" do
|
8
|
+
expect(burlap).to be_a_kind_of(String)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "is correct" do
|
12
|
+
expect(burlap).to eq("<double>5.0</double>")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|