xmlbuilder 0.2.6 → 0.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42a7c1b629722216b6d80b67c770a9ddc6b28cd9
4
- data.tar.gz: 395ad471f2713ed4b11b2c07e1d3860ab8adbdf4
3
+ metadata.gz: 3bd4c789992a5269f5279e618fe048e090f03184
4
+ data.tar.gz: 6a68d9ed39a906f87c7c19839f22bc59568dd900
5
5
  SHA512:
6
- metadata.gz: 462b61b94852841639c8892176a1b4ca8cef1f4c8385bfbf27bb3a21a8bbf7fa3b82f265a174b4c6b86946e09d388172ced39509565358f342513b10c2b7fd11
7
- data.tar.gz: dccf8a82a9405e3d72a87809244868ed6d1886ead40e9e38402f3e717ca999c2c94f7d22dfdd9ad6907e866f6be4c77bc7dccdca3d225dfb6e7aceabc88819ed
6
+ metadata.gz: 2c101946113eea1ca8b65f554e028cd2284400419762a2d0368f90fdc1ebfd0ac6466ca913a11c1699e50936476bed206ec371a52b287a9d8fdb2a8fcce83803
7
+ data.tar.gz: 46fca03eceb72c57ad051af2ee3ab494d9a5654b9d2822a1574b2535267721a60768e7204b4588b93553c2581af2eb2c9203570b3dbeef38d9206d71285ef764
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright 2020 Coderzthereal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,81 @@
1
+ ## This is not the original XmlBuilder library.
2
+ It is a separate library that uses a different interface. I did not write the original XmlBuilder gem, whose owner yanked it from rubygems.org in 2012.
3
+
4
+
5
+ # xmlbuilder: A simple way to build XML
6
+ This library allows you to generate XML in an idiomatic, human-readable way. It's designed to be easy to use to automatically generate XML on the fly or as needed inside your terminal.
7
+
8
+ ## Examples:
9
+ A hard-coded example:
10
+ ```
11
+ xml = XMLBuilder.new
12
+ xml.document type: 'xml', use: 'example' do
13
+ xml.description "This is an example of using XMLBuilder."
14
+ xml.nextmeeting date: Time.now+100000 do
15
+ xml.agenda "Nothing of importance will be decided."
16
+ xml.clearance true, level: 'classified'
17
+ # Passing in true creates a void tag
18
+ end
19
+ end
20
+
21
+ p xml.str
22
+
23
+ # =>
24
+ <document type="xml" use="example">
25
+ <description>This is an example of using XMLBuilder.</description>
26
+ <nextmeeting date="2017-02-10 21:56:56 -0800">
27
+ <agenda>Nothing of importance will be decided.</agenda>
28
+ <clearance level="classified" />
29
+ </nextmeeting>
30
+ </document>
31
+ ```
32
+
33
+ Automatically encoding a data structure:
34
+ ```
35
+ data = [
36
+ {
37
+ title: "Assassin's Apprentice",
38
+ author: "Robin Hobb",
39
+ published: 1995,
40
+ rating: 4.5
41
+ },
42
+ {
43
+ title: "The Fifth Season",
44
+ author: "N. K. Jemisin",
45
+ published: 2015,
46
+ rating: 4.6
47
+ },
48
+ ...
49
+ ].sort_by { |book| book['rating'] }
50
+
51
+ output = XMLBuilder.new
52
+ output.collection genre: 'fantasy' do
53
+ data.each do |book|
54
+ output.book do
55
+ book.each { |field, value| output.add_element field, value }
56
+ end
57
+ end
58
+ end
59
+
60
+ p output
61
+
62
+ # =>
63
+ <collection genre="fantasy">
64
+ <book>
65
+ <title>Assassin's Apprentice</title>
66
+ <author>Robin Hobb</author>
67
+ <published>1995</published>
68
+ <rating>4.5</rating>
69
+ </book>
70
+ ...
71
+ </collection>
72
+ ```
73
+
74
+ ## Installation
75
+ `gem install xmlbuilder`
76
+ or add `gem 'xmlbuilder'` to your Gemfile
77
+
78
+ [Here is the gem repo](https://rubygems.org/gems/xmlbuilder)
79
+
80
+ ## License
81
+ Available for use under the [MIT license](https://opensource.org/licenses/MIT)
@@ -1,78 +1,95 @@
1
- # XMLBuilder is a class that allows you to easily create XML.
2
- # Here's an example:
3
- # xml = XMLBuilder.new
4
- # xml.document :type => 'xml', :use => 'example' do |document|
5
- # document.description { |desc| desc.add "This is an example of using XMLBuilder.\n" }
6
- # document.nextmeeting :date => Time.now+100000 do |meeting|
7
- # meeting.agenda { |agenda| agenda.add "Nothing of importance will be decided.\n" }
8
- # meeting.clearance true, :level => :classified # Passing true in as the first parameter will cause it to be a tag with no closing tag.
9
- # end
10
- # xml.add "I hope that this has been a good example."
11
- # end
12
- # p xml.str
13
- # # <document type="xml" use="example">
14
- # # <description>
15
- # # This is an example of using XMLBuilder.
16
- # # </description>
17
- # # <nextmeeting date="2017-02-10 21:56:56 -0800">
18
- # # <agenda>
19
- # # Nothing of importance will be decided.
20
- # # </agenda>
21
- # # <clearance level="classified" />
22
- # # </nextmeeting>
23
- # # I hope that this has been a good example.
24
- # # </document>
1
+ # XMLBuilder is a library that allows you to easily create XML.
2
+ #
3
+ # Licensed under MIT
4
+ #
5
+ # Written by Coderz
6
+ #
7
+
25
8
  class XMLBuilder
26
- attr_reader :str
27
- # XMLBuilder#initialize simply sets the stored string to "".
28
- def initialize
29
- @str = ""
30
- end
31
- # XMLBuilder#clear does the same thing as #initialize (by delegating to it).
32
- def clear
33
- initialize # That's essentially what it does.
34
- end
35
- # XMLBuilder#add adds a string (with no processing) to the object's string.
36
- def add(str)
37
- @str << str
38
- end
39
- # XMLBuilder#method_missing is the brains of the operation. It takes the name of the tag to add,
40
- # an optional boolean parameter which signifies whether to make it a single tag or not,
41
- # any options to put in the tag, and a block to evaluate between the opening and closing tags.
42
- # There is an alias, XMLBuilder#add_element, which is used for already defined methods such as XMLBuilder#send and
43
- # XMLBuilder#method_missing.
44
- def method_missing(name, *args, &block)
45
- if args.length == 2
46
- one_tag, hash = *args
47
- elsif args.length == 1
48
- if args[0].is_a? Hash
49
- one_tag, hash = *[false, args[0]]
50
- else
51
- one_tag, hash = *[args[0], {}]
52
- end
53
- else
54
- one_tag, hash = false, {}
55
- end
56
- @str << "<#{name}"
57
- if one_tag
58
- hash.each do |k, v|
59
- @str << " #{k}=\"#{v}\""
60
- end
61
- @str << " />\n"
62
- else
63
- hash.each do |k, v|
64
- @str << " #{k}=\"#{v}\""
65
- end
66
- @str << ">\n"
67
- if block
68
- block.call(self)
69
- end
70
- @str << "</#{name}>\n"
71
- end
72
- return @str
73
- end
74
- alias :add_element :method_missing
75
- alias :to_s :str
76
- alias :to_str :str
77
- alias :inspect :str
78
- end
9
+ @@default_separator = " "
10
+ # separator set to two spaces by default, used in nesting
11
+
12
+ attr_reader :str
13
+ attr_accessor :separator
14
+
15
+ def initialize(separator = @@default_separator)
16
+ @str = ""
17
+ @depth = 0
18
+ @separator = separator
19
+ end
20
+
21
+ # Sets the stored string to "" and the depth to 0.
22
+ def clear
23
+ initialize(@separator)
24
+ self
25
+ end
26
+
27
+ # Adds a string (with no preprocessing) to the object's string.
28
+ def add(*strs)
29
+ @str << strs.flatten.join("")
30
+ end
31
+
32
+ # Takes the name of the tag to add, an optional string to put in the tag, an optional boolean parameter which signifies whether to make it a single tag or not, any options to put in the tag, and a block to evaluate between the opening and closing tags. Aliased to #method_missing to allow dynamic tag creation.
33
+ def add_element(name, *args)
34
+ one_tag, internal, attrs = process_args args
35
+
36
+ # logic time
37
+ add indentation, ?<, name
38
+ attrs.each do |attr, value|
39
+ add " #{attr}=\"#{value}\""
40
+ end
41
+ if one_tag
42
+ add " />\n"
43
+ return self
44
+ else
45
+ add ?>
46
+ end
47
+ if internal
48
+ add internal
49
+ elsif block_given?
50
+ @depth += 1
51
+ add "\n"
52
+ yield
53
+ @depth -= 1
54
+ end
55
+ add indentation unless internal
56
+ add "</#{name}>\n"
57
+ return self
58
+ end
59
+
60
+ def process_args(args)
61
+ # Argument cheat sheet:
62
+ # <name hash[0]="hash[1]">
63
+ # internal
64
+ # </name>
65
+
66
+ internal = nil
67
+ if args.size == 2
68
+ if args[0] == !!args[0]
69
+ one_tag, hash = *args
70
+ else
71
+ one_tag, internal, hash = false, *args
72
+ end
73
+ elsif args.size == 1
74
+ if args[0].is_a? Hash
75
+ one_tag, hash = *[false, args[0]]
76
+ elsif args[0] == !!args[0]
77
+ one_tag, hash = args[0], {}
78
+ else
79
+ one_tag, internal, hash = false, args[0].to_s, {}
80
+ end
81
+ else
82
+ one_tag, hash = false, {}
83
+ end
84
+ return one_tag, internal, hash
85
+ end
86
+
87
+ def indentation; @separator * @depth; end
88
+
89
+ alias :method_missing :add_element
90
+ alias :to_s :str
91
+ alias :to_str :str
92
+ alias :inspect :str
93
+ private :process_args, :indentation
94
+ public :add_element
95
+ end
@@ -0,0 +1,5 @@
1
+ # haha testing go brrr
2
+
3
+ require "minitest/autorun"
4
+ require_relative "tags"
5
+ require_relative "examples"
@@ -0,0 +1,100 @@
1
+ require_relative "../lib/xmlbuilder"
2
+
3
+ # This test file contains various HTML snippets and fragments
4
+ # in order to "stress-test" the library. Also I can't think of
5
+ # edge cases so hopefully this will find them.
6
+
7
+ $expected = [] # array of strings
8
+ $actual = [] # array of procs
9
+
10
+ $expected << <<-end
11
+ <html>
12
+ <head>
13
+ <title>Page Title</title>
14
+ </head>
15
+ <body>
16
+ <h1>My First Heading</h1>
17
+ <p>My first paragraph.</p>
18
+ </body>
19
+ </html>
20
+ end
21
+
22
+ $actual << Proc.new do |xml|
23
+ xml.html do
24
+ xml.head do
25
+ xml.title "Page Title"
26
+ end
27
+ xml.body do
28
+ xml.h1 "My First Heading"
29
+ xml.p "My first paragraph."
30
+ end
31
+ end
32
+ end
33
+
34
+ $expected << <<-end
35
+ <note>
36
+ <to>Dave</to>
37
+ <from>The Empress of Death</from>
38
+ <heading>Reminder</heading>
39
+ <body>Don't forget me this weekend!</body>
40
+ </note>
41
+ end
42
+
43
+ $actual << Proc.new do |xml|
44
+ xml.note do
45
+ xml.to "Dave"
46
+ xml.from "The Empress of Death"
47
+ xml.heading "Reminder"
48
+ xml.body 'Don\'t forget me this weekend!'
49
+ end
50
+ end
51
+
52
+ $expected << <<-end
53
+ <bookstore>
54
+ <book category="COOKING">
55
+ <title lang="en">Everyday Italian</title>
56
+ <author>Giada De Laurentiis</author>
57
+ <year>2005</year>
58
+ <price>30.00</price>
59
+ </book>
60
+ <book category="CHILDREN">
61
+ <title lang="en">Harry Potter</title>
62
+ <author>J K. Rowling</author>
63
+ <year>2005</year>
64
+ <price>29.99</price>
65
+ </book>
66
+ </bookstore>
67
+ end
68
+
69
+ $actual << Proc.new do |xml|
70
+ xml.bookstore do
71
+ xml.book category: "COOKING" do
72
+ xml.title "Everyday Italian", lang: "en"
73
+ xml.author "Giada De Laurentiis"
74
+ xml.year "2005"
75
+ xml.price "30.00"
76
+ end
77
+ xml.book category: "CHILDREN" do
78
+ xml.title "Harry Potter", lang: "en"
79
+ xml.author "J K. Rowling"
80
+ xml.year "2005"
81
+ xml.price "29.99"
82
+ end
83
+ end
84
+ end
85
+
86
+ class XMLBuilderStressTest < Minitest::Test
87
+ @@cases = $expected.zip($actual)
88
+
89
+ def setup
90
+ @test_obj = XMLBuilder.new
91
+ end
92
+
93
+ def test_all_cases
94
+ @@cases.each do |expected, actual|
95
+ actual = actual[@test_obj]
96
+ assert_equal expected.to_s, actual.to_s
97
+ @test_obj.clear
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,53 @@
1
+ require_relative "../lib/xmlbuilder"
2
+
3
+ class XMLBuilderTagTest < Minitest::Test
4
+ def setup
5
+ @test_obj = XMLBuilder.new
6
+ end
7
+
8
+ def test_builder_can_create_tags
9
+ @test_obj.add_element "test_tag"
10
+ assert_equal "<test_tag></test_tag>", @test_obj.to_s.chomp
11
+ @test_obj.clear.add_element "test_tag", true # Void element
12
+ assert_equal "<test_tag />", @test_obj.to_s.chomp
13
+ end
14
+
15
+ def test_builder_can_create_attributes
16
+ @test_obj.add_element "test", attr: "value"
17
+ assert_equal '<test attr="value"></test>', @test_obj.to_s.chomp
18
+ end
19
+
20
+ def test_can_handle_non_string_attrs_and_contents
21
+ @test_obj.add_element "test", true, num: 37
22
+ assert_equal '<test num="37" />', @test_obj.to_s.chomp
23
+ @test_obj.clear.add_element "test", 54
24
+ assert_equal "<test>54</test>", @test_obj.to_s.chomp
25
+ end
26
+
27
+ # May move to 'test/examples.rb'
28
+ def test_builder_can_nest_elements_correctly
29
+ expected = <<~end
30
+ <html>
31
+ <head>
32
+ <title>Test Title</title>
33
+ </head>
34
+ <body>
35
+ <p class="content">This is a piece of test content.</p>
36
+ <br />
37
+ </body>
38
+ </html>
39
+ end
40
+
41
+ xml = @test_obj
42
+ xml.html do
43
+ xml.head do
44
+ xml.title "Test Title"
45
+ end
46
+ xml.body do
47
+ xml.p "This is a piece of test content.", 'class': "content"
48
+ xml.br true
49
+ end
50
+ end
51
+ assert_equal expected, xml.str
52
+ end
53
+ end
metadata CHANGED
@@ -1,26 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xmlbuilder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Coderz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-24 00:00:00.000000000 Z
11
+ date: 2020-11-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: This gem allows you to write XML in a very Ruby-ish way. It supports
14
- single tags, nesting tags, and adding strings.
15
- email: asdfsocool@gmail.com
13
+ description: This library allows you to generate XML in an idiomatic, human-readable
14
+ way. It's designed to be easy to use to automatically generate XML on the fly or
15
+ as needed inside your terminal.
16
+ email:
16
17
  executables: []
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
20
- - lib/xmlbuilder.rb
21
- homepage: https://github.com/Coderzthereal/xmlbuilder/
21
+ - "./lib/xmlbuilder.rb"
22
+ - "./test/all.rb"
23
+ - "./test/examples.rb"
24
+ - "./test/tags.rb"
25
+ - LICENSE
26
+ - README.md
27
+ homepage: https://github.com/Coderzthereal/xmlbuilder
22
28
  licenses:
23
- - CC-BY-NC-SA-4.0
29
+ - MIT
24
30
  metadata: {}
25
31
  post_install_message:
26
32
  rdoc_options: []
@@ -30,7 +36,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - ">="
32
38
  - !ruby/object:Gem::Version
33
- version: '0'
39
+ version: '2.3'
34
40
  required_rubygems_version: !ruby/object:Gem::Requirement
35
41
  requirements:
36
42
  - - ">="
@@ -38,8 +44,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
38
44
  version: '0'
39
45
  requirements: []
40
46
  rubyforge_project:
41
- rubygems_version: 2.6.7
47
+ rubygems_version: 2.5.2
42
48
  signing_key:
43
49
  specification_version: 4
44
- summary: A simple gem that allows you to write XML in a very Ruby-ish way
50
+ summary: An idiomatic library allowing you to generate XML
45
51
  test_files: []