nm 0.5.4 → 0.6.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 +7 -7
- data/.gitignore +1 -0
- data/.l.yml +9 -0
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -0
- data/.t.yml +6 -0
- data/Gemfile +6 -2
- data/README.md +53 -51
- data/lib/nm.rb +12 -2
- data/lib/nm/context.rb +55 -0
- data/lib/nm/ext.rb +11 -18
- data/lib/nm/render.rb +12 -0
- data/lib/nm/source.rb +60 -47
- data/lib/nm/template_behaviors.rb +96 -0
- data/lib/nm/version.rb +3 -1
- data/nm.gemspec +12 -6
- data/test/helper.rb +6 -13
- data/test/support/factory.rb +3 -2
- data/test/support/templates/_list.nm +2 -0
- data/test/support/templates/_locals.nm +4 -2
- data/test/support/templates/_obj.nm +5 -3
- data/test/support/templates/aliases.nm +8 -3
- data/test/support/templates/list.nm +2 -0
- data/test/support/templates/locals.nm +4 -2
- data/test/support/templates/locals_alt.data.inem +2 -2
- data/test/support/templates/obj.nm +6 -4
- data/test/system/.keep +0 -0
- data/test/unit/context_tests.rb +51 -0
- data/test/unit/ext_tests.rb +27 -42
- data/test/unit/nm_tests.rb +20 -0
- data/test/unit/render_tests.rb +28 -0
- data/test/unit/source_tests.rb +89 -106
- data/test/unit/template_behaviors_tests.rb +259 -0
- metadata +82 -43
- data/lib/nm/template.rb +0 -103
- data/test/unit/template_tests.rb +0 -357
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "assert"
|
4
|
+
require "nm/render"
|
5
|
+
|
6
|
+
class Nm::Render
|
7
|
+
class UnitTests < Assert::Context
|
8
|
+
desc "Nm::Render"
|
9
|
+
subject{ unit_class }
|
10
|
+
|
11
|
+
let(:unit_class){ Nm::Render }
|
12
|
+
end
|
13
|
+
|
14
|
+
class InitTests < UnitTests
|
15
|
+
desc "when init"
|
16
|
+
subject{ unit_class.new(dstack: dstack, locals: locals) }
|
17
|
+
|
18
|
+
let(:dstack){ [] }
|
19
|
+
let(:locals){ {} }
|
20
|
+
|
21
|
+
should have_readers :dstack, :locals
|
22
|
+
|
23
|
+
should "know its attributes" do
|
24
|
+
assert_that(subject.dstack).equals(dstack)
|
25
|
+
assert_that(subject.locals).equals(locals)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/unit/source_tests.rb
CHANGED
@@ -1,155 +1,138 @@
|
|
1
|
-
|
2
|
-
require 'nm/source'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
require
|
3
|
+
require "assert"
|
4
|
+
require "nm/source"
|
5
5
|
|
6
|
-
|
6
|
+
require "nm/context"
|
7
7
|
|
8
|
+
class Nm::Source
|
8
9
|
class UnitTests < Assert::Context
|
9
10
|
desc "Nm::Source"
|
10
|
-
|
11
|
-
@source_class = Nm::Source
|
12
|
-
end
|
13
|
-
subject{ @source_class }
|
11
|
+
subject{ unit_class }
|
14
12
|
|
13
|
+
let(:unit_class){ Nm::Source }
|
15
14
|
end
|
16
15
|
|
17
16
|
class InitTests < UnitTests
|
18
17
|
desc "when init"
|
19
|
-
|
20
|
-
@root = Factory.template_root
|
21
|
-
@source = @source_class.new(@root)
|
22
|
-
end
|
23
|
-
subject{ @source }
|
18
|
+
subject{ source }
|
24
19
|
|
25
|
-
|
26
|
-
|
20
|
+
let(:root){ Factory.template_root }
|
21
|
+
let(:source){ unit_class.new(root) }
|
27
22
|
|
28
|
-
should
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
should "know its extension for looking up source files" do
|
33
|
-
assert_nil subject.ext
|
23
|
+
should have_readers :root, :extension, :cache, :locals
|
24
|
+
should have_imeths :data, :render, :file_path!
|
34
25
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
should "know its attributes" do
|
27
|
+
assert_that(subject.root.to_s).equals(root)
|
28
|
+
assert_that(subject.extension).is_nil
|
29
|
+
assert_that(subject.cache).is_a(unit_class::NullCache)
|
30
|
+
assert_that(subject.locals).equals({})
|
39
31
|
|
40
|
-
|
41
|
-
|
32
|
+
extension = Factory.string
|
33
|
+
locals = { key: "value" }
|
34
|
+
source =
|
35
|
+
unit_class.new(root, extension: extension, cache: true, locals: locals)
|
36
|
+
assert_that(source.extension).equals(".#{extension}")
|
37
|
+
assert_that(source.cache).is_a(Hash)
|
38
|
+
assert_that(source.locals).equals(locals)
|
42
39
|
end
|
43
|
-
|
44
|
-
should "cache templates if the :cache opt is `true`" do
|
45
|
-
source = @source_class.new(@root, :cache => true)
|
46
|
-
assert_kind_of Hash, source.cache
|
47
|
-
end
|
48
|
-
|
49
|
-
should "know its template class" do
|
50
|
-
assert_true subject.template_class < Nm::Template
|
51
|
-
end
|
52
|
-
|
53
|
-
should "optionally take and apply default locals to its template class" do
|
54
|
-
local_name, local_val = [Factory.string, Factory.string]
|
55
|
-
source = @source_class.new(@root, :locals => {
|
56
|
-
local_name => local_val
|
57
|
-
})
|
58
|
-
template = source.template_class.new
|
59
|
-
|
60
|
-
assert_responds_to local_name, template
|
61
|
-
assert_equal local_val, template.send(local_name)
|
62
|
-
end
|
63
|
-
|
64
40
|
end
|
65
41
|
|
66
42
|
class DataTests < InitTests
|
67
43
|
desc "`data` method"
|
68
|
-
|
69
|
-
|
70
|
-
end
|
44
|
+
|
45
|
+
let(:file_path){ Factory.template_file("obj.nm") }
|
71
46
|
|
72
47
|
should "read the contents of a given file path" do
|
73
|
-
|
74
|
-
assert_equal exp, subject.data(@file_path)
|
48
|
+
assert_that(subject.data(file_path)).equals(File.read(file_path))
|
75
49
|
end
|
76
50
|
|
77
51
|
should "not cache template source by default" do
|
78
|
-
|
52
|
+
assert_that(subject.cache.keys).equals([])
|
79
53
|
end
|
80
54
|
|
81
55
|
should "cache template source by file path if enabled" do
|
82
|
-
source =
|
56
|
+
source = unit_class.new(root, cache: true)
|
83
57
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
58
|
+
file_data = File.read(file_path)
|
59
|
+
assert_that(source.data(file_path)).equals(file_data)
|
60
|
+
assert_that(source.cache.keys).equals([file_path])
|
61
|
+
assert_that(source.cache[file_path]).equals(file_data)
|
88
62
|
end
|
89
|
-
|
90
63
|
end
|
91
64
|
|
92
65
|
class RenderTests < InitTests
|
93
66
|
desc "`render` method"
|
94
|
-
setup do
|
95
|
-
@template_name = ['locals', 'locals_alt'].sample
|
96
|
-
@file_locals = { 'key' => 'a-value' }
|
97
|
-
@file_path = Dir.glob("#{Factory.template_file(@template_name)}*").first
|
98
|
-
end
|
99
|
-
|
100
|
-
should "render a template for the given template name and return its data" do
|
101
|
-
exp = Nm::Template.new(subject, @file_path, @file_locals).__data__
|
102
|
-
assert_equal exp, subject.render(@template_name, @file_locals)
|
103
|
-
end
|
104
|
-
|
105
|
-
should "alias `render` as `partial`" do
|
106
|
-
exp = subject.render(@template_name, @file_locals)
|
107
|
-
assert_equal exp, subject.partial(@template_name, @file_locals)
|
108
|
-
end
|
109
|
-
|
110
|
-
should "only render templates with the matching ext if one is specified" do
|
111
|
-
source = @source_class.new(@root, :ext => 'nm')
|
112
|
-
file_path = Factory.template_file('locals.nm')
|
113
|
-
exp = Nm::Template.new(source, file_path, @file_locals).__data__
|
114
|
-
['locals', 'locals.nm'].each do |name|
|
115
|
-
assert_equal exp, source.render(name, @file_locals)
|
116
|
-
end
|
117
67
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
68
|
+
let(:custom_context){ Class.new.new }
|
69
|
+
let(:template_name){ ["locals", "locals_alt"].sample }
|
70
|
+
let(:file_path) do
|
71
|
+
Dir.glob("#{Factory.template_file(template_name)}*").first
|
72
|
+
end
|
73
|
+
let(:file_locals){ { "key" => "a-value" } }
|
74
|
+
|
75
|
+
should "render a template for the given name and return its data" do
|
76
|
+
assert_that(subject.render(template_name, locals: file_locals))
|
77
|
+
.equals(
|
78
|
+
Nm::Context
|
79
|
+
.new(Nm.default_context, source: subject, locals: subject.locals)
|
80
|
+
.render(template_name, file_locals),
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
should "only render templates with the matching extension if specified" do
|
85
|
+
source = unit_class.new(root, extension: "nm")
|
86
|
+
["locals", "locals.nm"].each do |name|
|
87
|
+
assert_that(subject.render(name, locals: file_locals))
|
88
|
+
.equals(
|
89
|
+
Nm::Context
|
90
|
+
.new(Nm.default_context, source: subject, locals: subject.locals)
|
91
|
+
.render(name, file_locals),
|
92
|
+
)
|
123
93
|
end
|
124
94
|
|
125
|
-
source =
|
126
|
-
[
|
127
|
-
|
95
|
+
source = unit_class.new(root, extension: "inem")
|
96
|
+
["locals", "locals_alt", "locals_alt.data", "locals_alt.data.inem"]
|
97
|
+
.each do |name|
|
98
|
+
assert_that(subject.render(name, locals: file_locals))
|
99
|
+
.equals(
|
100
|
+
Nm::Context
|
101
|
+
.new(
|
102
|
+
Nm.default_context,
|
103
|
+
source: subject,
|
104
|
+
locals: subject.locals,
|
105
|
+
)
|
106
|
+
.render(name, file_locals),
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
source = unit_class.new(root, extension: "nm")
|
111
|
+
["locals_alt", "locals_alt.data", "locals_alt.data.inem"].each do |name|
|
112
|
+
assert_that{ source.render(name, file_locals) }.raises(ArgumentError)
|
128
113
|
end
|
129
114
|
|
130
|
-
source =
|
131
|
-
[
|
132
|
-
|
115
|
+
source = unit_class.new(root, extension: "data")
|
116
|
+
["locals_alt", "locals_alt.data", "locals_alt.data.inem"].each do |name|
|
117
|
+
assert_that{ source.render(name, file_locals) }.raises(ArgumentError)
|
133
118
|
end
|
134
119
|
end
|
135
|
-
|
136
120
|
end
|
137
121
|
|
138
|
-
class
|
139
|
-
desc "
|
140
|
-
setup do
|
141
|
-
@source = Nm::DefaultSource.new
|
142
|
-
end
|
143
|
-
subject{ @source }
|
122
|
+
class FilePathBangTests < InitTests
|
123
|
+
desc "`file_path!` method"
|
144
124
|
|
145
|
-
|
146
|
-
|
125
|
+
let(:template_name){ ["locals", "locals_alt"].sample }
|
126
|
+
let(:file_path) do
|
127
|
+
Dir.glob("#{Factory.template_file(template_name)}*").first
|
147
128
|
end
|
148
129
|
|
149
|
-
should "
|
150
|
-
|
130
|
+
should "return the file path for the given template name if it exists" do
|
131
|
+
assert_that(subject.file_path!(template_name)).equals(file_path)
|
151
132
|
end
|
152
133
|
|
134
|
+
should "complain if the given template name does not exist" do
|
135
|
+
assert_that{ subject.file_path!(Factory.path) }.raises(ArgumentError)
|
136
|
+
end
|
153
137
|
end
|
154
|
-
|
155
138
|
end
|
@@ -0,0 +1,259 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "assert"
|
4
|
+
require "nm/template_behaviors"
|
5
|
+
|
6
|
+
require "nm/context"
|
7
|
+
require "nm/ext"
|
8
|
+
require "nm/source"
|
9
|
+
|
10
|
+
module Nm::TemplateBehaviors
|
11
|
+
class UnitTests < Assert::Context
|
12
|
+
desc "Nm::TemplateBehaviors"
|
13
|
+
subject{ unit_class }
|
14
|
+
|
15
|
+
let(:unit_module){ Nm::TemplateBehaviors }
|
16
|
+
end
|
17
|
+
|
18
|
+
class InitTests < UnitTests
|
19
|
+
desc "when mixed in on an context instance"
|
20
|
+
subject{ context }
|
21
|
+
|
22
|
+
setup do
|
23
|
+
nm_context
|
24
|
+
context.__nm_push_render__({})
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:nm_context) do
|
28
|
+
Nm::Context.new(context, source: source, locals: context_locals)
|
29
|
+
end
|
30
|
+
let(:context){ Class.new.new }
|
31
|
+
let(:template_root){ Factory.template_root }
|
32
|
+
let(:source){ Nm::Source.new(template_root) }
|
33
|
+
let(:context_locals){ {} }
|
34
|
+
|
35
|
+
should have_accessors :__nm_context__
|
36
|
+
should have_imeths :__nm_data__, :__node__, :__map__, :__partial__
|
37
|
+
should have_imeths :node, :_node, :n
|
38
|
+
should have_imeths :map, :_map, :m
|
39
|
+
should have_imeths :partial, :_partial, :p
|
40
|
+
|
41
|
+
should "have empty data if no markup meths called or no source given" do
|
42
|
+
assert_that(subject.__nm_data__).equals({})
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class NodeMethodTests < InitTests
|
47
|
+
desc "the `__node__` method"
|
48
|
+
|
49
|
+
should "return itself when called" do
|
50
|
+
assert_that(subject.__node__("key", "value")).equals(subject)
|
51
|
+
end
|
52
|
+
|
53
|
+
should "add key-value pairs at the root level" do
|
54
|
+
subject.__node__("a", "Aye")
|
55
|
+
assert_that(subject.__nm_data__).equals({ "a" => "Aye" })
|
56
|
+
end
|
57
|
+
|
58
|
+
should "add key-value pairs at nested levels" do
|
59
|
+
subject.__node__("nested"){ __node__("a", "Aye") }
|
60
|
+
assert_that(subject.__nm_data__)
|
61
|
+
.equals({
|
62
|
+
"nested" => { "a" => "Aye" },
|
63
|
+
})
|
64
|
+
end
|
65
|
+
|
66
|
+
should "be aliased as `node`, `_node` and `n`" do
|
67
|
+
exp = { "a" => "Aye" }
|
68
|
+
assert_that(subject.__node__("a", "Aye").__nm_data__).equals(exp)
|
69
|
+
assert_that(subject.node("a", "Aye").__nm_data__).equals(exp)
|
70
|
+
assert_that(subject._node("a", "Aye").__nm_data__).equals(exp)
|
71
|
+
assert_that(subject.n("a", "Aye").__nm_data__).equals(exp)
|
72
|
+
end
|
73
|
+
|
74
|
+
should "complain if called after a `__map__` call" do
|
75
|
+
subject.__map__([1, 2, 3])
|
76
|
+
assert_that{ subject.__node__("a", "Aye") }.raises(Nm::InvalidError)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class MapMethodTests < InitTests
|
81
|
+
desc "the `map` method"
|
82
|
+
|
83
|
+
let(:list){ [1, 2, 3] }
|
84
|
+
|
85
|
+
should "return itself when called" do
|
86
|
+
assert_that(subject.__map__([], &Proc.new{})).equals(subject)
|
87
|
+
end
|
88
|
+
|
89
|
+
should "map a given list to the data" do
|
90
|
+
assert_that(subject.__map__(list).__nm_data__).equals(list)
|
91
|
+
end
|
92
|
+
|
93
|
+
should "map a given list to node data" do
|
94
|
+
subject.__map__(list){ |item| __node__(item.to_s, item) }
|
95
|
+
assert_that(subject.__nm_data__)
|
96
|
+
.equals(
|
97
|
+
[
|
98
|
+
{ "1" => 1 },
|
99
|
+
{ "2" => 2 },
|
100
|
+
{ "3" => 3 },
|
101
|
+
],
|
102
|
+
)
|
103
|
+
end
|
104
|
+
|
105
|
+
should "map a given list to node data at a nested level" do
|
106
|
+
list_value = list
|
107
|
+
subject.__node__("list") do
|
108
|
+
__map__(list_value){ |item| __node__(item.to_s, item) }
|
109
|
+
end
|
110
|
+
assert_that(subject.__nm_data__)
|
111
|
+
.equals(
|
112
|
+
{
|
113
|
+
"list" => [
|
114
|
+
{ "1" => 1 },
|
115
|
+
{ "2" => 2 },
|
116
|
+
{ "3" => 3 },
|
117
|
+
],
|
118
|
+
},
|
119
|
+
)
|
120
|
+
end
|
121
|
+
|
122
|
+
should "be aliased as `map`, `_map` and `m`" do
|
123
|
+
assert_that(subject.__map__(list).__nm_data__).equals(list)
|
124
|
+
assert_that(subject.map(list).__nm_data__).equals(list + list)
|
125
|
+
assert_that(subject._map(list).__nm_data__).equals(list + list + list)
|
126
|
+
assert_that(subject.m(list).__nm_data__).equals(list + list + list + list)
|
127
|
+
end
|
128
|
+
|
129
|
+
should "complain if given a list that doesn't respond to `.map`" do
|
130
|
+
val = 123
|
131
|
+
assert_that(val).does_not_respond_to(:map)
|
132
|
+
assert_that{ subject.__map__(val) }.raises(ArgumentError)
|
133
|
+
end
|
134
|
+
|
135
|
+
should "complain if called after a `__node__` call" do
|
136
|
+
subject.__node__("a", "Aye")
|
137
|
+
assert_that{ subject.__map__([1, 2, 3]) }.raises(Nm::InvalidError)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class PartialMethodTests < InitTests
|
142
|
+
desc "the `partial` method"
|
143
|
+
|
144
|
+
let(:obj_template_name){ "obj" }
|
145
|
+
let(:obj) do
|
146
|
+
{
|
147
|
+
"obj" => {
|
148
|
+
"a" => "Aye",
|
149
|
+
"b" => "Bee",
|
150
|
+
"c" => "See",
|
151
|
+
},
|
152
|
+
}
|
153
|
+
end
|
154
|
+
let(:list_template_name){ "list" }
|
155
|
+
let(:list) do
|
156
|
+
[
|
157
|
+
{ "1" => 1 },
|
158
|
+
{ "2" => 2 },
|
159
|
+
{ "3" => 3 },
|
160
|
+
]
|
161
|
+
end
|
162
|
+
let(:partial_obj_template_name){ "_obj" }
|
163
|
+
let(:partial_obj) do
|
164
|
+
{
|
165
|
+
"a" => "Aye",
|
166
|
+
"b" => "Bee",
|
167
|
+
"c" => "See",
|
168
|
+
}
|
169
|
+
end
|
170
|
+
let(:partial_list_template_name){ "_list" }
|
171
|
+
let(:partial_list){ list }
|
172
|
+
|
173
|
+
should "return itself when called" do
|
174
|
+
assert_that(subject.__partial__(Factory.template_file("obj")))
|
175
|
+
.equals(subject)
|
176
|
+
end
|
177
|
+
|
178
|
+
should "render a template for the given partial name and add its data" do
|
179
|
+
assert_that(subject.__partial__(partial_obj_template_name).__nm_data__)
|
180
|
+
.equals(partial_obj)
|
181
|
+
end
|
182
|
+
|
183
|
+
should "be aliased as `render`, `_render` and `r`" do
|
184
|
+
assert_that(subject.__partial__(partial_obj_template_name).__nm_data__)
|
185
|
+
.equals(partial_obj)
|
186
|
+
assert_that(subject.partial(partial_obj_template_name).__nm_data__)
|
187
|
+
.equals(partial_obj)
|
188
|
+
assert_that(subject._partial(partial_obj_template_name).__nm_data__)
|
189
|
+
.equals(partial_obj)
|
190
|
+
assert_that(subject.p(partial_obj_template_name).__nm_data__)
|
191
|
+
.equals(partial_obj)
|
192
|
+
end
|
193
|
+
|
194
|
+
should "merge if call returns an obj and called after `__node__`" do
|
195
|
+
subject.__node__("1", "One")
|
196
|
+
|
197
|
+
exp = { "1" => "One" }.merge(partial_obj)
|
198
|
+
assert_that(subject.__partial__(partial_obj_template_name).__nm_data__)
|
199
|
+
.equals(exp)
|
200
|
+
end
|
201
|
+
|
202
|
+
should "complain if call returns an obj and called after `__map__`" do
|
203
|
+
subject.__map__([1, 2, 3])
|
204
|
+
assert_that{ subject.__partial__(partial_obj_template_name).__nm_data__ }
|
205
|
+
.raises(Nm::InvalidError)
|
206
|
+
end
|
207
|
+
|
208
|
+
should "merge if call returns a list and called after `__map__`" do
|
209
|
+
subject.__map__([1, 2, 3])
|
210
|
+
|
211
|
+
exp = [1, 2, 3].concat(partial_list)
|
212
|
+
assert_that(subject.__partial__(partial_list_template_name).__nm_data__)
|
213
|
+
.equals(exp)
|
214
|
+
end
|
215
|
+
|
216
|
+
should "complain if call returns a list and called after `__node__`" do
|
217
|
+
subject.__node__("1", "One")
|
218
|
+
|
219
|
+
assert_that{ subject.__partial__(partial_list_template_name).__nm_data__ }
|
220
|
+
.raises(Nm::InvalidError)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class RenderTests < InitTests
|
225
|
+
desc "and used to render a template"
|
226
|
+
|
227
|
+
let(:context) do
|
228
|
+
Class
|
229
|
+
.new{
|
230
|
+
def helper_method1
|
231
|
+
"helper method value 1"
|
232
|
+
end
|
233
|
+
}
|
234
|
+
.new
|
235
|
+
end
|
236
|
+
let(:context_locals) do
|
237
|
+
{
|
238
|
+
"key1" => "value1",
|
239
|
+
"node" => "A Node",
|
240
|
+
"map" => "A Map",
|
241
|
+
}
|
242
|
+
end
|
243
|
+
let(:render_locals) do
|
244
|
+
{ "key2" => "value2" }
|
245
|
+
end
|
246
|
+
|
247
|
+
should "render exposing locals and context methods as expected" do
|
248
|
+
d = nm_context.render("aliases.nm", render_locals)
|
249
|
+
assert_that(d).is_a(::Array)
|
250
|
+
assert_that(d.size).equals(1)
|
251
|
+
assert_that(d.first["node local value"]).equals("A Node")
|
252
|
+
assert_that(d.first["map local value"]).equals("A Map")
|
253
|
+
assert_that(d.first["context method value"])
|
254
|
+
.equals("helper method value 1")
|
255
|
+
assert_that(d.first["context local value"]).equals("value1")
|
256
|
+
assert_that(d.first["render local value"]).equals("value2")
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|