adsl 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -20
  3. data/README.md +14 -21
  4. data/bin/adsl-verify +8 -8
  5. data/lib/adsl.rb +3 -0
  6. data/lib/adsl/adsl.rb +3 -0
  7. data/lib/adsl/ds/data_store_spec.rb +339 -0
  8. data/lib/adsl/extract/instrumenter.rb +206 -0
  9. data/lib/adsl/extract/meta.rb +33 -0
  10. data/lib/adsl/extract/rails/action_block_builder.rb +233 -0
  11. data/lib/adsl/extract/rails/action_instrumenter.rb +400 -0
  12. data/lib/adsl/extract/rails/action_runner.rb +57 -0
  13. data/lib/adsl/extract/rails/active_record_metaclass_generator.rb +555 -0
  14. data/lib/adsl/extract/rails/callback_chain_simulator.rb +135 -0
  15. data/lib/adsl/extract/rails/invariant_extractor.rb +48 -0
  16. data/lib/adsl/extract/rails/invariant_instrumenter.rb +70 -0
  17. data/lib/adsl/extract/rails/other_meta.rb +57 -0
  18. data/lib/adsl/extract/rails/rails_extractor.rb +211 -0
  19. data/lib/adsl/extract/rails/rails_instrumentation_test_case.rb +34 -0
  20. data/lib/adsl/extract/rails/rails_special_gem_instrumentation.rb +120 -0
  21. data/lib/adsl/extract/rails/rails_test_helper.rb +140 -0
  22. data/lib/adsl/extract/sexp_utils.rb +54 -0
  23. data/lib/adsl/fol/first_order_logic.rb +261 -0
  24. data/lib/adsl/parser/adsl_parser.racc +159 -0
  25. data/lib/{parser → adsl/parser}/adsl_parser.rex +4 -4
  26. data/lib/{parser → adsl/parser}/adsl_parser.rex.rb +6 -6
  27. data/lib/adsl/parser/adsl_parser.tab.rb +1031 -0
  28. data/lib/adsl/parser/ast_nodes.rb +1410 -0
  29. data/lib/adsl/railtie.rb +67 -0
  30. data/lib/adsl/spass/bin.rb +230 -0
  31. data/lib/{spass → adsl/spass}/ruby_extensions.rb +0 -0
  32. data/lib/adsl/spass/spass_ds_extensions.rb +931 -0
  33. data/lib/adsl/spass/spass_translator.rb +393 -0
  34. data/lib/adsl/spass/util.rb +13 -0
  35. data/lib/adsl/util/csv_hash_formatter.rb +94 -0
  36. data/lib/adsl/util/general.rb +228 -0
  37. data/lib/adsl/util/test_helper.rb +71 -0
  38. data/lib/adsl/verification/formula_generators.rb +231 -0
  39. data/lib/adsl/verification/instrumentation_filter.rb +50 -0
  40. data/lib/adsl/verification/invariant.rb +19 -0
  41. data/lib/adsl/verification/rails_verification.rb +33 -0
  42. data/lib/adsl/verification/utils.rb +20 -0
  43. data/lib/adsl/verification/verification_case.rb +13 -0
  44. data/test/integration/rails/rails_branch_verification_test.rb +112 -0
  45. data/test/integration/rails/rails_verification_test.rb +253 -0
  46. data/test/integration/spass/basic_translation_test.rb +563 -0
  47. data/test/integration/spass/control_flow_translation_test.rb +421 -0
  48. data/test/unit/adsl/ds/data_store_spec_test.rb +54 -0
  49. data/test/unit/adsl/extract/instrumenter_test.rb +103 -0
  50. data/test/unit/adsl/extract/meta_test.rb +142 -0
  51. data/test/unit/adsl/extract/rails/action_block_builder_test.rb +178 -0
  52. data/test/unit/adsl/extract/rails/action_instrumenter_test.rb +68 -0
  53. data/test/unit/adsl/extract/rails/active_record_metaclass_generator_test.rb +336 -0
  54. data/test/unit/adsl/extract/rails/callback_chain_simulator_test.rb +76 -0
  55. data/test/unit/adsl/extract/rails/invariant_extractor_test.rb +92 -0
  56. data/test/unit/adsl/extract/rails/rails_extractor_test.rb +1380 -0
  57. data/test/unit/adsl/extract/rails/rails_test_helper_test.rb +25 -0
  58. data/test/unit/adsl/extract/sexp_utils_test.rb +100 -0
  59. data/test/unit/adsl/fol/first_order_logic_test.rb +227 -0
  60. data/test/unit/adsl/parser/action_parser_test.rb +1040 -0
  61. data/test/unit/adsl/parser/ast_nodes_test.rb +359 -0
  62. data/test/unit/adsl/parser/class_parser_test.rb +288 -0
  63. data/test/unit/adsl/parser/general_parser_test.rb +67 -0
  64. data/test/unit/adsl/parser/invariant_parser_test.rb +432 -0
  65. data/test/unit/adsl/parser/parser_util_test.rb +126 -0
  66. data/test/unit/adsl/spass/bin_test.rb +65 -0
  67. data/test/unit/adsl/spass/ruby_extensions_test.rb +39 -0
  68. data/test/unit/adsl/spass/spass_ds_extensions_test.rb +7 -0
  69. data/test/unit/adsl/spass/spass_translator_test.rb +342 -0
  70. data/test/unit/adsl/util/csv_hash_formatter_test.rb +68 -0
  71. data/test/unit/adsl/util/general_test.rb +303 -0
  72. data/test/unit/adsl/util/test_helper_test.rb +120 -0
  73. data/test/unit/adsl/verification/formula_generators_test.rb +200 -0
  74. data/test/unit/adsl/verification/instrumentation_filter_test.rb +39 -0
  75. data/test/unit/adsl/verification/utils_test.rb +39 -0
  76. data/test/unit/adsl/verification/verification_case_test.rb +8 -0
  77. metadata +229 -29
  78. data/lib/ds/data_store_spec.rb +0 -292
  79. data/lib/fol/first_order_logic.rb +0 -260
  80. data/lib/parser/adsl_ast.rb +0 -779
  81. data/lib/parser/adsl_parser.racc +0 -151
  82. data/lib/parser/adsl_parser.tab.rb +0 -976
  83. data/lib/parser/dsdl_parser.rex.rb +0 -196
  84. data/lib/parser/dsdl_parser.tab.rb +0 -976
  85. data/lib/spass/bin.rb +0 -164
  86. data/lib/spass/spass_ds_extensions.rb +0 -870
  87. data/lib/spass/spass_translator.rb +0 -388
  88. data/lib/spass/util.rb +0 -11
  89. data/lib/util/csv_hash_formatter.rb +0 -47
  90. data/lib/util/test_helper.rb +0 -33
  91. data/lib/util/util.rb +0 -114
@@ -0,0 +1,68 @@
1
+ require 'adsl/util/csv_hash_formatter'
2
+ require 'test/unit'
3
+
4
+ class ADSL::Util::CSVHashFormatterTest < Test::Unit::TestCase
5
+ include ADSL::Util
6
+
7
+ def wrap(col_count, *content)
8
+ output = ""
9
+ until content.empty?
10
+ row = content.shift col_count
11
+ output = output + row.map{ |c| "\"#{c}\"" }.join(',') + "\n"
12
+ end
13
+ output
14
+ end
15
+
16
+ def test_blank_if_empty
17
+ formatter = CSVHashFormatter.new
18
+ assert_equal '', formatter.to_s
19
+ end
20
+
21
+ def test_single_row_column
22
+ formatter = CSVHashFormatter.new
23
+ formatter << { :asd => 'kme' }
24
+ assert_equal wrap(1, 'asd', 'kme'), formatter.to_s
25
+ end
26
+
27
+ def test_no_duplicate_columns
28
+ formatter = CSVHashFormatter.new
29
+ formatter.add_column 'a'
30
+ assert_raise do
31
+ formatter.add_column 'a'
32
+ end
33
+
34
+ formatter = CSVHashFormatter.new 'a'
35
+ assert_raise do
36
+ formatter.add_column 'a'
37
+ end
38
+
39
+ assert_raise do
40
+ formatter = CSVHashFormatter.new 'a', 'a'
41
+ end
42
+ end
43
+
44
+ def test_two_rows_columns
45
+ formatter = CSVHashFormatter.new :asd, :asd2
46
+ formatter << { :asd => 'kme1', :asd2 => 'kme2'}
47
+ formatter << { :asd => 'kme3', :asd2 => 'kme4'}
48
+ assert_equal wrap(2, 'asd', 'asd2', 'kme1', 'kme2', 'kme3', 'kme4'), formatter.to_s
49
+
50
+ formatter = CSVHashFormatter.new 'asd'
51
+ formatter << { :asd => 'kme1', :asd2 => 'kme2'}
52
+ formatter << { :asd2 => 'kme4', :asd => 'kme3'}
53
+ assert_equal wrap(2, 'asd', 'asd2', 'kme1', 'kme2', 'kme3', 'kme4'), formatter.to_s
54
+ end
55
+
56
+ def test_incomplete_column_lists
57
+ formatter = CSVHashFormatter.new :col1, :col2, :col3
58
+ formatter << { :col1 => 'val1', :col2 => 'val2'}
59
+ formatter << { :col3 => 'val4', :col2 => 'val3'}
60
+ assert_equal wrap(3, 'col1', 'col2', 'col3', 'val1', 'val2', '', '', 'val3', 'val4'), formatter.to_s
61
+ end
62
+
63
+ def test_csv_escaping
64
+ formatter = CSVHashFormatter.new
65
+ formatter << { :asd => '"kme"'}
66
+ assert_equal wrap(1, 'asd', '""kme""'), formatter.to_s
67
+ end
68
+ end
@@ -0,0 +1,303 @@
1
+ require 'test/unit'
2
+ require 'adsl/util/general'
3
+ require 'adsl/util/test_helper'
4
+
5
+ class ADSL::Util::GeneralTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ assert_false class_defined? :Foo, :Foo2
9
+ end
10
+
11
+ def teardown
12
+ unload_class :Foo, :Foo2
13
+ end
14
+
15
+ def test_module__lookup_const
16
+ assert_equal Module, self.class.lookup_const('Module')
17
+ assert_equal Module, self.class.lookup_const(:Module)
18
+ assert_equal Object, self.class.lookup_const('::Object')
19
+ assert_equal Test::Unit, self.class.lookup_const('Test::Unit')
20
+ assert_equal Test::Unit::TestCase, self.class.lookup_const('Test::Unit::TestCase')
21
+ assert_equal Test::Unit::TestCase, Test::Unit.lookup_const('TestCase')
22
+ end
23
+
24
+ def test_module__lookup_or_create_module
25
+ assert_equal Module, self.class.lookup_or_create_module('Module')
26
+ assert_equal Module, self.class.lookup_or_create_module('::Module')
27
+ assert_equal Module, self.class.lookup_or_create_module(:Module)
28
+ foo = self.class.lookup_or_create_module(:Foo)
29
+ assert_equal Module, foo.class
30
+ assert_equal Foo, foo
31
+
32
+ assert_equal Test::Unit, self.class.lookup_or_create_module('Test::Unit')
33
+ new_deep = self.class.lookup_or_create_module('Test::Unit::NewDeep')
34
+ assert_equal Module, new_deep.class
35
+ assert_equal Test::Unit::NewDeep, new_deep
36
+ end
37
+
38
+ def test_module__lookup_or_create_class
39
+ assert_equal Object, self.class.lookup_or_create_class('Object', nil)
40
+ assert_equal Object, self.class.lookup_or_create_class('::Object', nil)
41
+ assert_equal Object, self.class.lookup_or_create_class(:Object, nil)
42
+ foo = self.class.lookup_or_create_class(:Foo, Object)
43
+ assert_equal Class, foo.class
44
+ assert_equal Foo, foo
45
+ assert_equal Object, foo.superclass
46
+
47
+ assert_equal Test::Unit::TestCase, self.class.lookup_or_create_class('Test::Unit::TestCase', Test::Unit::TestCase.superclass)
48
+ new_deep = self.class.lookup_or_create_class('Test::Unit::NewDeep', String)
49
+ assert_equal Class, new_deep.class
50
+ assert_equal Test::Unit::NewDeep, new_deep
51
+ assert_equal String, new_deep.superclass
52
+ ensure
53
+ unload_class 'Test::Unit::NewDeep'
54
+ end
55
+
56
+ def test_container_for__blank
57
+ eval <<-ruby
58
+ class Foo
59
+ container_for
60
+ end
61
+ ruby
62
+
63
+ assert Foo.container_for_fields.empty?
64
+ end
65
+
66
+ def test_container_for__does_list
67
+ eval <<-ruby
68
+ class Foo
69
+ container_for :field
70
+ end
71
+ ruby
72
+
73
+ kme = Foo.new
74
+ assert_nil kme.field
75
+
76
+ kme = Foo.new :field => :asd
77
+ assert_equal :asd, kme.field
78
+ end
79
+
80
+ def test_container_for__nonoverwriting
81
+ eval <<-ruby
82
+ class Foo
83
+ container_for :field
84
+ end
85
+
86
+ class Foo
87
+ container_for :field2
88
+ end
89
+ ruby
90
+
91
+ assert_nothing_raised do
92
+ Foo.new
93
+ Foo.new :field => 4
94
+ Foo.new :field2 => 5
95
+ a = Foo.new :field => 1, :field2 => 2
96
+ assert_equal 1, a.field
97
+ assert_equal 2, a.field2
98
+ end
99
+ end
100
+
101
+ def test_container_for__container_for_fields_and_inheritance
102
+ eval <<-ruby
103
+ class Foo
104
+ end
105
+ ruby
106
+
107
+ assert_raise do
108
+ Foo.container_for_fields
109
+ end
110
+
111
+ eval <<-ruby
112
+ class Foo
113
+ container_for :field
114
+ end
115
+
116
+ class Foo2 < Foo
117
+ end
118
+ ruby
119
+
120
+ assert_raise do
121
+ Class.container_for_fields
122
+ end
123
+
124
+ assert_equal [:field], Foo.container_for_fields.to_a
125
+ assert_equal [:field], Foo2.container_for_fields.to_a
126
+
127
+ eval <<-ruby
128
+ class Foo
129
+ container_for :field2
130
+ end
131
+ ruby
132
+ assert_equal [:field, :field2], Foo.container_for_fields.to_a.sort_by{ |a| a.to_s }
133
+ assert_equal [:field, :field2], Foo2.container_for_fields.to_a.sort_by{ |a| a.to_s }
134
+
135
+ eval <<-ruby
136
+ class Foo2 < Foo
137
+ container_for :field3
138
+ end
139
+ ruby
140
+ assert_equal [:field, :field2], Foo.container_for_fields.to_a.sort_by{ |a| a.to_s }
141
+ assert_equal [:field, :field2, :field3], Foo2.container_for_fields.to_a.sort_by{ |a| a.to_s }
142
+ end
143
+
144
+ def test_container_for__doesnt_list
145
+ eval <<-ruby
146
+ class Foo
147
+ container_for :field
148
+ end
149
+ ruby
150
+
151
+ assert_raise ArgumentError do
152
+ Foo.new :unknown_field => :value
153
+ end
154
+ end
155
+
156
+ def test_container_for__block
157
+ eval <<-ruby
158
+ class Foo
159
+ container_for :field do
160
+ raise 'inside block'
161
+ end
162
+ end
163
+ ruby
164
+
165
+ assert_raise RuntimeError, 'Inside block' do
166
+ Foo.new
167
+ end
168
+ end
169
+
170
+ def test_container_for__block_allows_extra_args
171
+ eval <<-ruby
172
+ class Foo
173
+ container_for :field do; end
174
+ end
175
+ ruby
176
+
177
+ Foo.new :unmentioned_field => :whatever
178
+ end
179
+
180
+ def test_container_for__recursively_gather
181
+ eval <<-ruby
182
+ class Foo
183
+ container_for :field1, :field2
184
+ attr_accessor :content
185
+ end
186
+ ruby
187
+
188
+ assert_equal [:field1, :field2], Foo.container_for_fields.to_a.sort_by{ |a| a.to_s }
189
+ assert Foo.method_defined?(:recursively_gather)
190
+ assert_equal Set[], Foo.new.recursively_gather(:field1)
191
+ assert_equal Set[:a], Foo.new(:field1 => :a).recursively_gather(:field1)
192
+
193
+ foo = Foo.new
194
+ foo.content = :kme
195
+ foo.field1 = Foo.new :field1 => :kme
196
+ foo.field1.content = :kme2
197
+ foo.field2 = Foo.new :field1 => Foo.new
198
+ foo.field2.content = :kme
199
+ assert_equal Set[:kme, :kme2], foo.recursively_gather(:content)
200
+
201
+ newchild = Foo.new
202
+ newchild.content = :asd
203
+ foo.field1 = [newchild, foo.field1]
204
+ assert_equal Set[:kme, :kme2, :asd], foo.recursively_gather(:content)
205
+ end
206
+
207
+ def test_container_for__recursively_gather_recursively_safe
208
+ eval <<-ruby
209
+ class Foo
210
+ container_for :field
211
+ attr_accessor :content
212
+ end
213
+ ruby
214
+
215
+ foo = Foo.new
216
+ foo.field = foo
217
+ foo.content = :a
218
+ assert_equal Set[:a], foo.recursively_gather(:content)
219
+ end
220
+
221
+ def test_process_race__1_process
222
+ stdout = process_race "echo 'blah'"
223
+ assert_equal 'blah', stdout.strip
224
+ end
225
+
226
+ def test_process_race__2_processes
227
+ time = Time.now
228
+ stdout = process_race "echo 'blah'", "sleep 20; echo 'blah2'"
229
+ assert (Time.now - time) < 1
230
+ assert_equal 'blah', stdout.strip
231
+ end
232
+
233
+ def test_string__increment_suffix
234
+ assert_equal 'asd_2', 'asd'.increment_suffix
235
+ assert_equal 'asd_3', 'asd_2'.increment_suffix
236
+ assert_equal 'asd_123', 'asd_122'.increment_suffix
237
+ assert_equal 'a1s2_d4_2', 'a1s2_d4'.increment_suffix
238
+ end
239
+
240
+ def test_array__worklist_each__plain
241
+ worklist = [3, 2, 1, 0]
242
+ looking_for = 0
243
+ worklist.worklist_each do |task|
244
+ if task == looking_for
245
+ looking_for += 1
246
+ next
247
+ else
248
+ next task
249
+ end
250
+ end
251
+ assert worklist.empty?
252
+ assert_equal 4, looking_for
253
+ end
254
+
255
+ def test_array__worklist_each__stops_on_no_change
256
+ worklist = [3, 2, 5, 19, 1, 0]
257
+ looking_for = 0
258
+ worklist.worklist_each do |task|
259
+ if task == looking_for
260
+ looking_for += 1
261
+ next
262
+ else
263
+ next task
264
+ end
265
+ end
266
+ assert_equal 4, looking_for
267
+ end
268
+
269
+ def test_module__parent_module
270
+ eval <<-ruby
271
+ module Foo
272
+ class Foo2
273
+ end
274
+ end
275
+ ruby
276
+
277
+ assert_equal Object, String.parent_module
278
+ assert_equal ADSL::Util::GeneralTest, Foo.parent_module
279
+ assert_equal ADSL::Util::GeneralTest::Foo, Foo::Foo2.parent_module
280
+ end
281
+
282
+ def test_array__split_simple
283
+ array = [-1, 3, 12, -5, 20, 0, 45]
284
+
285
+ accepted, rejected = array.select_reject{ |i| i > 0 }
286
+ assert_equal [3, 12, 20, 45], accepted
287
+ assert_equal [-1, -5, 0], rejected
288
+ end
289
+
290
+ def test_array__split_cornercases
291
+ accepted, rejected = [1, 2, 3, 4, 5].select_reject{ |i| i > 0 }
292
+ assert_equal [1, 2, 3, 4, 5], accepted
293
+ assert_equal [], rejected
294
+
295
+ accepted, rejected = [1, 2, 3, 4, 5].select_reject{ |i| i < 0 }
296
+ assert_equal [], accepted
297
+ assert_equal [1, 2, 3, 4, 5], rejected
298
+
299
+ accepted, rejected = [].select_reject{ |i| i < 0 }
300
+ assert_equal [], accepted
301
+ assert_equal [], rejected
302
+ end
303
+ end
@@ -0,0 +1,120 @@
1
+ require 'test/unit'
2
+ require 'adsl/util/test_helper'
3
+ require 'adsl/fol/first_order_logic'
4
+
5
+ class ADSL::Util::TestHelperTest < Test::Unit::TestCase
6
+ def test_adsl_assert__plain
7
+ adsl_assert :correct, <<-ADSL
8
+ class Class {}
9
+ action Action() {}
10
+ invariant true
11
+ ADSL
12
+ end
13
+
14
+ def test_adsl_assert__custom_conjecture
15
+ adsl_assert :correct, <<-ADSL
16
+ class Class {}
17
+ action Action() {}
18
+ invariant true
19
+ ADSL
20
+ adsl_assert :correct, <<-ADSL, :conjecture => true
21
+ class Class {}
22
+ action Action() {}
23
+ ADSL
24
+ adsl_assert :incorrect, <<-ADSL, :conjecture => false
25
+ class Class {}
26
+ action Action() {}
27
+ ADSL
28
+ end
29
+
30
+ def test_class_defined__basic
31
+ assert_false class_defined? :TestClassDefinedBasic
32
+ eval <<-ruby
33
+ class TestClassDefinedBasic
34
+ end
35
+ ruby
36
+ assert_true class_defined? :TestClassDefinedBasic
37
+ end
38
+
39
+ def test_class_defined__multiple
40
+ assert_false class_defined? :Multiple1, :Multiple2
41
+ eval <<-ruby
42
+ class Multiple1
43
+ end
44
+ ruby
45
+ assert_true class_defined? :Multiple1, :Multiple2
46
+ end
47
+
48
+ def test_unload_class__classes_unload
49
+ assert_false class_defined? :TestUnloadClassClassesUnload
50
+ eval <<-ruby
51
+ class TestUnloadClassClassesUnload
52
+ end
53
+ ruby
54
+ assert class_defined? :TestUnloadClassClassesUnload
55
+ unload_class :TestUnloadClassClassesUnload
56
+ assert_false class_defined? :TestUnloadClassClassesUnload
57
+ end
58
+
59
+ def test_unload_class__works_through_modules
60
+ assert_false class_defined? '::Mod::TestUnloadClassWorksThroughModules'
61
+ if Object.const_defined? :Mod
62
+ assert_false class_defined? '::Mod::TestUnloadClassWorksThroughModules'
63
+ end
64
+
65
+ eval <<-ruby
66
+ module ::Mod
67
+ class TestUnloadClassWorksThroughModules
68
+ end
69
+ end
70
+ ruby
71
+
72
+ assert class_defined? '::Mod::TestUnloadClassWorksThroughModules'
73
+ unload_class '::Mod::TestUnloadClassWorksThroughModules'
74
+ assert_false class_defined? '::Mod::TestUnloadClassWorksThroughModules'
75
+ end
76
+
77
+ def test_unload_class__methods_get_removed
78
+ assert_false class_defined? :TestUnloadClassMethodsGetRemoved
79
+ eval <<-ruby
80
+ class TestUnloadClassMethodsGetRemoved
81
+ def a; end
82
+ end
83
+ ruby
84
+ assert class_defined? :TestUnloadClassMethodsGetRemoved
85
+ assert self.class.const_get(:TestUnloadClassMethodsGetRemoved).method_defined?('a')
86
+ unload_class :TestUnloadClassMethodsGetRemoved
87
+ assert_false class_defined? :TestUnloadClassMethodsGetRemoved
88
+ eval <<-ruby
89
+ class TestUnloadClassMethodsGetRemoved
90
+ end
91
+ ruby
92
+ assert class_defined? :TestUnloadClassMethodsGetRemoved
93
+ assert_false self.class.const_get(:TestUnloadClassMethodsGetRemoved).methods.include?('a')
94
+ end
95
+
96
+ def test_in_temp_file__block_called
97
+ called = false
98
+ in_temp_file "" do |path|
99
+ called = true
100
+ end
101
+ assert called
102
+ end
103
+
104
+ def test_in_temp_file__content_there
105
+ expected_content = "blah\nasd\n\n"
106
+ in_temp_file expected_content do |path|
107
+ file = File.open path, 'r'
108
+ assert_equal expected_content, file.read
109
+ file.close
110
+ end
111
+ end
112
+
113
+ def test_in_temp_file__file_gone_after_call
114
+ stored_path = nil
115
+ in_temp_file "" do |path|
116
+ stored_path = path
117
+ end
118
+ assert_false File.exists? stored_path
119
+ end
120
+ end