mtk_framework 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.github/workflows/test.yml +21 -0
  4. data/.rspec +1 -0
  5. data/Gemfile +22 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +18 -0
  8. data/Rakefile +50 -0
  9. data/VERSION +1 -0
  10. data/lib/mtk_framework.rb +50 -0
  11. data/lib/mtk_framework/active_interaction_concerns/i18nable.rb +18 -0
  12. data/lib/mtk_framework/active_interaction_concerns/interruptable.rb +32 -0
  13. data/lib/mtk_framework/active_interaction_concerns/loggable.rb +84 -0
  14. data/lib/mtk_framework/active_interaction_concerns/rescuable.rb +27 -0
  15. data/lib/mtk_framework/active_interaction_concerns/updatable_object.rb +32 -0
  16. data/lib/mtk_framework/active_interaction_mocks/interaction_group_mocks_helper.rb +32 -0
  17. data/lib/mtk_framework/active_interaction_mocks/interaction_mocks_helper.rb +61 -0
  18. data/lib/mtk_framework/active_interaction_mocks/mocks_loader.rb +53 -0
  19. data/lib/mtk_framework/active_interaction_params.rb +16 -0
  20. data/lib/mtk_framework/active_interaction_params/parametrize_filter.rb +108 -0
  21. data/lib/mtk_framework/core_extensions/array/except.rb +7 -0
  22. data/lib/mtk_framework/core_extensions/class/virtual_method.rb +11 -0
  23. data/lib/mtk_framework/core_extensions/hash/rename_keys.rb +11 -0
  24. data/lib/mtk_framework/gem_extensions/active_interaction/base.rb +20 -0
  25. data/lib/mtk_framework/gem_extensions/active_interaction/filters/abstract_tz_filter.rb +28 -0
  26. data/lib/mtk_framework/gem_extensions/active_interaction/filters/hash_filter.rb +38 -0
  27. data/lib/mtk_framework/gem_extensions/active_interaction/filters/tz_account_filter.rb +23 -0
  28. data/lib/mtk_framework/gem_extensions/active_interaction/filters/tz_contract_address_filter.rb +23 -0
  29. data/lib/mtk_framework/gem_extensions/active_interaction/filters/tz_operation_filter.rb +23 -0
  30. data/lib/mtk_framework/gem_extensions/active_interaction/filters/tz_public_key_filter.rb +23 -0
  31. data/lib/mtk_framework/gem_extensions/active_interaction/filters/tz_secret_key_filter.rb +23 -0
  32. data/lib/mtk_framework/gem_extensions/active_interaction/filters/tz_signature_filter.rb +23 -0
  33. data/lib/mtk_framework/locale/active_interaction.fr.yml +8 -0
  34. data/lib/mtk_framework/locale/fr.yml +219 -0
  35. data/lib/mtk_framework/railtie.rb +13 -0
  36. data/mtk_framework.gemspec +114 -0
  37. data/spec/active_interaction_concerns/interruptable_spec.rb +127 -0
  38. data/spec/active_interaction_concerns/loggable_spec.rb +195 -0
  39. data/spec/application_interaction_spec.rb +17 -0
  40. data/spec/fake_app.rb +14 -0
  41. data/spec/gem_extensions/active_interaction/filters/tz_account_filter_spec.rb +7 -0
  42. data/spec/gem_extensions/active_interaction/filters/tz_contract_address_filter_spec.rb +7 -0
  43. data/spec/gem_extensions/active_interaction/filters/tz_operation_filter_spec.rb +7 -0
  44. data/spec/gem_extensions/active_interaction/filters/tz_public_key_filter_spec.rb +7 -0
  45. data/spec/gem_extensions/active_interaction/filters/tz_secret_key_filter_spec.rb +7 -0
  46. data/spec/gem_extensions/active_interaction/filters/tz_signature_filter_spec.rb +7 -0
  47. data/spec/gem_extensions/active_interaction/filters_shared.rb +253 -0
  48. data/spec/gem_extensions/active_interaction/tz_filters_shared.rb +60 -0
  49. data/spec/spec_helper.rb +24 -0
  50. metadata +232 -0
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteraction
4
+ class Base
5
+ # @!method self.tz_secret_key(*attributes, options = {})
6
+ # Creates accessors for the attributes and ensures that values passed to
7
+ # the attributes are Strings.
8
+ #
9
+ # @example
10
+ # tz_secret_key :secret_key
11
+ end
12
+
13
+ # @private
14
+ class TzSecretKeyFilter < AbstractTzFilter
15
+ register :tz_secret_key
16
+
17
+ private
18
+
19
+ def prefixes
20
+ %i[edsk edsk2].freeze
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveInteraction
4
+ class Base
5
+ # @!method self.tz_signature(*attributes, options = {})
6
+ # Creates accessors for the attributes and ensures that values passed to
7
+ # the attributes are Strings.
8
+ #
9
+ # @example
10
+ # tz_signature :signature
11
+ end
12
+
13
+ # @private
14
+ class TzSignatureFilter < AbstractTzFilter
15
+ register :tz_signature
16
+
17
+ private
18
+
19
+ def prefixes
20
+ %i[edsig spsig1 p2sig sig].freeze
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,8 @@
1
+ active_interaction:
2
+ types:
3
+ tz_secret_key: clef secrète tezos
4
+ tz_public_key: clef publique tezos
5
+ tz_contract_address: adresse de smart contrat tezos
6
+ tz_account: compte tezos
7
+ tz_signature: signature tezos
8
+ tz_operation: operation tezos
@@ -0,0 +1,219 @@
1
+ # find in github: https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/fr.yml
2
+ fr:
3
+ activerecord:
4
+ errors:
5
+ messages:
6
+ record_invalid: 'La validation a échoué : %{errors}'
7
+ restrict_dependent_destroy:
8
+ has_one: Vous ne pouvez pas supprimer l'enregistrement car un(e) %{record}
9
+ dépendant(e) existe
10
+ has_many: Vous ne pouvez pas supprimer l'enregistrement parce que les %{record}
11
+ dépendants existent
12
+ date:
13
+ abbr_day_names:
14
+ - dim
15
+ - lun
16
+ - mar
17
+ - mer
18
+ - jeu
19
+ - ven
20
+ - sam
21
+ abbr_month_names:
22
+ -
23
+ - jan.
24
+ - fév.
25
+ - mar.
26
+ - avr.
27
+ - mai
28
+ - juin
29
+ - juil.
30
+ - août
31
+ - sept.
32
+ - oct.
33
+ - nov.
34
+ - déc.
35
+ day_names:
36
+ - dimanche
37
+ - lundi
38
+ - mardi
39
+ - mercredi
40
+ - jeudi
41
+ - vendredi
42
+ - samedi
43
+ formats:
44
+ default: "%d/%m/%Y"
45
+ long: "%e %B %Y"
46
+ short: "%e %b"
47
+ month_names:
48
+ -
49
+ - janvier
50
+ - février
51
+ - mars
52
+ - avril
53
+ - mai
54
+ - juin
55
+ - juillet
56
+ - août
57
+ - septembre
58
+ - octobre
59
+ - novembre
60
+ - décembre
61
+ order:
62
+ - :day
63
+ - :month
64
+ - :year
65
+ datetime:
66
+ distance_in_words:
67
+ about_x_hours:
68
+ one: environ une heure
69
+ other: environ %{count} heures
70
+ about_x_months:
71
+ one: environ un mois
72
+ other: environ %{count} mois
73
+ about_x_years:
74
+ one: environ un an
75
+ other: environ %{count} ans
76
+ almost_x_years:
77
+ one: presqu'un an
78
+ other: presque %{count} ans
79
+ half_a_minute: une demi-minute
80
+ less_than_x_seconds:
81
+ zero: moins d'une seconde
82
+ one: moins d'une seconde
83
+ other: moins de %{count} secondes
84
+ less_than_x_minutes:
85
+ zero: moins d'une minute
86
+ one: moins d'une minute
87
+ other: moins de %{count} minutes
88
+ over_x_years:
89
+ one: plus d'un an
90
+ other: plus de %{count} ans
91
+ x_seconds:
92
+ one: 1 seconde
93
+ other: "%{count} secondes"
94
+ x_minutes:
95
+ one: 1 minute
96
+ other: "%{count} minutes"
97
+ x_days:
98
+ one: 1 jour
99
+ other: "%{count} jours"
100
+ x_months:
101
+ one: 1 mois
102
+ other: "%{count} mois"
103
+ x_years:
104
+ one: 1 an
105
+ other: "%{count} ans"
106
+ prompts:
107
+ second: Seconde
108
+ minute: Minute
109
+ hour: Heure
110
+ day: Jour
111
+ month: Mois
112
+ year: Année
113
+ errors:
114
+ format: "%{attribute} %{message}"
115
+ messages:
116
+ accepted: doit être accepté(e)
117
+ blank: doit être rempli(e)
118
+ confirmation: ne concorde pas avec %{attribute}
119
+ empty: doit être rempli(e)
120
+ equal_to: doit être égal à %{count}
121
+ even: doit être pair
122
+ exclusion: n'est pas disponible
123
+ greater_than: doit être supérieur à %{count}
124
+ greater_than_or_equal_to: doit être supérieur ou égal à %{count}
125
+ inclusion: n'est pas inclus(e) dans la liste
126
+ invalid: n'est pas valide
127
+ less_than: doit être inférieur à %{count}
128
+ less_than_or_equal_to: doit être inférieur ou égal à %{count}
129
+ model_invalid: 'Validation échouée : %{errors}'
130
+ not_a_number: n'est pas un nombre
131
+ not_an_integer: doit être un nombre entier
132
+ odd: doit être impair
133
+ other_than: doit être différent de %{count}
134
+ present: doit être vide
135
+ required: doit exister
136
+ taken: n'est pas disponible
137
+ too_long:
138
+ one: est trop long (pas plus d'un caractère)
139
+ other: est trop long (pas plus de %{count} caractères)
140
+ too_short:
141
+ one: est trop court (au moins un caractère)
142
+ other: est trop court (au moins %{count} caractères)
143
+ wrong_length:
144
+ one: ne fait pas la bonne longueur (doit comporter un seul caractère)
145
+ other: ne fait pas la bonne longueur (doit comporter %{count} caractères)
146
+ template:
147
+ body: 'Veuillez vérifier les champs suivants : '
148
+ header:
149
+ one: 'Impossible d''enregistrer ce(tte) %{model} : 1 erreur'
150
+ other: 'Impossible d''enregistrer ce(tte) %{model} : %{count} erreurs'
151
+ helpers:
152
+ select:
153
+ prompt: Veuillez sélectionner
154
+ submit:
155
+ create: Créer un(e) %{model}
156
+ submit: Enregistrer ce(tte) %{model}
157
+ update: Modifier ce(tte) %{model}
158
+ number:
159
+ currency:
160
+ format:
161
+ delimiter: " "
162
+ format: "%n %u"
163
+ precision: 2
164
+ separator: ","
165
+ significant: false
166
+ strip_insignificant_zeros: false
167
+ unit: "€"
168
+ format:
169
+ delimiter: " "
170
+ precision: 3
171
+ separator: ","
172
+ significant: false
173
+ strip_insignificant_zeros: false
174
+ human:
175
+ decimal_units:
176
+ format: "%n %u"
177
+ units:
178
+ billion: milliard
179
+ million: million
180
+ quadrillion: million de milliards
181
+ thousand: millier
182
+ trillion: billion
183
+ unit: ''
184
+ format:
185
+ delimiter: ''
186
+ precision: 3
187
+ significant: true
188
+ strip_insignificant_zeros: true
189
+ storage_units:
190
+ format: "%n %u"
191
+ units:
192
+ byte:
193
+ one: octet
194
+ other: octets
195
+ eb: Eo
196
+ gb: Go
197
+ kb: ko
198
+ mb: Mo
199
+ pb: Po
200
+ tb: To
201
+ percentage:
202
+ format:
203
+ delimiter: ''
204
+ format: "%n%"
205
+ precision:
206
+ format:
207
+ delimiter: ''
208
+ support:
209
+ array:
210
+ last_word_connector: " et "
211
+ two_words_connector: " et "
212
+ words_connector: ", "
213
+ time:
214
+ am: am
215
+ formats:
216
+ default: "%d %B %Y %Hh %Mmin %Ss"
217
+ long: "%A %d %B %Y %Hh%M"
218
+ short: "%d %b %Hh%M"
219
+ pm: pm
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'active_interaction_mocks/mocks_loader.rb'
4
+
5
+ module MtkFramework
6
+ class Railtie < Rails::Railtie
7
+ config.after_initialize do
8
+ if ENV['RAILS_ENV'] == 'test'
9
+ MtkFramework::ActiveInteractionMocks::MocksLoader.new.run
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,114 @@
1
+ # Generated by juwelier
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: mtk_framework 0.1.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "mtk_framework".freeze
9
+ s.version = "0.1.0"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["othmane el kesri".freeze]
14
+ s.date = "2021-03-18"
15
+ s.email = "dev@moneytrack.io".freeze
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.txt",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".github/workflows/test.yml",
23
+ ".rspec",
24
+ "Gemfile",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "lib/mtk_framework.rb",
30
+ "lib/mtk_framework/active_interaction_concerns/i18nable.rb",
31
+ "lib/mtk_framework/active_interaction_concerns/interruptable.rb",
32
+ "lib/mtk_framework/active_interaction_concerns/loggable.rb",
33
+ "lib/mtk_framework/active_interaction_concerns/rescuable.rb",
34
+ "lib/mtk_framework/active_interaction_concerns/updatable_object.rb",
35
+ "lib/mtk_framework/active_interaction_mocks/interaction_group_mocks_helper.rb",
36
+ "lib/mtk_framework/active_interaction_mocks/interaction_mocks_helper.rb",
37
+ "lib/mtk_framework/active_interaction_mocks/mocks_loader.rb",
38
+ "lib/mtk_framework/active_interaction_params.rb",
39
+ "lib/mtk_framework/active_interaction_params/parametrize_filter.rb",
40
+ "lib/mtk_framework/core_extensions/array/except.rb",
41
+ "lib/mtk_framework/core_extensions/class/virtual_method.rb",
42
+ "lib/mtk_framework/core_extensions/hash/rename_keys.rb",
43
+ "lib/mtk_framework/gem_extensions/active_interaction/base.rb",
44
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/abstract_tz_filter.rb",
45
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/hash_filter.rb",
46
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/tz_account_filter.rb",
47
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/tz_contract_address_filter.rb",
48
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/tz_operation_filter.rb",
49
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/tz_public_key_filter.rb",
50
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/tz_secret_key_filter.rb",
51
+ "lib/mtk_framework/gem_extensions/active_interaction/filters/tz_signature_filter.rb",
52
+ "lib/mtk_framework/locale/active_interaction.fr.yml",
53
+ "lib/mtk_framework/locale/fr.yml",
54
+ "lib/mtk_framework/railtie.rb",
55
+ "mtk_framework.gemspec",
56
+ "spec/active_interaction_concerns/interruptable_spec.rb",
57
+ "spec/active_interaction_concerns/loggable_spec.rb",
58
+ "spec/application_interaction_spec.rb",
59
+ "spec/fake_app.rb",
60
+ "spec/gem_extensions/active_interaction/filters/tz_account_filter_spec.rb",
61
+ "spec/gem_extensions/active_interaction/filters/tz_contract_address_filter_spec.rb",
62
+ "spec/gem_extensions/active_interaction/filters/tz_operation_filter_spec.rb",
63
+ "spec/gem_extensions/active_interaction/filters/tz_public_key_filter_spec.rb",
64
+ "spec/gem_extensions/active_interaction/filters/tz_secret_key_filter_spec.rb",
65
+ "spec/gem_extensions/active_interaction/filters/tz_signature_filter_spec.rb",
66
+ "spec/gem_extensions/active_interaction/filters_shared.rb",
67
+ "spec/gem_extensions/active_interaction/tz_filters_shared.rb",
68
+ "spec/spec_helper.rb"
69
+ ]
70
+ s.homepage = "http://github.com/moneytrackio/mtk_framework".freeze
71
+ s.licenses = ["MIT".freeze]
72
+ s.rubygems_version = "3.0.8".freeze
73
+ s.summary = "Moneytrack's gems extensions and monkey patches.".freeze
74
+
75
+ if s.respond_to? :specification_version then
76
+ s.specification_version = 4
77
+
78
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
79
+ s.add_runtime_dependency(%q<active_interaction>.freeze, ["~> 4.0"])
80
+ s.add_runtime_dependency(%q<grape>.freeze, ["~> 1.3.0"])
81
+ s.add_runtime_dependency(%q<rails>.freeze, ["~> 6.0.0"])
82
+ s.add_runtime_dependency(%q<rspec-rails>.freeze, ["~> 3.8.2"])
83
+ s.add_runtime_dependency(%q<tezos_client>.freeze, ["~> 1.3.5"])
84
+ s.add_development_dependency(%q<bundler>.freeze, ["~> 2.2.14"])
85
+ s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
86
+ s.add_development_dependency(%q<pry>.freeze, [">= 0"])
87
+ s.add_development_dependency(%q<rdoc>.freeze, ["~> 3.12"])
88
+ s.add_development_dependency(%q<faker>.freeze, [">= 0"])
89
+ else
90
+ s.add_dependency(%q<active_interaction>.freeze, ["~> 4.0"])
91
+ s.add_dependency(%q<grape>.freeze, ["~> 1.3.0"])
92
+ s.add_dependency(%q<rails>.freeze, ["~> 6.0.0"])
93
+ s.add_dependency(%q<rspec-rails>.freeze, ["~> 3.8.2"])
94
+ s.add_dependency(%q<tezos_client>.freeze, ["~> 1.3.5"])
95
+ s.add_dependency(%q<bundler>.freeze, ["~> 2.2.14"])
96
+ s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
97
+ s.add_dependency(%q<pry>.freeze, [">= 0"])
98
+ s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
99
+ s.add_dependency(%q<faker>.freeze, [">= 0"])
100
+ end
101
+ else
102
+ s.add_dependency(%q<active_interaction>.freeze, ["~> 4.0"])
103
+ s.add_dependency(%q<grape>.freeze, ["~> 1.3.0"])
104
+ s.add_dependency(%q<rails>.freeze, ["~> 6.0.0"])
105
+ s.add_dependency(%q<rspec-rails>.freeze, ["~> 3.8.2"])
106
+ s.add_dependency(%q<tezos_client>.freeze, ["~> 1.3.5"])
107
+ s.add_dependency(%q<bundler>.freeze, ["~> 2.2.14"])
108
+ s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
109
+ s.add_dependency(%q<pry>.freeze, [">= 0"])
110
+ s.add_dependency(%q<rdoc>.freeze, ["~> 3.12"])
111
+ s.add_dependency(%q<faker>.freeze, [">= 0"])
112
+ end
113
+ end
114
+
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe MtkFramework::ActiveInteractionConcerns::Interruptable do
4
+ describe 'Interruptable' do
5
+ before do
6
+ application_interaction = Class.new(ActiveInteraction::Base) do
7
+ include MtkFramework::ActiveInteractionConcerns::Interruptable
8
+ end
9
+
10
+ stub_const('ApplicationInteraction', application_interaction)
11
+ end
12
+
13
+ describe '#run with interrupt_execute'
14
+ context 'adding error' do
15
+ subject { interrupted_interaction.run }
16
+
17
+ let(:interrupted_interaction) do
18
+ Class.new(ApplicationInteraction) do
19
+ def self.name
20
+ 'InterruptedInterraction'
21
+ end
22
+
23
+ def execute
24
+ errors.add :base, :invalid
25
+ interrupt_execute!
26
+ raise "I've not been interrupted"
27
+ end
28
+ end
29
+ end
30
+
31
+ it 'interrupts execution' do
32
+ expect { subject }.not_to raise_exception
33
+ end
34
+
35
+ it 'lets the interaction invalid with correct errors' do
36
+ expect(subject).to be_invalid
37
+ expect(subject.errors.full_messages).to include 'est invalide'
38
+ end
39
+ end
40
+
41
+ context 'passing error while interrupting' do
42
+ subject { interrupted_interaction.run }
43
+
44
+ let(:interrupted_interaction) do
45
+ Class.new(ApplicationInteraction) do
46
+ def self.name
47
+ 'InterruptedInterraction'
48
+ end
49
+
50
+ def execute
51
+ interrupt_execute! :base, :invalid
52
+ raise "I've not been interrupted"
53
+ end
54
+ end
55
+ end
56
+
57
+ it 'interrupts execution' do
58
+ expect { subject }.not_to raise_exception
59
+ end
60
+
61
+ it 'lets the interaction invalid with correct errors' do
62
+ expect(subject).to be_invalid
63
+ expect(subject.errors.full_messages).to include 'est invalide'
64
+ end
65
+ end
66
+
67
+ context 'passing errors while interrupting' do
68
+ before do
69
+ dummy_model = Class.new do
70
+ include ActiveModel::Model
71
+ attr_accessor :label
72
+
73
+ validates :label, presence: true
74
+ end
75
+
76
+ stub_const('DummyModel', dummy_model)
77
+ end
78
+ subject { interrupted_interaction.run }
79
+
80
+ let(:interrupted_interaction) do
81
+ Class.new(ApplicationInteraction) do
82
+ def self.name
83
+ 'InterruptedInterraction'
84
+ end
85
+
86
+ def execute
87
+ contract = DummyModel.new
88
+ contract.valid?
89
+ interrupt_execute! contract.errors
90
+
91
+ raise "I've not been interrupted"
92
+ end
93
+ end
94
+ end
95
+
96
+ it 'interrupts execution' do
97
+ expect { subject }.not_to raise_exception
98
+ end
99
+
100
+ it 'lets the interaction invalid with correct errors' do
101
+ expect(subject).to be_invalid
102
+ expect(subject.errors.full_messages).to include 'Label doit être rempli(e)'
103
+ end
104
+ end
105
+
106
+ context 'forgetting to add errors when interrupting' do
107
+ subject { interrupted_interaction.run }
108
+
109
+ let(:interrupted_interaction) do
110
+ Class.new(ApplicationInteraction) do
111
+ def self.name
112
+ 'InterruptedInterraction'
113
+ end
114
+
115
+ def execute
116
+ interrupt_execute!
117
+ raise "I've not been interrupted"
118
+ end
119
+ end
120
+ end
121
+
122
+ it 'raises and exception' do
123
+ expect { subject }.to raise_exception RuntimeError, 'interrupt_execute! called without error'
124
+ end
125
+ end
126
+ end
127
+ end