fragment 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 05b9ed2ebd1d81634b699810495aca5a66acb46e
4
+ data.tar.gz: 8d11babc8d25ade0f40112ec8c0c111cae637064
5
+ SHA512:
6
+ metadata.gz: a69a5f02a542d5acde4b37643a8cbf8cda4fbb5afe52b45468aebadb189b5d7e178c142dbb4c3628d39c7ff87f7dee3baf6b77a97a19aa76ebbca6a9a0bb8816
7
+ data.tar.gz: cf3b9dd2585853d1d4114874e304581838fe64423aa84144d771a3e808443663698f04f865bda30fac6a9166e96864f3898498645e497d2d8cf06790b9230d4c
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ gemspec
2
+
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fragment (1.0.0)
5
+
6
+ GEM
7
+ specs:
8
+ diff-lcs (1.2.5)
9
+ rspec (3.2.0)
10
+ rspec-core (~> 3.2.0)
11
+ rspec-expectations (~> 3.2.0)
12
+ rspec-mocks (~> 3.2.0)
13
+ rspec-core (3.2.2)
14
+ rspec-support (~> 3.2.0)
15
+ rspec-expectations (3.2.0)
16
+ diff-lcs (>= 1.2.0, < 2.0)
17
+ rspec-support (~> 3.2.0)
18
+ rspec-mocks (3.2.1)
19
+ diff-lcs (>= 1.2.0, < 2.0)
20
+ rspec-support (~> 3.2.0)
21
+ rspec-support (3.2.2)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ fragment!
28
+ rspec
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Mickael Riga
1
+ Copyright (c) 2011-2015 Mickael Riga
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -16,4 +16,5 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
16
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
17
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
18
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- THE SOFTWARE.
19
+ THE SOFTWARE.
20
+
data/README.md CHANGED
@@ -9,49 +9,65 @@ In essence, Fragment works more or less like any builder.
9
9
 
10
10
  First, how to install:
11
11
 
12
- gem install fragment
12
+ ```
13
+ gem install fragment
14
+ ```
15
+
16
+ Or in your `Gemfile`:
17
+
18
+ ```
19
+ gem 'fragment'
20
+ ```
13
21
 
14
22
  Then you can require Fragment and use it that way:
15
23
 
16
- require 'fragment'
17
-
18
- default = 'HTML'
19
-
20
- html = Fragment.create do
21
- doctype
22
- html(:lang=>'en') do
23
- head { title { "My Choice" } }
24
- body do
25
- comment "Here starts the body"
26
- select(:name => 'language') do
27
- ['JS', 'HTML', 'CSS'].each do |l|
28
- option(:value => l, :selected => l==default) { l }
29
- end
30
- end
31
- write "\n<!-- This allows to write HTML directly when using a snippet -->\n"
32
- write "\n<!-- like Google Analytics or including another fragment -->\n"
24
+ ```
25
+ require 'fragment'
26
+
27
+ default = 'HTML'
28
+
29
+ html = Fragment.create do
30
+ doctype
31
+ html(:lang=>'en') do
32
+ head { title { "My Choice" } }
33
+ body do
34
+ comment "Here starts the body"
35
+ select(:name => 'language') do
36
+ ['JS', 'HTML', 'CSS'].each do |l|
37
+ option(:value => l, :selected => l==default) { l }
33
38
  end
34
39
  end
35
- end
40
+ write "\n<!-- This allows to write HTML directly when using a snippet -->\n"
41
+ write "\n<!-- like Google Analytics or including another fragment -->\n"
42
+ end
43
+ end
44
+ end
45
+ ```
36
46
 
37
47
  If you try this example, you might notice a couple of things:
38
48
 
39
49
  First of all, you have a `doctype` helper which only creates an HTML5 doctype.
40
- If you want something else, you can use the `write` method which lets you write directly in place:
50
+ If you want something else, you can use the `write` method which lets you
51
+ write directly in place:
41
52
 
42
- write "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'"
43
- write " 'http://www.w3.org/TR/html4/strict.dtd'>"
53
+ ```
54
+ write "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'"
55
+ write " 'http://www.w3.org/TR/html4/strict.dtd'>"
56
+ ```
44
57
 
45
- The major difference with Gestalt (if you used it) is that it does not accept content
46
- in the arguments. This simplifies the code a lot for a very small sacrifice.
47
- So the argument is either a Hash that represents the attributes, or a string like
48
- you would write in the HTML code.
58
+ The major difference with Gestalt (if you used it) is that it does not accept
59
+ content in the arguments. This simplifies the code a lot for a very small
60
+ sacrifice. So the argument is either a Hash that represents the attributes,
61
+ or a string like you would write in the HTML code.
49
62
 
50
- One problem I had when creating fragments of HTML from code with a Hash for attributes
51
- is for attributes like 'selected' or 'checked' which are a bit annoying because they do
52
- not have a negative value (not that I know of), so you cannot write things like:
63
+ One problem I had when creating fragments of HTML from code with a Hash for
64
+ attributes is for attributes like `selected` or `checked` which are a bit
65
+ annoying because they do not have a negative value (not that I know of),
66
+ so you cannot write things like:
53
67
 
54
- selected='not_selected'
68
+ ```
69
+ selected='not_selected'
70
+ ```
55
71
 
56
72
  I find this slightly irritating.
57
73
  So what I did is that in the Hash, when a value is false, its key is removed.
@@ -59,11 +75,17 @@ This is what I did on the long example above for marking the default option.
59
75
 
60
76
  Nothing fancy but quite good to be aware of.
61
77
 
62
- If you do something and want to keep the scope you are in, you can use `create_here` instead of `here`. You then have access to the methods through the fragment object passed to the block:
63
-
64
- html = Fragment.create_here do |f|
65
- f.h1 { "" }
66
- end
78
+ If you need more control on the scope of variables and basically stay in the
79
+ scope you are in, you can add an argument to the block which represents the
80
+ fragment itself. The change of arity changes the scope and since you are in the
81
+ current scope, every fragment method has to be called on the fragment object.
82
+ Here is an example which hopefully makes it clearer:
83
+
84
+ ```
85
+ html = Fragment.create do |f|
86
+ f.h1 { "" }
87
+ end
88
+ ```
67
89
 
68
90
  Do not hesitate to fork the project if you want to help me improve it.
69
91
 
@@ -1,13 +1,21 @@
1
+ require_relative './lib/fragment/version'
2
+
1
3
  Gem::Specification.new do |s|
4
+
2
5
  s.name = 'fragment'
3
- s.version = "1.0.0"
4
- s.platform = Gem::Platform::RUBY
6
+ s.version = Fragment.version
5
7
  s.summary = "Lightweight HTML builder"
6
8
  s.description = "An HTML builder heavily based on Gestalt from the Ramaze framework. Its main purpose is to create fragments (hence the name), but is perfectly suited for building full pages."
7
- s.files = `git ls-files`.split("\n").sort
8
- s.require_path = './lib'
9
9
  s.author = "Mickael Riga"
10
10
  s.email = "mig@mypeplum.com"
11
11
  s.homepage = "https://github.com/mig-hub/fragment"
12
- s.add_development_dependency(%q<bacon>, "~> 1.1.0")
12
+ s.licenses = ['MIT']
13
+
14
+ s.platform = Gem::Platform::RUBY
15
+ s.require_path = './lib'
16
+ s.files = `git ls-files`.split("\n").sort
17
+ s.test_files = s.files.select { |p| p =~ /^spec\/.*_spec.rb/ }
18
+
19
+ s.add_development_dependency("rspec")
13
20
  end
21
+
@@ -1,13 +1,19 @@
1
+ require 'fragment/version'
2
+
1
3
  class Fragment
2
4
  attr_accessor :to_s
3
5
 
4
- def self.create(&block); self.new(false,&block).to_s; end
5
- def self.create_here(&block); self.new(true,&block).to_s; end
6
+ def self.create(&block); self.new(&block).to_s; end
7
+ # create_here is kept for backward compatibility
8
+ def self.create_here(&block); self.new(&block).to_s; end
6
9
 
7
10
  def initialize outer_scope=false, &block
11
+ # outer_scope argument is kept for backward compatibility
12
+ # but it is not used
13
+ # checking is simpler with arity instead
8
14
  @to_s = ""
9
15
  return self unless block_given?
10
- unless outer_scope
16
+ if block.arity==0
11
17
  instance_eval(&block)
12
18
  else
13
19
  block.call(self)
@@ -0,0 +1,7 @@
1
+ class Fragment
2
+ VERSION = [1,1,0]
3
+ def self.version
4
+ VERSION.join('.')
5
+ end
6
+ end
7
+
@@ -0,0 +1,190 @@
1
+ # encoding: utf-8
2
+ require "fragment"
3
+
4
+ RSpec.describe Fragment do
5
+
6
+ def fragment(&block); Fragment.create(&block); end
7
+
8
+ it "Builds simple tags" do
9
+ expect(fragment{ br }).to eq '<br />'
10
+ expect(fragment{ p }).to eq '<p />'
11
+ end
12
+
13
+ it "Opens and closes tags" do
14
+ expect(fragment{ p{} }).to eq '<p></p>'
15
+ expect(fragment{ div{} }).to eq '<div></div>'
16
+ end
17
+
18
+ it "Nests tags" do
19
+ expect(fragment{ p{ br } }).to eq '<p><br /></p>'
20
+ end
21
+
22
+ it "Builds deeply nested tags" do
23
+ expect(fragment do
24
+ p do
25
+ div do
26
+ ol do
27
+ li
28
+ end
29
+ end
30
+ end
31
+ end).to eq '<p><div><ol><li /></ol></div></p>'
32
+ end
33
+
34
+ it "Builds deeply nested tags with repetition" do
35
+ expect(fragment do
36
+ p do
37
+ div do
38
+ ol do
39
+ li
40
+ li
41
+ end
42
+ ol do
43
+ li
44
+ li
45
+ end
46
+ end
47
+ end
48
+ end).to eq '<p><div><ol><li /><li /></ol><ol><li /><li /></ol></div></p>'
49
+ end
50
+
51
+ it "Builds deeply nested tags with strings" do
52
+ expect(fragment do
53
+ p do
54
+ div {'Hello, World'}
55
+ end
56
+ end).to eq '<p><div>Hello, World</div></p>'
57
+ end
58
+
59
+ it "Allows to write directly if needed" do
60
+ expect(fragment do
61
+ write "<!DOCTYPE html>"
62
+ end).to eq '<!DOCTYPE html>'
63
+ end
64
+
65
+ it "Builds a full HTML page" do
66
+ expect(fragment do
67
+ doctype
68
+ html do
69
+ head do
70
+ title {"Hello World"}
71
+ end
72
+ body do
73
+ h1 {"Hello World"}
74
+ end
75
+ end
76
+ end).to eq "<!DOCTYPE html>\n<html><head><title>Hello World</title></head><body><h1>Hello World</h1></body></html>"
77
+ end
78
+
79
+ it "Builds with some ruby inside" do
80
+ expect(fragment do
81
+ table do
82
+ tr do
83
+ %w[one two three].each do |s|
84
+ td{s}
85
+ end
86
+ end
87
+ end
88
+ end).to eq '<table><tr><td>one</td><td>two</td><td>three</td></tr></table>'
89
+ end
90
+
91
+ it "Builds escapeable attributes" do
92
+ expect(fragment {
93
+ a(:href => "http://example.org/?a=one&b=two") {
94
+ "Click here"
95
+ }
96
+ }).to eq "<a href='http://example.org/?a=one&amp;b=two'>Click here</a>"
97
+ end
98
+
99
+ it "Should accept attributes in a string" do
100
+ expect(fragment{ input("type='text'") }).to eq "<input type='text' />"
101
+ end
102
+
103
+ it 'Should accept symbols as attributes' do
104
+ input = fragment{ input(:type => :text, :value => :one) }
105
+
106
+ expect(input).to match /type='text'/
107
+ expect(input).to match /value='one'/
108
+ end
109
+
110
+ it 'Builds tags with prefix' do
111
+ expect(fragment{ tag "prefix:local" }).to eq '<prefix:local />'
112
+ end
113
+
114
+ it 'Builds tags with a variety of characters' do
115
+ # with "-"
116
+ expect(fragment{ tag "hello-world" }).to eq '<hello-world />'
117
+ # with Hiragana
118
+ expect(fragment{ tag "あいうえお" }).to eq '<あいうえお />'
119
+ end
120
+
121
+ it "Has a practicle way to add attributes like 'selected' based on boolean" do
122
+ @selected = false
123
+ expect(fragment do
124
+ option({:name => 'opt', :selected => @selected})
125
+ option(:name => 'opt', :selected => !@selected)
126
+ option(:name => 'opt', :selected => @i_am_nil)
127
+ end).to eq "<option name='opt' /><option name='opt' selected='true' /><option name='opt' />"
128
+ end
129
+
130
+ it "Builds a more complex HTML page with a variable in the outer scope" do
131
+
132
+ default = 'HTML'
133
+
134
+ html = Fragment.new do
135
+ doctype
136
+ html(:lang=>'en') do
137
+ head { title { "My Choice" } }
138
+ body do
139
+ comment "Here starts the body"
140
+ select(:name => 'language') do
141
+ ['JS', 'HTML', 'CSS'].each do |l|
142
+ option(:value => l, :selected => l==default) { l }
143
+ end
144
+ end
145
+ write "\n<!-- This allows to write HTML directly when using a snippet -->\n"
146
+ write "\n<!-- like Google Analytics or including another fragment -->\n"
147
+ end
148
+ end
149
+ end.to_s
150
+
151
+ expect(html).to eq "<!DOCTYPE html>\n<html lang='en'><head><title>My Choice</title></head><body>\n<!-- Here starts the body -->\n<select name='language'><option value='JS'>JS</option><option value='HTML' selected='true'>HTML</option><option value='CSS'>CSS</option></select>\n<!-- This allows to write HTML directly when using a snippet -->\n\n<!-- like Google Analytics or including another fragment -->\n</body></html>"
152
+
153
+ end
154
+
155
+ it 'Can be used inside the scope of an object' do
156
+ class Stranger
157
+ attr_accessor :name, :comment
158
+ def show_comment
159
+ Fragment.create do |b|
160
+ b.p{ self.comment }
161
+ end
162
+ end
163
+ def show_summary
164
+ Fragment.create do |b|
165
+ b.article do
166
+ b.h1{ self.name }
167
+ b.p{ self.comment }
168
+ end
169
+ end
170
+ end
171
+ def fail_summary
172
+ Fragment.create do
173
+ article do
174
+ h1{ self.name }
175
+ p{ self.comment }
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ s = Stranger.new
182
+ s.name = 'The Doors'
183
+ s.comment = 'Strange days'
184
+ expect(s.show_comment).to eq '<p>Strange days</p>'
185
+ expect(s.show_summary).to eq '<article><h1>The Doors</h1><p>Strange days</p></article>'
186
+ expect(s.fail_summary).to eq "<article><h1><name /></h1><p>\n<!-- -->\n</p></article>"
187
+ end
188
+
189
+ end
190
+
@@ -0,0 +1,21 @@
1
+ RSpec.configure do |config|
2
+
3
+ config.expect_with :rspec do |expectations|
4
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
5
+ end
6
+ config.mock_with :rspec do |mocks|
7
+ mocks.verify_partial_doubles = true
8
+ end
9
+ config.filter_run :focus
10
+ config.run_all_when_everything_filtered = true
11
+ config.disable_monkey_patching!
12
+ config.warnings = true
13
+ if config.files_to_run.one?
14
+ config.default_formatter = 'doc'
15
+ end
16
+ config.profile_examples = 10
17
+ config.order = :random
18
+ Kernel.srand config.seed
19
+
20
+ end
21
+
metadata CHANGED
@@ -1,32 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fragment
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
5
- prerelease:
4
+ version: 1.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Mickael Riga
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-10-29 00:00:00.000000000 Z
11
+ date: 2015-07-01 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: bacon
14
+ name: rspec
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
- version: 1.1.0
19
+ version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
- version: 1.1.0
26
+ version: '0'
30
27
  description: An HTML builder heavily based on Gestalt from the Ramaze framework. Its
31
28
  main purpose is to create fragments (hence the name), but is perfectly suited for
32
29
  building full pages.
@@ -36,33 +33,40 @@ extensions: []
36
33
  extra_rdoc_files: []
37
34
  files:
38
35
  - .gitignore
39
- - MIT_LICENCE
36
+ - .rspec
37
+ - Gemfile
38
+ - Gemfile.lock
39
+ - MIT_LICENSE
40
40
  - README.md
41
41
  - fragment.gemspec
42
42
  - lib/fragment.rb
43
+ - lib/fragment/version.rb
44
+ - spec/fragment_spec.rb
45
+ - spec/spec_helper.rb
43
46
  - test/spec_fragment.rb
44
47
  homepage: https://github.com/mig-hub/fragment
45
- licenses: []
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
46
51
  post_install_message:
47
52
  rdoc_options: []
48
53
  require_paths:
49
54
  - ./lib
50
55
  required_ruby_version: !ruby/object:Gem::Requirement
51
- none: false
52
56
  requirements:
53
- - - ! '>='
57
+ - - '>='
54
58
  - !ruby/object:Gem::Version
55
59
  version: '0'
56
60
  required_rubygems_version: !ruby/object:Gem::Requirement
57
- none: false
58
61
  requirements:
59
- - - ! '>='
62
+ - - '>='
60
63
  - !ruby/object:Gem::Version
61
64
  version: '0'
62
65
  requirements: []
63
66
  rubyforge_project:
64
- rubygems_version: 1.8.23
67
+ rubygems_version: 2.0.14
65
68
  signing_key:
66
- specification_version: 3
69
+ specification_version: 4
67
70
  summary: Lightweight HTML builder
68
- test_files: []
71
+ test_files:
72
+ - spec/fragment_spec.rb