app_archetype 1.2.3
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 -0
- data/.doxie.json +25 -0
- data/.github/workflows/build.yml +25 -0
- data/.gitignore +22 -0
- data/.rubocop.yml +35 -0
- data/.ruby-version +1 -0
- data/CONTRIBUTING.md +51 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +172 -0
- data/LICENSE +21 -0
- data/README.md +138 -0
- data/Rakefile +19 -0
- data/app_archetype.gemspec +39 -0
- data/bin/archetype +20 -0
- data/lib/app_archetype.rb +14 -0
- data/lib/app_archetype/cli.rb +204 -0
- data/lib/app_archetype/cli/presenters.rb +106 -0
- data/lib/app_archetype/cli/prompts.rb +152 -0
- data/lib/app_archetype/generators.rb +95 -0
- data/lib/app_archetype/logger.rb +69 -0
- data/lib/app_archetype/renderer.rb +116 -0
- data/lib/app_archetype/template.rb +12 -0
- data/lib/app_archetype/template/helpers.rb +216 -0
- data/lib/app_archetype/template/manifest.rb +193 -0
- data/lib/app_archetype/template/plan.rb +172 -0
- data/lib/app_archetype/template/source.rb +39 -0
- data/lib/app_archetype/template/variable.rb +237 -0
- data/lib/app_archetype/template/variable_manager.rb +75 -0
- data/lib/app_archetype/template_manager.rb +113 -0
- data/lib/app_archetype/version.rb +6 -0
- data/lib/core_ext/string.rb +67 -0
- data/spec/app_archetype/cli/presenters_spec.rb +99 -0
- data/spec/app_archetype/cli/prompts_spec.rb +292 -0
- data/spec/app_archetype/cli_spec.rb +132 -0
- data/spec/app_archetype/generators_spec.rb +119 -0
- data/spec/app_archetype/logger_spec.rb +86 -0
- data/spec/app_archetype/renderer_spec.rb +291 -0
- data/spec/app_archetype/template/helpers_spec.rb +251 -0
- data/spec/app_archetype/template/manifest_spec.rb +245 -0
- data/spec/app_archetype/template/plan_spec.rb +191 -0
- data/spec/app_archetype/template/source_spec.rb +60 -0
- data/spec/app_archetype/template/variable_manager_spec.rb +103 -0
- data/spec/app_archetype/template/variable_spec.rb +245 -0
- data/spec/app_archetype/template_manager_spec.rb +221 -0
- data/spec/core_ext/string_spec.rb +143 -0
- data/spec/spec_helper.rb +29 -0
- metadata +370 -0
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe AppArchetype::Template::Plan do
|
4
|
+
let(:template) { AppArchetype::Template::Source.new('path/to/template') }
|
5
|
+
let(:destination) { 'path/to/destination' }
|
6
|
+
let(:variables) do
|
7
|
+
OpenStruct.new(
|
8
|
+
foo: 'bar'
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
subject do
|
13
|
+
described_class.new(
|
14
|
+
template,
|
15
|
+
variables,
|
16
|
+
destination_path: destination
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#devise' do
|
21
|
+
let(:dest_exist) { true }
|
22
|
+
|
23
|
+
before do
|
24
|
+
allow(subject).to receive(:destination_exist?).and_return(dest_exist)
|
25
|
+
allow(template).to receive(:files).and_return(['path/to/file'])
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'creates file objects' do
|
29
|
+
subject.devise
|
30
|
+
expect(subject.files).to all be_a(AppArchetype::Template::OutputFile)
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'destination path does not exist' do
|
34
|
+
let(:dest_exist) { false }
|
35
|
+
|
36
|
+
it 'raises error' do
|
37
|
+
expect do
|
38
|
+
subject.devise
|
39
|
+
end.to raise_error('destination path does not exist')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#execute' do
|
45
|
+
let(:renderer) { double(AppArchetype::Renderer) }
|
46
|
+
|
47
|
+
before do
|
48
|
+
allow(renderer).to receive(:render)
|
49
|
+
allow(AppArchetype::Renderer)
|
50
|
+
.to receive(:new)
|
51
|
+
.and_return(renderer)
|
52
|
+
|
53
|
+
subject.execute
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'creates a renderer' do
|
57
|
+
expect(AppArchetype::Renderer)
|
58
|
+
.to have_received(:new).with(subject, false)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'renders plan' do
|
62
|
+
expect(renderer).to have_received(:render)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#destination_exist?' do
|
67
|
+
let(:dirname) { 'some-directory' }
|
68
|
+
let(:exist) { true }
|
69
|
+
|
70
|
+
before do
|
71
|
+
allow(File).to receive(:exist?).and_return(exist)
|
72
|
+
allow(File).to receive(:dirname).and_return(dirname)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns true' do
|
76
|
+
expect(subject.destination_exist?).to be true
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when destination does not exist' do
|
80
|
+
let(:exist) { false }
|
81
|
+
|
82
|
+
it 'returns false' do
|
83
|
+
expect(subject.destination_exist?).to be false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#render_dest_file_path' do
|
89
|
+
it 'creates a destination file path from source path' do
|
90
|
+
expect(
|
91
|
+
subject.render_dest_file_path('path/to/template/file')
|
92
|
+
).to eq 'path/to/destination/file'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#render_path' do
|
97
|
+
it 'renders path with variables' do
|
98
|
+
expect(subject.render_path('{{foo}}')).to eq 'bar'
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
RSpec.describe AppArchetype::Template::OutputFile do
|
104
|
+
let(:source_file) { 'path/to/source' }
|
105
|
+
let(:dest_file) { 'path/to/dest' }
|
106
|
+
|
107
|
+
subject { described_class.new(source_file, dest_file) }
|
108
|
+
|
109
|
+
describe '#source_directory?' do
|
110
|
+
before do
|
111
|
+
allow(File).to receive(:directory?)
|
112
|
+
subject.source_directory?
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'delegates source file directory check to File' do
|
116
|
+
expect(File).to have_received(:directory?).with(source_file)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#source_erb?' do
|
121
|
+
let(:ext) { '.erb' }
|
122
|
+
|
123
|
+
before do
|
124
|
+
allow(File).to receive(:extname).and_return(ext)
|
125
|
+
@result = subject.source_erb?
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'delegates source file template check to File' do
|
129
|
+
expect(File).to have_received(:extname).with(source_file)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'returns true if file is erb' do
|
133
|
+
expect(@result).to be true
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'when not erb' do
|
137
|
+
let(:ext) { 'doc' }
|
138
|
+
|
139
|
+
it 'returns false' do
|
140
|
+
expect(@result).to be false
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#source_hbs?' do
|
146
|
+
let(:ext) { '.hbs' }
|
147
|
+
|
148
|
+
before do
|
149
|
+
allow(File).to receive(:extname).and_return(ext)
|
150
|
+
@result = subject.source_hbs?
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'delegates source file template check to File' do
|
154
|
+
expect(File).to have_received(:extname).with(source_file)
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'returns true if file is hbs' do
|
158
|
+
expect(@result).to be true
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'when not hbs' do
|
162
|
+
let(:ext) { 'doc' }
|
163
|
+
|
164
|
+
it 'returns false' do
|
165
|
+
expect(@result).to be false
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe '#source_file?' do
|
171
|
+
before do
|
172
|
+
allow(File).to receive(:file?)
|
173
|
+
subject.source_file?
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'delegates source file check to File' do
|
177
|
+
expect(File).to have_received(:file?).with(source_file)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#exist?' do
|
182
|
+
before do
|
183
|
+
allow(File).to receive(:exist?)
|
184
|
+
subject.exist?
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'delegates exist check to File' do
|
188
|
+
expect(File).to have_received(:exist?).with(dest_file)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe AppArchetype::Template::Source do
|
4
|
+
let(:path) { 'path/to/source' }
|
5
|
+
subject { described_class.new(path) }
|
6
|
+
|
7
|
+
describe '#load' do
|
8
|
+
let(:glob_files) { %w[file1 file2] }
|
9
|
+
let(:exist) { true }
|
10
|
+
|
11
|
+
before do
|
12
|
+
allow(Dir).to receive(:glob).and_return(glob_files)
|
13
|
+
allow(subject).to receive(:exist?).and_return(exist)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when source exists' do
|
17
|
+
before do
|
18
|
+
subject.load
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'loads expected file paths into source_files' do
|
22
|
+
expect(subject.files).to eq glob_files
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when source does not exist' do
|
27
|
+
let(:exist) { false }
|
28
|
+
|
29
|
+
it 'raises template source does not exist error' do
|
30
|
+
expect do
|
31
|
+
subject.load
|
32
|
+
end.to raise_error('template source does not exist')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#exist?' do
|
38
|
+
let(:path) { 'path/to/source' }
|
39
|
+
let(:exist) { true }
|
40
|
+
|
41
|
+
before { allow(File).to receive(:exist?).and_return(exist) }
|
42
|
+
|
43
|
+
it 'checks if file exists' do
|
44
|
+
expect(File).to receive(:exist?).with(path)
|
45
|
+
subject.exist?
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns true' do
|
49
|
+
expect(subject.exist?).to be true
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when file does not exist' do
|
53
|
+
let(:exist) { false }
|
54
|
+
|
55
|
+
it 'returns false' do
|
56
|
+
expect(subject.exist?).to be false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe AppArchetype::Template::VariableManager do
|
4
|
+
let(:var_name) { 'example_string' }
|
5
|
+
let(:var_type) { 'string' }
|
6
|
+
let(:var_desc) { 'This is an example string variable' }
|
7
|
+
let(:var_default) { 'default value' }
|
8
|
+
let(:var_value) { 'set value' }
|
9
|
+
|
10
|
+
let(:variables_spec) do
|
11
|
+
{
|
12
|
+
var_name => {
|
13
|
+
'type' => var_type,
|
14
|
+
'description' => var_desc,
|
15
|
+
'default' => var_default
|
16
|
+
},
|
17
|
+
"#{var_name}_with_value" => {
|
18
|
+
'type' => var_type,
|
19
|
+
'description' => var_desc,
|
20
|
+
'default' => var_default,
|
21
|
+
'value' => var_value
|
22
|
+
},
|
23
|
+
'example_random_string' => {
|
24
|
+
'type' => 'string',
|
25
|
+
'description' => 'Example call to helper to generate 25 char string',
|
26
|
+
'value' => '#random_string,25'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
subject { described_class.new(variables_spec) }
|
32
|
+
|
33
|
+
describe '#all' do
|
34
|
+
it 'returns array of template variables' do
|
35
|
+
expect(subject.all).to all(be_a AppArchetype::Template::Variable)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'has expected variables' do
|
39
|
+
expect(subject.all.map(&:name))
|
40
|
+
.to eq(
|
41
|
+
%w[
|
42
|
+
example_string
|
43
|
+
example_string_with_value
|
44
|
+
example_random_string
|
45
|
+
]
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#get' do
|
51
|
+
before { @var = subject.get(var_name) }
|
52
|
+
|
53
|
+
it 'returns variable' do
|
54
|
+
expect(@var.name).to eq var_name
|
55
|
+
expect(@var.type).to eq var_type
|
56
|
+
expect(@var.description).to eq var_desc
|
57
|
+
expect(@var.default).to eq var_default
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#to_h' do
|
62
|
+
let(:instance_helpers) { double }
|
63
|
+
let(:random_result) { 'random-string-25-chars-long' }
|
64
|
+
|
65
|
+
before do
|
66
|
+
allow_any_instance_of(AppArchetype::Template::Variable)
|
67
|
+
.to receive(:helpers)
|
68
|
+
.and_return(instance_helpers)
|
69
|
+
|
70
|
+
allow(instance_helpers)
|
71
|
+
.to receive(:random_string)
|
72
|
+
.and_return(random_result)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns hash representation of variables (key => value)' do
|
76
|
+
expect(subject.to_h).to eq(
|
77
|
+
var_name => var_default,
|
78
|
+
"#{var_name}_with_value" => var_value,
|
79
|
+
'example_random_string' => random_result
|
80
|
+
)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#method_missing' do
|
85
|
+
context 'when variable is defined without value' do
|
86
|
+
it 'returns default variable value' do
|
87
|
+
expect(subject.example_string).to eq var_default
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when variable is defined with a value' do
|
92
|
+
it 'returns set variable value' do
|
93
|
+
expect(subject.example_string_with_value).to eq var_value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when variable is not defined' do
|
98
|
+
it 'raises NoMethodError' do
|
99
|
+
expect { subject.foo }.to raise_error(NoMethodError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe AppArchetype::Template::Variable do
|
4
|
+
let(:description) { 'explanation of variable' }
|
5
|
+
let(:type) { 'string' }
|
6
|
+
let(:default) { 'default-value' }
|
7
|
+
let(:value) { nil }
|
8
|
+
|
9
|
+
let(:name) { 'var' }
|
10
|
+
let(:spec) do
|
11
|
+
{
|
12
|
+
'description' => description,
|
13
|
+
'type' => type,
|
14
|
+
'default' => default,
|
15
|
+
'value' => value
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
subject { described_class.new(name, spec) }
|
20
|
+
|
21
|
+
describe '::STRING_VALIDATOR' do
|
22
|
+
it 'returns true when given string input' do
|
23
|
+
expect(
|
24
|
+
described_class::STRING_VALIDATOR.call('this is string')
|
25
|
+
).to be true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'returns false when given non string input' do
|
29
|
+
expect(
|
30
|
+
described_class::STRING_VALIDATOR.call(1)
|
31
|
+
).to be false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '::BOOLEAN_VALIDATOR' do
|
36
|
+
it 'returns true when given boolean input' do
|
37
|
+
expect(
|
38
|
+
described_class::BOOLEAN_VALIDATOR.call(true)
|
39
|
+
).to be true
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns true when given string representation of boolean input' do
|
43
|
+
expect(
|
44
|
+
described_class::BOOLEAN_VALIDATOR.call('true')
|
45
|
+
).to be true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns false when given non boolean input' do
|
49
|
+
expect(
|
50
|
+
described_class::BOOLEAN_VALIDATOR.call('not bool')
|
51
|
+
).to be false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '::INTEGER_VALIDATOR' do
|
56
|
+
it 'returns true when given integer input' do
|
57
|
+
expect(
|
58
|
+
described_class::INTEGER_VALIDATOR.call(1)
|
59
|
+
).to be true
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'returns true when given string representation of integer' do
|
63
|
+
expect(
|
64
|
+
described_class::INTEGER_VALIDATOR.call('1')
|
65
|
+
).to be true
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns false when given non integer input' do
|
69
|
+
expect(
|
70
|
+
described_class::INTEGER_VALIDATOR.call('one')
|
71
|
+
).to be false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#set!' do
|
76
|
+
context 'setting with a valid value' do
|
77
|
+
before { subject.set!('a value') }
|
78
|
+
|
79
|
+
it 'sets the value of the variable' do
|
80
|
+
expect(subject.value).to eq 'a value'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'setting with an invalid value' do
|
85
|
+
let(:type) { 'integer' }
|
86
|
+
|
87
|
+
it 'raises invalid value runtime error' do
|
88
|
+
expect do
|
89
|
+
subject.set!('a string')
|
90
|
+
end.to raise_error('invalid value')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe '#default' do
|
96
|
+
context 'when default is in specification' do
|
97
|
+
it 'returns specified default value' do
|
98
|
+
expect(subject.default).to eq default
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when default is not specified' do
|
103
|
+
let(:spec) do
|
104
|
+
{
|
105
|
+
'type' => 'integer'
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'returns archetype default' do
|
110
|
+
expect(subject.default).to eq 0
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '#description' do
|
116
|
+
context 'when description is in specification' do
|
117
|
+
it 'returns specified description value' do
|
118
|
+
expect(subject.description).to eq description
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when default is not specified' do
|
123
|
+
let(:spec) do
|
124
|
+
{
|
125
|
+
'type' => 'integer'
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'returns empty string' do
|
130
|
+
expect(subject.description).to eq ''
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe '#type' do
|
136
|
+
context 'when type is in specification' do
|
137
|
+
it 'returns specified type value' do
|
138
|
+
expect(subject.type).to eq type
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when default is not specified' do
|
143
|
+
let(:spec) do
|
144
|
+
{}
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'returns string by default' do
|
148
|
+
expect(subject.type).to eq 'string'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe '#value' do
|
154
|
+
context 'when value is not specified' do
|
155
|
+
it 'returns default value' do
|
156
|
+
expect(subject.value).to eq default
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'when value is a function call' do
|
161
|
+
let(:helper) { double }
|
162
|
+
let(:value) { '#upcase,foo' }
|
163
|
+
|
164
|
+
it 'returns result of function call' do
|
165
|
+
expect(subject.value).to eq 'FOO'
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'when value has been set' do
|
170
|
+
let(:value) { 'some-value' }
|
171
|
+
|
172
|
+
it 'returns variable value' do
|
173
|
+
expect(subject.value).to eq value
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe '#value?' do
|
179
|
+
context 'when value is not set' do
|
180
|
+
let(:value) { nil }
|
181
|
+
|
182
|
+
it 'returns false' do
|
183
|
+
expect(subject.value?).to be false
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
let(:value) { 'some-value' }
|
188
|
+
|
189
|
+
context 'when value is set' do
|
190
|
+
it 'returns true' do
|
191
|
+
expect(subject.value?).to be true
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#validator' do
|
197
|
+
context 'when variable type is specified' do
|
198
|
+
let(:type) { 'integer' }
|
199
|
+
|
200
|
+
it 'returns validator for specified type' do
|
201
|
+
expect(subject.validator)
|
202
|
+
.to eq AppArchetype::Template::Variable::INTEGER_VALIDATOR
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'when variable type is not specified' do
|
207
|
+
let(:type) { nil }
|
208
|
+
|
209
|
+
it 'returns string validator' do
|
210
|
+
expect(subject.validator)
|
211
|
+
.to eq AppArchetype::Template::Variable::STRING_VALIDATOR
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe '#valid?' do
|
217
|
+
context 'when validator returns true' do
|
218
|
+
let(:result) { true }
|
219
|
+
let(:validator) { double(call: result) }
|
220
|
+
|
221
|
+
before do
|
222
|
+
allow(subject).to receive(:validator)
|
223
|
+
.and_return(validator)
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'returns true' do
|
227
|
+
expect(subject.valid?('input')).to be true
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'when validator returns false' do
|
232
|
+
let(:result) { false }
|
233
|
+
let(:validator) { double(call: result) }
|
234
|
+
|
235
|
+
before do
|
236
|
+
allow(subject).to receive(:validator)
|
237
|
+
.and_return(validator)
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'returns false' do
|
241
|
+
expect(subject.valid?('input')).to be false
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|