commaparty 0.0.2pre → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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