commaparty 0.0.2pre → 0.0.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: 3ff205c728b610398ebae49f09f8b3f7bd76b7aa
4
- data.tar.gz: 2fa31a4f7a4267c4a4ddadc1d8288f6b7872f7c2
3
+ metadata.gz: c6e73d560a55fc00b3b576893d73e44430a59ed6
4
+ data.tar.gz: 9e48ba511096e3ea56f0fd04ed90e2663c70db9b
5
5
  SHA512:
6
- metadata.gz: 3b6b55a5955129843ad2c48b2f203c4e46126bc3a3c66fbf87df990d1aaf416a13418165cb60b1aa0e4b5e0f2f7a621ba33c7b2598238a860b62a8abc54921fe
7
- data.tar.gz: 49d7511cb62731b6b664d4bb866252e85a492992930ef8c92f8d17db5e8416e80c9488459cfbc9057f811dc2f3939413c88f73896e1cad61c3f06b2994a77386
6
+ metadata.gz: 058f7d1a5fb6df420d9287fca8db5643b4a3dfcee1f4be03a882441643ed95e812f0e5763967cb08de2bb434c3ce385eb70ab4af75d5db51659fc63015c004bd
7
+ data.tar.gz: e05832615dfff1cebff80dd2ec1a207032ccfe627d4315de6cf11a86b96afb32c3314db71d2208eee9f396fd945d0cc349f217ff706d56061272338458fc98c5
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  CommaParty
2
2
  ======
3
+ [![Build Status](https://travis-ci.org/ecmendenhall/commaparty.png?branch=master)](https://travis-ci.org/ecmendenhall/commaparty)
4
+
3
5
  CommaParty is a Ruby implementation of Clojure's
4
6
  [Hiccup](https://github.com/weavejester/hiccup/) HTML generation library.
5
7
  It uses arrays to represent elements, and hashes to represent an element's
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -17,5 +17,9 @@ module CommaParty
17
17
  CommaParty::Markup.new(hiccup).call
18
18
  end
19
19
 
20
+ def self.builder(hiccup)
21
+ CommaParty::Markup.new(hiccup).builder
22
+ end
23
+
20
24
  end
21
25
 
@@ -9,29 +9,36 @@ module CommaParty
9
9
  end
10
10
 
11
11
  def call
12
+ build(@hiccup).doc.to_html
13
+ end
14
+
15
+ def builder
12
16
  build(@hiccup)
13
17
  end
14
18
 
19
+ def hiccup
20
+ @hiccup.flatten(1)
21
+ end
22
+
15
23
  private
16
24
 
17
25
  def build(elements)
18
- doc = Nokogiri::XML::Builder.new do |doc|
19
- doc.root do |root|
20
- elements.each do |element|
21
- create_child(root, element)
22
- end
26
+ Nokogiri::XML::Builder.new do |doc|
27
+ elements.each do |element|
28
+ create_child(doc, element)
23
29
  end
24
- end.doc.root.children.to_html
30
+ end
25
31
  end
26
32
 
27
33
  def create_child(node, element)
34
+ return if element == []
28
35
  tag, attributes, children = CommaParty::DestructureElement.new(element).call
29
36
  node.send(tag, attributes) {|n| make_nodes(n, children) }
30
37
  end
31
38
 
32
39
  def make_nodes(parent, children)
33
40
  children.each do |child|
34
- if child.is_a?(String) || child.is_a?(Fixnum)
41
+ if terminal?(child)
35
42
  parent << child.to_s
36
43
  else
37
44
  create_child(parent, child)
@@ -39,5 +46,11 @@ module CommaParty
39
46
  end
40
47
  end
41
48
 
49
+ def terminal?(child)
50
+ child.is_a?(String) ||
51
+ child.is_a?(Fixnum) ||
52
+ child.nil?
53
+ end
54
+
42
55
  end
43
56
  end
@@ -1,3 +1,3 @@
1
1
  module CommaParty
2
- VERSION = "0.0.2pre"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -9,20 +9,13 @@ module CommaParty
9
9
  end
10
10
 
11
11
  def initialize(markup)
12
- @markup = CommaParty::Markup.new(markup).call
12
+ @markup = CommaParty::Markup.new(markup)
13
13
  end
14
14
 
15
15
  def call
16
- build(@markup)
16
+ @markup.builder.to_xml
17
17
  end
18
18
 
19
- private
20
-
21
- def build(markup)
22
- Nokogiri::XML::Builder.new do |doc|
23
- doc << markup
24
- end.to_xml
25
- end
26
19
  end
27
20
 
28
21
  end
@@ -46,7 +46,7 @@ describe CommaParty::DestructureElement do
46
46
  expect(body).to eq([[:li, "one"], [:li, "two"], [:li, "three"]])
47
47
  end
48
48
 
49
- it 'wat' do
49
+ it 'destructures an element with a tag in the body' do
50
50
  tag, attributes, body = described_class.new([:p, [:em, "hello"]]).call
51
51
  expect(tag).to eq(:p_)
52
52
  expect(attributes).to eq({})
@@ -7,42 +7,180 @@ describe CommaParty::Markup do
7
7
 
8
8
  it 'generates a single tag' do
9
9
  html = described_class.new([:tag]).call
10
- expect(html).to eq("<tag></tag>")
10
+ expect(html).to eq("<tag></tag>\n")
11
11
  end
12
12
 
13
13
  it 'generates a single tag with an attribute' do
14
14
  html = described_class.new([:tag, {attribute: 'something'}]).call
15
- expect(html).to eq("<tag attribute=\"something\"></tag>")
15
+ expect(html).to eq("<tag attribute=\"something\"></tag>\n")
16
16
  end
17
17
 
18
18
  it 'generates a single tag with a value' do
19
19
  html = described_class.new([:tag, 'value']).call
20
- expect(html).to eq("<tag>value</tag>")
20
+ expect(html).to eq("<tag>value</tag>\n")
21
21
  end
22
22
 
23
23
  it 'generates two sibling tags' do
24
24
  html = described_class.new([:div, [:tag1], [:tag2]]).call
25
- expect(html).to eq("<div>\n<tag1></tag1><tag2></tag2>\n</div>")
25
+ expect(html).to eq("<div>\n<tag1></tag1><tag2></tag2>\n</div>\n")
26
26
  end
27
27
 
28
28
  it 'generates nested tags' do
29
- html = described_class.new([:theparent, [:tag1], [:tag2]]).call
30
- expect(html).to eq("<theparent><tag1></tag1><tag2></tag2></theparent>")
29
+ nested = [:parent, [:tag1, [:tag2, [:tag3, [:tag4, 'deep', [:tag5, 'nesting']]]]]]
30
+ html = described_class.new(nested).call
31
+ expect(html).to eq("<parent><tag1><tag2><tag3><tag4>deep<tag5>nesting</tag5></tag4></tag3></tag2></tag1></parent>\n")
31
32
  end
32
33
 
33
34
  it 'handles tags with the same names as ruby methods' do
34
35
  html = described_class.new([:parent]).call
35
- expect(html).to eq("<parent></parent>")
36
+ expect(html).to eq("<parent></parent>\n")
36
37
  end
37
38
 
38
39
  it 'handles tags with shortcut syntax' do
39
40
  html = described_class.new([:'tag.one.two.three#id']).call
40
- expect(html).to eq("<tag class=\"one two three\" id=\"id\"></tag>")
41
+ expect(html).to eq("<tag class=\"one two three\" id=\"id\"></tag>\n")
41
42
  end
42
43
 
43
44
  it 'handles seqs in the tag body' do
44
45
  html = described_class.new([:ul, ["one", "two", "three"].map {|n| [:li, n]}]).call
45
- expect(html).to eq("<ul>\n<li>one</li>\n<li>two</li>\n<li>three</li>\n</ul>")
46
+ expect(html).to eq("<ul>\n<li>one</li>\n<li>two</li>\n<li>three</li>\n</ul>\n")
47
+ end
48
+
49
+ it 'handles nils in the tag body' do
50
+ html = described_class.new([:div, nil]).call
51
+ expect(html).to eq("<div></div>\n")
52
+ end
53
+
54
+ it 'handles empty arrays in the tag body' do
55
+ html = described_class.new([:div, [], 'he', [[]], 'llo']).call
56
+ expect(html).to eq("<div>hello</div>\n")
57
+ end
58
+ end
59
+
60
+ describe 'Generating builders' do
61
+
62
+ it 'returns a Nokogiri builder' do
63
+ builder = described_class.new([:div]).builder
64
+ expect(builder.class).to eq(Nokogiri::XML::Builder)
65
+ end
66
+
67
+ it 'produces the same XML' do
68
+ markup = described_class.new([:div, [:span, 'lol']])
69
+ expect(markup.builder.doc.to_html).to eq(markup.call)
70
+ end
71
+
72
+ end
73
+
74
+ describe 'Retrieving hiccup' do
75
+
76
+ it 'returns its hiccup' do
77
+ hiccup = described_class.new([:div, [:ul, (1..3).map {|n| [:li, n]}]]).hiccup
78
+ expect(hiccup).to eq([:div, [:ul, [[:li, 1], [:li, 2], [:li, 3]]]])
79
+ end
80
+
81
+ end
82
+
83
+ describe 'Hiccup specs' do
84
+
85
+ describe 'basic tags' do
86
+ specify { expect(described_class.new([:div]).call).to eq("<div></div>\n") }
87
+ specify { expect(described_class.new(["div"]).call).to eq("<div></div>\n") }
88
+ end
89
+
90
+ describe 'tag syntax sugar' do
91
+ specify { expect(described_class.new([:'div#foo']).call).to eq("<div id=\"foo\"></div>\n") }
92
+ specify { expect(described_class.new([:'div.foo']).call).to eq("<div class=\"foo\"></div>\n") }
93
+ specify { expect(described_class.new([:'div.foo', ["bar", "baz"].join]).call).
94
+ to eq("<div class=\"foo\">barbaz</div>\n") }
95
+ specify { expect(described_class.new([:'div.a.b']).call).to eq("<div class=\"a b\"></div>\n") }
96
+ specify { expect(described_class.new([:'div.a.b.c']).call).to eq("<div class=\"a b c\"></div>\n") }
97
+ specify { expect(described_class.new([:'div#foo.bar.baz']).call).
98
+ to eq("<div class=\"bar baz\" id=\"foo\"></div>\n") }
99
+ end
100
+
101
+ describe 'tag contents' do
102
+ specify { expect(described_class.new([:div]).call).to eq("<div></div>\n") }
103
+ specify { expect(described_class.new([:h1]).call).to eq("<h1></h1>\n") }
104
+ specify { expect(described_class.new([:script]).call).to eq("<script></script>\n") }
105
+ specify { expect(described_class.new([:text]).call).to eq("<text></text>\n") }
106
+ specify { expect(described_class.new([:a]).call).to eq("<a></a>\n") }
107
+ specify { expect(described_class.new([:iframe]).call).to eq("<iframe></iframe>\n") }
108
+ specify { expect(described_class.new([:title]).call).to eq("<title></title>\n") }
109
+ specify { expect(described_class.new([:section]).call).to eq("<section></section>\n") }
110
+ specify { expect(described_class.new([:select]).call).to eq("<select></select>\n") }
111
+ specify { expect(described_class.new([:object]).call).to eq("<object></object>\n") }
112
+ specify { expect(described_class.new([:video]).call).to eq("<video></video>\n") }
113
+ end
114
+
115
+ describe 'tags containing text' do
116
+ specify { expect(described_class.new([:text, "Lorem Ipsum"]).call).
117
+ to eq("<text>Lorem Ipsum</text>\n") }
118
+ end
119
+
120
+ describe 'contents are concatenated' do
121
+ specify { expect(described_class.new([:body, "foo", "bar"]).call).
122
+ to eq("<body>foobar</body>\n") }
123
+ specify { expect(described_class.new([:body, [:p], [:br]]).call).
124
+ to eq("<body>\n<p></p>\n<br>\n</body>\n") }
125
+ end
126
+
127
+ describe 'seqs are expanded' do
128
+ specify { expect(described_class.new([:body, ["foo", "bar"]]).call).
129
+ to eq("<body>foobar</body>\n") }
130
+ end
131
+
132
+ describe 'tags can contain tags' do
133
+ specify { expect(described_class.new([:div, [:p]]).call).
134
+ to eq("<div><p></p></div>\n") }
135
+ specify { expect(described_class.new([:div, [:b]]).call).
136
+ to eq("<div><b></b></div>\n") }
137
+ specify { expect(described_class.new([:p, [:span, [:a, "foo"]]]).call).
138
+ to eq("<p><span><a>foo</a></span></p>\n") }
139
+ end
140
+
141
+ describe 'tag with blank attribute map' do
142
+ specify { expect(described_class.new([:xml, {}]).call).
143
+ to eq("<xml></xml>\n") }
144
+ end
145
+
146
+ describe 'tag with populated attribute map' do
147
+ specify { expect(described_class.new([:xml, {a: "1", b: "2"}]).call).
148
+ to eq("<xml a=\"1\" b=\"2\"></xml>\n") }
149
+ specify { expect(described_class.new([:img, {id: "foo"}]).call).
150
+ to eq("<img id=\"foo\">\n") }
151
+ end
152
+
153
+ describe 'tag content can be vars' do
154
+ var = "foo"
155
+ specify { expect(described_class.new([:span, var]).call).
156
+ to eq("<span>foo</span>\n") }
157
+ end
158
+
159
+ describe 'tag content can be function calls' do
160
+ specify { expect(described_class.new([:span, [1, 1].inject(:+)]).call).
161
+ to eq("<span>2</span>\n") }
162
+ specify { expect(described_class.new([:span, {foo: "bar"}.fetch(:foo)]).call).
163
+ to eq("<span>bar</span>\n") }
164
+ end
165
+
166
+ describe 'attributes can contain vars' do
167
+ var = "foo"
168
+ specify { expect(described_class.new([:xml, {x: var}]).call).
169
+ to eq("<xml x=\"foo\"></xml>\n") }
170
+ specify { expect(described_class.new([:xml, {x: var}, "bar"]).call).
171
+ to eq("<xml x=\"foo\">bar</xml>\n") }
172
+ end
173
+
174
+ describe 'attributes can contain function calls' do
175
+
176
+ def foo
177
+ "foo"
178
+ end
179
+
180
+ specify { expect(described_class.new([:img, {src: ["/foo", "/bar"].join}]).call).
181
+ to eq("<img src=\"/foo/bar\">\n") }
182
+ specify { expect(described_class.new([:div, {id: ["a", "b"].join}, foo]).call).
183
+ to eq("<div id=\"ab\">foo</div>\n") }
46
184
  end
47
185
 
48
186
  end
@@ -3,7 +3,7 @@ require 'commaparty/parse_body'
3
3
 
4
4
  describe CommaParty::ParseBody do
5
5
 
6
- it 'returns nil for tags with no body' do
6
+ it 'returns [] for tags with no body' do
7
7
  body = described_class.new([:tag]).call
8
8
  expect(body).to eq([])
9
9
  end
@@ -3,40 +3,46 @@ require 'commaparty'
3
3
  describe CommaParty do
4
4
 
5
5
  it 'has a helpful html method' do
6
- expect(CommaParty.html([:tag])).to match('<html><tag></tag></html>')
6
+ expect(CommaParty.html([:tag])).to match("<html><tag></tag></html>\n")
7
7
  end
8
8
 
9
9
  it 'has a helpful xml method' do
10
- expect(CommaParty.xml([:tag])).to match('<tag/>')
10
+ expect(CommaParty.xml([:tag])).to match("<tag/>\n")
11
11
  end
12
12
 
13
13
  it 'has a helpful markup method' do
14
- expect(CommaParty.markup([:tag])).to match('<tag></tag>')
14
+ expect(CommaParty.markup([:tag])).to match("<tag></tag>\n")
15
+ end
16
+
17
+ it 'has a helpful builder method' do
18
+ builder = CommaParty.builder([:tag])
19
+ expect(builder.class).to eq(Nokogiri::XML::Builder)
20
+ expect(builder.doc.to_html).to eq(CommaParty.markup([:tag]))
15
21
  end
16
22
 
17
23
  context 'converts ruby syntax to html string' do
18
- it { expect(CommaParty.markup [:script]).to eq "<script></script>" }
19
- it { expect(CommaParty.markup [:p, "hello"]).to eq "<p>hello</p>" }
20
- it { expect(CommaParty.markup [:p, [:em, "hello"]]).to eq "<p><em>hello</em></p>" }
21
- it { expect(CommaParty.markup [:span, {:class => "foo"}, "bar"]).to eq "<span class=\"foo\">bar</span>" }
22
- it { expect(CommaParty.markup [:div, {id: "email", class: "selected starred"}, "..."]).to eq "<div id=\"email\" class=\"selected starred\">...</div>" }
23
- it { expect(CommaParty.markup [:a, {:href => "http://github.com"}, "GitHub"]).to eq "<a href=\"http://github.com\">GitHub</a>"}
24
+ it { expect(CommaParty.markup [:script]).to eq "<script></script>\n" }
25
+ it { expect(CommaParty.markup [:p, "hello"]).to eq "<p>hello</p>\n" }
26
+ it { expect(CommaParty.markup [:p, [:em, "hello"]]).to eq "<p><em>hello</em></p>\n" }
27
+ it { expect(CommaParty.markup [:span, {:class => "foo"}, "bar"]).to eq "<span class=\"foo\">bar</span>\n" }
28
+ it { expect(CommaParty.markup [:div, {id: "email", class: "selected starred"}, "..."]).to eq "<div id=\"email\" class=\"selected starred\">...</div>\n" }
29
+ it { expect(CommaParty.markup [:a, {:href => "http://github.com"}, "GitHub"]).to eq "<a href=\"http://github.com\">GitHub</a>\n"}
24
30
 
25
31
  context 'collections' do
26
- it { expect(CommaParty.markup [:ul, ['a','b'].map { |x| [:li, x]}]).to eq "<ul>\n<li>a</li>\n<li>b</li>\n</ul>"}
27
- it { expect(CommaParty.markup [:ul, (11...13).map { |n| [:li, n]}]).to eq "<ul>\n<li>11</li>\n<li>12</li>\n</ul>"}
32
+ it { expect(CommaParty.markup [:ul, ['a','b'].map { |x| [:li, x]}]).to eq "<ul>\n<li>a</li>\n<li>b</li>\n</ul>\n"}
33
+ it { expect(CommaParty.markup [:ul, (11...13).map { |n| [:li, n]}]).to eq "<ul>\n<li>11</li>\n<li>12</li>\n</ul>\n"}
28
34
  end
29
35
 
30
36
  context 'css shorthand' do
31
- it { expect(CommaParty.markup [:'p.hi', "hello"]).to eq "<p class=\"hi\">hello</p>" }
32
- it { expect(CommaParty.markup [:'p#hi', "hello"]).to eq "<p id=\"hi\">hello</p>" }
33
- it { expect(CommaParty.markup [:'p.hi.greet.left', "hello"]).to eq "<p class=\"hi greet left\">hello</p>" }
34
- it { expect(CommaParty.markup [:'p#hi.greet.left', "hello"]).to eq "<p class=\"greet left\" id=\"hi\">hello</p>" }
37
+ it { expect(CommaParty.markup [:'p.hi', "hello"]).to eq "<p class=\"hi\">hello</p>\n" }
38
+ it { expect(CommaParty.markup [:'p#hi', "hello"]).to eq "<p id=\"hi\">hello</p>\n" }
39
+ it { expect(CommaParty.markup [:'p.hi.greet.left', "hello"]).to eq "<p class=\"hi greet left\">hello</p>\n" }
40
+ it { expect(CommaParty.markup [:'p#hi.greet.left', "hello"]).to eq "<p class=\"greet left\" id=\"hi\">hello</p>\n" }
35
41
  end
36
42
 
37
43
  context 'different shaped trees' do
38
- it { expect(CommaParty.markup [:p, "Hello ", [:em, "World!"]]).to eq "<p>Hello <em>World!</em></p>" }
39
- it { expect(CommaParty.markup [:div, [:p, "Hello"], [:em, "World!"]]).to eq "<div>\n<p>Hello</p>\n<em>World!</em>\n</div>" }
44
+ it { expect(CommaParty.markup [:p, "Hello ", [:em, "World!"]]).to eq "<p>Hello <em>World!</em></p>\n" }
45
+ it { expect(CommaParty.markup [:div, [:p, "Hello"], [:em, "World!"]]).to eq "<div>\n<p>Hello</p>\n<em>World!</em>\n</div>\n" }
40
46
  end
41
47
  end
42
48
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: commaparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2pre
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connor Mendenhall
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-07 00:00:00.000000000 Z
11
+ date: 2014-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -88,12 +88,14 @@ extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
90
  - .gitignore
91
+ - .travis.yml
91
92
  - Gemfile
92
93
  - LICENSE.txt
93
94
  - README.md
94
95
  - Rakefile
95
96
  - commaparty.gemspec
96
97
  - lib/commaparty.rb
98
+ - lib/commaparty/.markup.rb.swn
97
99
  - lib/commaparty/destructure_element.rb
98
100
  - lib/commaparty/html.rb
99
101
  - lib/commaparty/markup.rb
@@ -125,9 +127,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
127
  version: '0'
126
128
  required_rubygems_version: !ruby/object:Gem::Requirement
127
129
  requirements:
128
- - - '>'
130
+ - - '>='
129
131
  - !ruby/object:Gem::Version
130
- version: 1.3.1
132
+ version: '0'
131
133
  requirements: []
132
134
  rubyforge_project:
133
135
  rubygems_version: 2.0.3