trenni-formatters 0.5.3 → 1.0.0

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: 3010072052341464ed8f33309fd8b9b59b827c8b
4
- data.tar.gz: 4d4e10b75652a479706624c450ef5905c67507d0
3
+ metadata.gz: 38446eb1ee4817cddda1a893f8ac201d994102cd
4
+ data.tar.gz: 0a5bdcf731d0aab78c21cb8ec379c385aff4c561
5
5
  SHA512:
6
- metadata.gz: dc49678aecb21aef566d29fd8c4e1a8dbb734d54160dc76b6c39ef28b1dfe581000de5723080f840374bceca8f5dfa87471e0707213004b00df038bc52e2cce1
7
- data.tar.gz: e6a51446102c792d38f64315ffbd64bdf55ac091048fd3a2bf3a4ac3bc3438f6e4b4ffea49b18cd3c3cb34dc27425dddfa7069d816555d50ddaad99f93ea9aa6
6
+ metadata.gz: 5c764c5ed7624b752f6fa3c1171db00f945bb1c449bc115cc06cdd9fe849c4bee7d0124e9ff291fe779e3944d75b4449d7e19b093454cbfb49b5236a8760ceb5
7
+ data.tar.gz: 693f5abca9f92b155338aa2a7d2bbd0a1f9c61cfec40b5d910e5f226e2333cf5a885524075b9bffb8d42c7a8fd3c3bb421b7755dff4418e20e22eea2d835f278
data/README.md CHANGED
@@ -11,19 +11,23 @@ formatting needs.
11
11
  [![Code Climate](https://codeclimate.com/github/ioquatix/trenni-formatters.png)](https://codeclimate.com/github/ioquatix/trenni-formatters)
12
12
  [![Coverage Status](https://coveralls.io/repos/ioquatix/trenni-formatters/badge.svg)](https://coveralls.io/r/ioquatix/trenni-formatters)
13
13
 
14
+ ## Motivation
15
+
16
+ `Trenni::Formatters` was a library extracted from [Financier](https://github.com/ioquatix/financier) which is a CouchDB backed invoicing system, itself, derived from an old Rails app. I was a bit envious of `form_for` in terms of the ease of generating forms, but found that it wasn't very extendable. I also found myself generating code to format model data as rich HTML. `Trenni::Formatters` attempts to be an easily extendable formatting module which can generate rich text, links and HTML.
17
+
14
18
  ## Installation
15
19
 
16
20
  Add this line to your application's Gemfile:
17
21
 
18
- gem 'trenni-formatters'
22
+ gem 'trenni-formatters'
19
23
 
20
24
  And then execute:
21
25
 
22
- $ bundle
26
+ $ bundle
23
27
 
24
28
  Or install it yourself as:
25
29
 
26
- $ gem install trenni-formatters
30
+ $ gem install trenni-formatters
27
31
 
28
32
  ## Usage
29
33
 
@@ -36,9 +40,9 @@ a mapping corresponding to the objects type:
36
40
  "String: #{value}"
37
41
  end
38
42
 
39
- assert_equal "String: foobar", formatter.format("foobar")
43
+ expect(formatter.format("foobar")).to be == "String: foobar"
40
44
 
41
- For more examples please see `test/`.
45
+ For more examples please see `spec/`.
42
46
 
43
47
  ## Contributing
44
48
 
@@ -0,0 +1,34 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'sanitize'
22
+ require 'kramdown'
23
+
24
+ module Trenni::Formatters::Format
25
+ module Markdown
26
+ def markdown(text)
27
+ config = Sanitize::Config::BASIC.dup
28
+
29
+ config[:elements] += ['h1', 'h2', 'h3']
30
+
31
+ Sanitize.clean(Kramdown::Document.new(text).to_html, config)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'trenni/strings'
22
+ require 'mapping/model'
23
+
24
+ module Trenni::Formatters::Format
25
+ module Text
26
+ def truncated_text(content, options = {}, &block)
27
+ if content
28
+ length = options.fetch(:length, 30)
29
+
30
+ content = self.class.truncate_text(content, length, options)
31
+
32
+ return self.format(content)
33
+ end
34
+ end
35
+
36
+ def self.truncate_text(text, truncate_at, options = {})
37
+ return text.dup unless text.length > truncate_at
38
+
39
+ options[:omission] ||= '...'
40
+ length_with_room_for_omission = truncate_at - options[:omission].length
41
+ stop = if options[:separator]
42
+ text.rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
43
+ else
44
+ length_with_room_for_omission
45
+ end
46
+
47
+ "#{text[0...stop]}#{options[:omission]}"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,39 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'trenni/strings'
22
+ require 'mapping/model'
23
+
24
+ module Trenni::Formatters::Format
25
+ module Time
26
+ def included(base)
27
+ base.map(Time) do |object, options|
28
+ # Ensure we display the time in localtime, and show the year if it is different:
29
+ if object.localtime.year != Time.now.year
30
+ object.localtime.strftime("%B %-d, %-l:%M%P, %Y")
31
+ else
32
+ object.localtime.strftime("%B %-d, %-l:%M%P")
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -19,24 +19,30 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  require 'trenni/strings'
22
+ require 'mapping/model'
22
23
 
23
24
  module Trenni
24
25
  module Formatters
25
- class Formatter
26
+ class Formatter < Mapping::Model
26
27
  def initialize(options = {})
27
28
  @options = options
28
- @formatters = {}
29
+ end
30
+
31
+ def format_unspecified(object, options)
32
+ if object
33
+ Strings::to_html(object.to_s)
34
+ else
35
+ options[:blank] || ""
36
+ end
29
37
  end
30
38
 
31
39
  def format(object, options = {})
32
- if formatter = @formatters[object.class]
33
- formatter.call(object, options)
40
+ method_name = self.method_for_mapping(object)
41
+
42
+ if self.respond_to?(method_name)
43
+ self.send(method_name, object, options)
34
44
  else
35
- if object
36
- Strings::to_html(object.to_s)
37
- else
38
- options[:blank] || ""
39
- end
45
+ format_unspecified(object, options)
40
46
  end
41
47
  end
42
48
 
@@ -45,10 +51,6 @@ module Trenni
45
51
  def [] key
46
52
  @options[key]
47
53
  end
48
-
49
- def for(klass, &block)
50
- @formatters[klass] = block
51
- end
52
54
  end
53
55
  end
54
56
  end
@@ -34,8 +34,14 @@ module Trenni
34
34
  options = @options.merge(options)
35
35
 
36
36
  Builder.fragment do |builder|
37
- builder.inline(:dt) { builder.text title_for(options) }
38
-
37
+ builder.inline(:dt) do
38
+ builder.text title_for(options)
39
+
40
+ if details = details_for(options)
41
+ builder.inline(:small) { builder.text details }
42
+ end
43
+ end
44
+
39
45
  builder.inline(:dd) do
40
46
  builder.tag :input, input_attributes_for(options)
41
47
  end
@@ -50,7 +56,9 @@ module Trenni
50
56
  builder.inline(:dt) { builder.text title_for(options) }
51
57
 
52
58
  builder.inline(:dd) do
53
- builder.tag :output, output_attributes_for(options)
59
+ builder.inline :output, output_attributes_for(options) do
60
+ builder.text value_for(options)
61
+ end
54
62
  end
55
63
  end
56
64
  end
@@ -60,7 +68,13 @@ module Trenni
60
68
  options = @options.merge(options)
61
69
 
62
70
  Builder.fragment do |builder|
63
- builder.inline(:dt) { builder.text title_for(options) }
71
+ builder.tag(:dt) do
72
+ builder.text title_for(options)
73
+
74
+ if details = details_for(options)
75
+ builder.inline(:small) { builder.text details }
76
+ end
77
+ end
64
78
 
65
79
  builder.inline(:dd) do
66
80
  builder.tag :textarea, textarea_attributes_for(options) do
@@ -77,8 +91,11 @@ module Trenni
77
91
  Builder.fragment do |builder|
78
92
  builder.tag(:dd) do
79
93
  builder.tag :input, :type => :hidden, :name => name_for(options), :value => 'false'
80
- builder.tag :input, checkbox_attributes_for(options)
81
- builder.text " " + title_for(options)
94
+ builder.inline(:label) do
95
+ builder.tag :input, checkbox_attributes_for(options)
96
+ # We would like a little bit of whitespace between the checkbox and the title.
97
+ builder.text " " + title_for(options)
98
+ end
82
99
  end
83
100
  end
84
101
  end
@@ -86,13 +103,8 @@ module Trenni
86
103
  # A submission button
87
104
  def submit(options = {})
88
105
  options = @options.merge(options)
106
+ options[:title] ||= submit_title_for(options)
89
107
 
90
- if title = title_for(options)
91
- options[:title] = title
92
- else
93
- options[:title] ||= new_record? ? 'Create' : 'Update'
94
- end
95
-
96
108
  Builder.fragment do |builder|
97
109
  builder.tag :input, submit_attributes_for(options)
98
110
  end
@@ -103,7 +115,14 @@ module Trenni
103
115
  buffer = Trenni::Template.buffer(block.binding)
104
116
 
105
117
  buffer << Builder.fragment do |builder|
106
- builder.inline(:dt) { builder.text title_for(options) }
118
+ builder.inline(:dt) do
119
+ builder.text title_for(options)
120
+
121
+ if details = details_for(options)
122
+ builder.inline(:small) { builder.text details }
123
+ end
124
+ end
125
+
107
126
  builder.tag(:dd) do
108
127
  klass.call(self, options, builder, &block)
109
128
  end
@@ -37,10 +37,15 @@ module Trenni
37
37
  return !object.saved?
38
38
  end
39
39
  end
40
-
40
+
41
+ # Any additional details relating to a field (e.g. explanation text)
42
+ def details_for(options)
43
+ options[:details]
44
+ end
45
+
41
46
  # The name of the field, used for the name attribute of an input.
42
47
  def name_for(options)
43
- (options[:name] || options[:field]).to_s
48
+ options[:name] || options[:field]
44
49
  end
45
50
 
46
51
  def field_for(options)
@@ -49,17 +54,21 @@ module Trenni
49
54
 
50
55
  # A title is a text string that will be displayed next to or on top of the control to describe it or its value:
51
56
  def title_for(options)
52
- title = options[:title]
53
- return Strings::to_html(title) if title
54
-
55
- field_name = field_for(options)
57
+ if title = options[:title]
58
+ return title
59
+ end
56
60
 
57
- # Remove postfix "_id" or "_ids":
58
- return Strings::to_title(field_name.to_s.sub(/_ids?/, '')) if field_name
61
+ # Generate a title from a field name:
62
+ if field_name = field_for(options)
63
+ # Remove postfix "_id" or "_ids":
64
+ return Strings::to_title(field_name.to_s.sub(/_ids?/, ''))
65
+ end
59
66
  end
60
67
 
61
68
  def object_value_for(options)
62
- options[:object].send(field_for(options)) if options[:object]
69
+ if object = options[:object] and field = field_for(options)
70
+ object.send(field)
71
+ end
63
72
  end
64
73
 
65
74
  def raw_value_for(options)
@@ -71,7 +80,9 @@ module Trenni
71
80
 
72
81
  # The value of the field.
73
82
  def value_for(options)
74
- self.format(raw_value_for(options), options)
83
+ if value = raw_value_for(options)
84
+ self.format(value, options)
85
+ end
75
86
  end
76
87
 
77
88
  def pattern_for(options)
@@ -157,7 +168,11 @@ module Trenni
157
168
  :value => title_for(options),
158
169
  }
159
170
  end
160
-
171
+
172
+ def submit_title_for(options)
173
+ title_for(options) || (new_record? ? 'Create' : 'Update')
174
+ end
175
+
161
176
  def hidden_attributes_for(options)
162
177
  return {
163
178
  :type => options[:type] || 'hidden',
@@ -176,6 +191,38 @@ module Trenni
176
191
  builder.tag :input, hidden_attributes_for(options)
177
192
  end
178
193
  end
194
+
195
+ def button_attributes_for(options)
196
+ return {
197
+ :type => options[:type] || 'submit',
198
+ :name => name_for(options),
199
+ :id => options[:id],
200
+ :class => options[:class],
201
+ :disabled => options[:disabled],
202
+ :value => value_for(options),
203
+ }
204
+ end
205
+
206
+ def button_title_for(options)
207
+ type = options.fetch(:type, 'submit').to_sym
208
+
209
+ if type == :submit
210
+ submit_title_for(options)
211
+ else
212
+ title_for(options) || Strings::to_title(type.to_s)
213
+ end
214
+ end
215
+
216
+ # A hidden field.
217
+ def button(options = {})
218
+ options = @options.merge(options)
219
+
220
+ Builder.fragment do |builder|
221
+ builder.inline :button, button_attributes_for(options) do
222
+ builder.text button_title_for(options)
223
+ end
224
+ end
225
+ end
179
226
  end
180
227
  end
181
228
  end
@@ -42,13 +42,13 @@ module Trenni
42
42
  end
43
43
 
44
44
  def name_for(options)
45
- name = @formatter.name_for(options)
46
-
47
- if options[:multiple]
48
- name += '[]'
45
+ if name = @formatter.name_for(options)
46
+ if options[:multiple]
47
+ name = "#{name}[]"
48
+ end
49
+
50
+ return name
49
51
  end
50
-
51
- return name
52
52
  end
53
53
 
54
54
  def value_for(options)
@@ -85,7 +85,7 @@ module Trenni
85
85
  end
86
86
 
87
87
  def group(options = {}, &block)
88
- Builder.fragment do |builder|
88
+ Builder.fragment(@builder) do |builder|
89
89
  builder.tag :optgroup, group_attributes_for(options) do
90
90
  if options[:optional]
91
91
  item(:title => '', :value => '', :builder => builder)
@@ -24,7 +24,7 @@ module Trenni
24
24
  module Formatters
25
25
  module HTML
26
26
  # Table based select boxes using per-row checkboxes.
27
- class TableSelect
27
+ class RadioSelect
28
28
  def self.call(formatter, options, builder, &block)
29
29
  instance = self.new(formatter, options, builder)
30
30
 
@@ -97,7 +97,6 @@ module Trenni
97
97
  end
98
98
  end
99
99
  end
100
-
101
100
  end
102
101
  end
103
102
  end
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Trenni
22
22
  module Formatters
23
- VERSION = "0.5.3"
23
+ VERSION = "1.0.0"
24
24
  end
25
25
  end
@@ -20,8 +20,6 @@
20
20
 
21
21
  require 'trenni/formatters'
22
22
  require 'trenni/formatters/html/definition_list_form'
23
- require 'trenni/formatters/html/option_select'
24
- require 'trenni/formatters/html/table_select'
25
23
 
26
24
  module Trenni::Formatters::FormFormatterSpec
27
25
  class FormFormatter < Trenni::Formatters::Formatter
@@ -32,8 +30,8 @@ module Trenni::Formatters::FormFormatterSpec
32
30
  let(:formatter) {FormFormatter.new(:object => double(:bar => 10))}
33
31
 
34
32
  it "should generate form" do
35
- output_tag = formatter.input(:field => :bar)
36
- expect(output_tag).to be == %Q{<dt>Bar</dt>\n<dd><input name="bar" value="10"/></dd>}
33
+ result = formatter.input(:field => :bar)
34
+ expect(result).to be == %Q{<dt>Bar</dt>\n<dd><input name="bar" value="10"/></dd>}
37
35
  end
38
36
 
39
37
  it "should have default value" do
@@ -42,8 +40,8 @@ module Trenni::Formatters::FormFormatterSpec
42
40
  end
43
41
 
44
42
  it "should have a different title" do
45
- output_tag = formatter.input(:field => :bar, :title => "Title")
46
- expect(output_tag).to be == %Q{<dt>Title</dt>\n<dd><input name="bar" value="10"/></dd>}
43
+ result = formatter.input(:field => :bar, :title => "Title")
44
+ expect(result).to be == %Q{<dt>Title</dt>\n<dd><input name="bar" value="10"/></dd>}
47
45
  end
48
46
  end
49
47
 
@@ -57,8 +55,8 @@ module Trenni::Formatters::FormFormatterSpec
57
55
  expect(attributes[:max]).to be == 20
58
56
  expect(attributes[:step]).to be == 2
59
57
 
60
- output_tag = formatter.input(:field => :bar, :min => 10)
61
- expect(output_tag).to be == %Q{<dt>Bar</dt>\n<dd><input name="bar" value="10" min="10"/></dd>}
58
+ result = formatter.input(:field => :bar, :min => 10)
59
+ expect(result).to be == %Q{<dt>Bar</dt>\n<dd><input name="bar" value="10" min="10"/></dd>}
62
60
  end
63
61
 
64
62
  it "should not specify required, readonly or disabled" do
@@ -79,16 +77,87 @@ module Trenni::Formatters::FormFormatterSpec
79
77
  attributes = formatter.checkbox_attributes_for(:value => true)
80
78
  expect(attributes[:checked]).to be true
81
79
 
82
- output_tag = formatter.checkbox(:field => :bob)
83
- expect(output_tag).to be == %Q{<dd>\n\t<input type="hidden" name="bob" value="false"/>\t<input type="checkbox" name="bob" value="true" checked/>\tBob\n</dd>}
80
+ result = formatter.checkbox(:field => :bob)
81
+ expect(result).to be == %Q{<dd>\n\t<input type="hidden" name="bob" value="false"/>\n\t<label><input type="checkbox" name="bob" value="true" checked/> Bob</label>\n</dd>}
84
82
  end
85
83
 
86
84
  it "should generate unchecked checkbox" do
87
85
  attributes = formatter.checkbox_attributes_for(:value => false)
88
86
  expect(attributes[:checked]).to be nil
89
87
 
90
- output_tag = formatter.checkbox(:field => :dole)
91
- expect(output_tag).to be == %Q{<dd>\n\t<input type="hidden" name="dole" value="false"/>\t<input type="checkbox" name="dole" value="true"/>\tDole\n</dd>}
88
+ result = formatter.checkbox(:field => :dole)
89
+ expect(result).to be == %Q{<dd>\n\t<input type="hidden" name="dole" value="false"/>\n\t<label><input type="checkbox" name="dole" value="true"/> Dole</label>\n</dd>}
90
+ end
91
+ end
92
+
93
+ describe '<input type="hidden">' do
94
+ let(:formatter) {FormFormatter.new(:object => double(age: 20))}
95
+
96
+ it "should generate hidden field" do
97
+ result = formatter.hidden(:field => :age)
98
+ expect(result).to be == %Q{<input type="hidden" name="age" value="20"/>}
99
+ end
100
+
101
+ it "should escape characters correctly" do
102
+ result = formatter.submit
103
+ expect(result).to be == %Q{<input type="submit" value="Update"/>}
104
+ end
105
+
106
+ it "can have custom title" do
107
+ result = formatter.submit(title: 'Alice')
108
+ expect(result).to be == %Q{<input type="submit" value="Alice"/>}
109
+ end
110
+ end
111
+
112
+ describe '<input type="submit">' do
113
+ let(:new_record_formatter) {FormFormatter.new(:object => double(new_record?: true))}
114
+ let(:formatter) {FormFormatter.new(:object => double(new_record?: false))}
115
+
116
+ it "should have correct title for new_record?" do
117
+ result = new_record_formatter.submit
118
+ expect(result).to be == %Q{<input type="submit" value="Create"/>}
119
+ end
120
+
121
+ it "should escape characters correctly" do
122
+ result = formatter.submit
123
+ expect(result).to be == %Q{<input type="submit" value="Update"/>}
124
+ end
125
+
126
+ it "can have custom title" do
127
+ result = formatter.submit(title: 'Alice')
128
+ expect(result).to be == %Q{<input type="submit" value="Alice"/>}
129
+ end
130
+ end
131
+
132
+ describe "<textarea>" do
133
+ let(:formatter) {FormFormatter.new(:object => double(details: "foo<bar>"))}
134
+
135
+ it "should escape characters correctly" do
136
+ result = formatter.textarea(:field => :details)
137
+ expect(result).to be == %Q{<dt>\n\tDetails\n</dt>\n<dd><textarea name=\"details\">foo&lt;bar&gt;</textarea></dd>}
138
+ end
139
+ end
140
+
141
+ describe "<output>" do
142
+ let(:formatter) {FormFormatter.new(:object => double(bar: 10, bob: true, dole: false))}
143
+
144
+ it "should show output value" do
145
+ result = formatter.output(:field => :bar)
146
+ expect(result).to be == %Q{<dt>Bar</dt>\n<dd><output name=\"bar\">10</output></dd>}
147
+ end
148
+
149
+ it "should show output value" do
150
+ result = formatter.output(:name => :total)
151
+ expect(result).to be == %Q{<dt></dt>\n<dd><output name=\"total\"></output></dd>}
152
+ end
153
+ end
154
+
155
+ describe "<button>" do
156
+ let(:formatter) {FormFormatter.new}
157
+
158
+ it "should generate reset button" do
159
+ result = formatter.button(:type => :reset)
160
+ expect(result).to be == %Q{<button type="reset">Reset</button>}
92
161
  end
93
162
  end
94
163
  end
@@ -21,25 +21,37 @@
21
21
  require 'trenni/formatters'
22
22
 
23
23
  module Trenni::FormattersSpec
24
- describe Trenni::Formatters do
25
- before do
24
+ class TestFormatter < Trenni::Formatters::Formatter
25
+ def initialize(*)
26
26
  @count = 0
27
- @formatter = Trenni::Formatters::Formatter.new
27
+
28
+ super
29
+ end
28
30
 
29
- @formatter.for(String) do |value, options|
30
- @count += 1
31
- "String: #{value}"
32
- end
31
+ attr :count
32
+
33
+ map(String) do |value, options|
34
+ @count += 1
35
+
36
+ "String: #{value}"
33
37
  end
38
+ end
39
+
40
+ describe Trenni::Formatters do
41
+ let(:test_formatter) {TestFormatter.new(foo: :bar)}
34
42
 
35
43
  it "should format string" do
36
- expect(@formatter.format("foobar")).to be == "String: foobar"
37
- expect(@count).to be == 1
44
+ expect(test_formatter.format("foobar")).to be == "String: foobar"
45
+ expect(test_formatter.count).to be == 1
38
46
  end
39
47
 
40
48
  it "should format numbers" do
41
- expect(@formatter.format(10)).to be == "10"
42
- expect(@count).to be == 0
49
+ expect(test_formatter.format(10)).to be == "10"
50
+ expect(test_formatter.count).to be == 0
51
+ end
52
+
53
+ it "has options" do
54
+ expect(test_formatter[:foo]).to be == :bar
43
55
  end
44
56
  end
45
57
  end
@@ -19,6 +19,7 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  require 'trenni/formatters'
22
+ require 'trenni/formatters/html/option_select'
22
23
 
23
24
  module Trenni::Formatters::HTML::OptionSelectSpec
24
25
  class FormFormatter < Trenni::Formatters::Formatter
@@ -31,10 +32,9 @@ module Trenni::Formatters::HTML::OptionSelectSpec
31
32
 
32
33
  describe Trenni::Formatters::HTML::OptionSelect do
33
34
  let(:formatter) {FormFormatter.new(:object => double(:bar => 10))}
35
+ let(:_out) {Array.new}
34
36
 
35
- it "should format items" do
36
- _out = []
37
-
37
+ it "should list items" do
38
38
  formatter.select :field => :bar do |select|
39
39
  _out << select.item(:title => "A", :value => 0)
40
40
  _out << select.item(:title => "B", :value => 10)
@@ -42,5 +42,45 @@ module Trenni::Formatters::HTML::OptionSelectSpec
42
42
 
43
43
  expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<option value=\"0\">A</option><option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
44
44
  end
45
+
46
+ it "should list items for multiple selection" do
47
+ formatter.select :field => :bar, multiple: true do |select|
48
+ _out << select.item(:title => "A", :value => 0)
49
+ _out << select.item(:title => "B", :value => 10)
50
+ end
51
+
52
+ expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar[]\" multiple>\n\t\t<option value=\"0\">A</option><option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
53
+ end
54
+
55
+ it "should add optional item" do
56
+ formatter.select :field => :bar, optional: true do |select|
57
+ _out << select.item(:title => "A", :value => 0)
58
+ _out << select.item(:title => "B", :value => 10)
59
+ end
60
+
61
+ expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<option value=\"\"></option>\t\t<option value=\"0\">A</option><option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
62
+ end
63
+
64
+ it "should add optional item in group" do
65
+ formatter.select :field => :bar do |select|
66
+ select.group(title: 'group', optional: true) do
67
+ _out << select.item(:title => "A", :value => 0)
68
+ end
69
+ _out << select.item(:title => "B", :value => 10)
70
+ end
71
+
72
+ expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<optgroup label=\"group\">\n\t\t\t<option value=\"\"></option>\t\t\t<option value=\"0\">A</option>\n\t\t</optgroup>\t\t<option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
73
+ end
74
+
75
+ it "should add a group" do
76
+ formatter.select :field => :bar do |select|
77
+ select.group(title: 'group') do
78
+ _out << select.item(:title => "A", :value => 0)
79
+ end
80
+ _out << select.item(:title => "B", :value => 10)
81
+ end
82
+
83
+ expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<optgroup label=\"group\">\n\t\t\t<option value=\"0\">A</option>\n\t\t</optgroup>\t\t<option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
84
+ end
45
85
  end
46
86
  end
@@ -0,0 +1,46 @@
1
+ # Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'trenni/formatters'
22
+ require 'trenni/formatters/html/radio_select'
23
+
24
+ module Trenni::Formatters::HTML::RadioSelectSpec
25
+ class FormFormatter < Trenni::Formatters::Formatter
26
+ include Trenni::Formatters::HTML::DefinitionListForm
27
+
28
+ def select(options = {}, &block)
29
+ element(Trenni::Formatters::HTML::RadioSelect, options, &block)
30
+ end
31
+ end
32
+
33
+ describe Trenni::Formatters::HTML::RadioSelect do
34
+ let(:formatter) {FormFormatter.new(:object => double(:bar => 10))}
35
+ let(:_out) {Array.new}
36
+
37
+ it "should list items" do
38
+ formatter.select :field => :bar do |select|
39
+ _out << select.item(:title => "A", :value => 0)
40
+ _out << select.item(:title => "B", :value => 10)
41
+ end
42
+
43
+ expect(_out.join).to be == %Q{<dt>Bar</dt>\n<dd>\n\t<table>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td class="handle"><input type="radio" name="bar" value="0"/></td>\n\t\t\t\t<td class="item">A</td>\n\t\t\t</tr><tr>\n\t\t\t\t<td class="handle"><input type="radio" name="bar" value="10"/></td>\n\t\t\t\t<td class="item">B</td>\n\t\t\t</tr>\n\t\t</tbody>\n\t</table>\n</dd>}
44
+ end
45
+ end
46
+ end
@@ -24,7 +24,9 @@ Gem::Specification.new do |spec|
24
24
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
25
  spec.require_paths = ["lib"]
26
26
 
27
- spec.add_dependency "trenni", "~> 1.4.0"
27
+ spec.add_dependency "trenni", "~> 1.5.0"
28
+
29
+ spec.add_dependency "mapping", "~> 1.0.0"
28
30
 
29
31
  spec.add_development_dependency "bundler", "~> 1.3"
30
32
  spec.add_development_dependency "rspec", "~> 3.4.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trenni-formatters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-10 00:00:00.000000000 Z
11
+ date: 2016-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trenni
@@ -16,14 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.4.0
19
+ version: 1.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.4.0
26
+ version: 1.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: mapping
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -84,15 +98,19 @@ files:
84
98
  - README.md
85
99
  - Rakefile
86
100
  - lib/trenni/formatters.rb
101
+ - lib/trenni/formatters/format/markdown.rb
102
+ - lib/trenni/formatters/format/text.rb
103
+ - lib/trenni/formatters/format/time.rb
87
104
  - lib/trenni/formatters/formatter.rb
88
105
  - lib/trenni/formatters/html/definition_list_form.rb
89
106
  - lib/trenni/formatters/html/form_formatter.rb
90
107
  - lib/trenni/formatters/html/option_select.rb
91
- - lib/trenni/formatters/html/table_select.rb
108
+ - lib/trenni/formatters/html/radio_select.rb
92
109
  - lib/trenni/formatters/version.rb
93
110
  - spec/trenni/formatters/form_formatter_spec.rb
94
111
  - spec/trenni/formatters/formatters_spec.rb
95
112
  - spec/trenni/formatters/html/option_select_spec.rb
113
+ - spec/trenni/formatters/html/radio_select_spec.rb
96
114
  - trenni-formatters.gemspec
97
115
  homepage: https://github.com/ioquatix/trenni-formatters
98
116
  licenses: []
@@ -113,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
131
  version: '0'
114
132
  requirements: []
115
133
  rubyforge_project:
116
- rubygems_version: 2.4.6
134
+ rubygems_version: 2.5.2
117
135
  signing_key:
118
136
  specification_version: 4
119
137
  summary: Formatters for Trenni, to assist with typical views and form based interfaces.
@@ -121,3 +139,4 @@ test_files:
121
139
  - spec/trenni/formatters/form_formatter_spec.rb
122
140
  - spec/trenni/formatters/formatters_spec.rb
123
141
  - spec/trenni/formatters/html/option_select_spec.rb
142
+ - spec/trenni/formatters/html/radio_select_spec.rb