detour 0.0.1 → 0.0.2

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.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -1
  3. data/.travis.yml +6 -2
  4. data/Gemfile +5 -0
  5. data/README.md +41 -132
  6. data/Rake.md +108 -0
  7. data/Rakefile +21 -1
  8. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  9. data/app/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  10. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  11. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  12. data/app/assets/images/detour/.gitkeep +0 -0
  13. data/app/assets/javascripts/detour/application.js +16 -0
  14. data/app/assets/javascripts/detour/bootstrap.js +2006 -0
  15. data/app/assets/javascripts/detour/delete_feature.js +13 -0
  16. data/app/assets/javascripts/detour/delete_flag.js +13 -0
  17. data/app/assets/javascripts/detour/modals.js +3 -0
  18. data/app/assets/javascripts/detour/tooltips.js +3 -0
  19. data/app/assets/stylesheets/detour/application.css +14 -0
  20. data/app/assets/stylesheets/detour/bootstrap.css +7112 -0
  21. data/app/assets/stylesheets/detour/main.css +49 -0
  22. data/app/controllers/detour/application_controller.rb +12 -0
  23. data/app/controllers/detour/features_controller.rb +19 -0
  24. data/app/controllers/detour/flaggable_flags_controller.rb +90 -0
  25. data/app/controllers/detour/flags_controller.rb +18 -0
  26. data/app/helpers/detour/application_helper.rb +32 -0
  27. data/app/helpers/detour/flaggable_flags_helper.rb +5 -0
  28. data/app/helpers/detour/flags_helper.rb +7 -0
  29. data/app/models/detour/concerns/countable_flag.rb +19 -0
  30. data/app/models/detour/concerns/flag_actions.rb +141 -0
  31. data/app/models/detour/concerns/matchers.rb +73 -0
  32. data/app/models/detour/feature.rb +81 -0
  33. data/{lib → app/models}/detour/flag.rb +8 -2
  34. data/app/models/detour/flag_in_flag.rb +12 -0
  35. data/app/models/detour/group_flag.rb +13 -0
  36. data/{lib → app/models}/detour/opt_out_flag.rb +4 -2
  37. data/app/models/detour/percentage_flag.rb +9 -0
  38. data/app/views/detour/application/index.html.erb +0 -0
  39. data/app/views/detour/features/_errors.html.erb +11 -0
  40. data/app/views/detour/features/_success.html.erb +1 -0
  41. data/app/views/detour/features/error.js.erb +5 -0
  42. data/app/views/detour/features/success.js.erb +1 -0
  43. data/app/views/detour/flaggable_flags/_errors.html.erb +11 -0
  44. data/app/views/detour/flaggable_flags/_flaggable_flag.html.erb +11 -0
  45. data/app/views/detour/flaggable_flags/error.js.erb +5 -0
  46. data/app/views/detour/flaggable_flags/index.html.erb +34 -0
  47. data/app/views/detour/flaggable_flags/success.js.erb +1 -0
  48. data/app/views/detour/flags/_feature_form.html.erb +38 -0
  49. data/app/views/detour/flags/index.html.erb +76 -0
  50. data/app/views/detour/shared/_nav.html.erb +28 -0
  51. data/app/views/detour/shared/_spacer_cells.html.erb +3 -0
  52. data/app/views/layouts/detour/application.html.erb +29 -0
  53. data/config/routes.rb +16 -0
  54. data/detour.gemspec +15 -14
  55. data/lib/detour/acts_as_flaggable.rb +42 -3
  56. data/lib/detour/configuration.rb +35 -0
  57. data/lib/detour/engine.rb +5 -0
  58. data/lib/detour/flag_form.rb +87 -0
  59. data/lib/detour/version.rb +1 -1
  60. data/lib/detour.rb +10 -14
  61. data/lib/generators/templates/migration.rb +2 -0
  62. data/lib/tasks/detour.rake +16 -16
  63. data/script/rails +8 -0
  64. data/spec/controllers/detour/application_controller_spec.rb +15 -0
  65. data/spec/controllers/detour/features_controller_spec.rb +51 -0
  66. data/spec/controllers/detour/flaggable_flags_controller_spec.rb +100 -0
  67. data/spec/controllers/detour/flags_controller_spec.rb +77 -0
  68. data/spec/dummy/README.rdoc +261 -0
  69. data/spec/dummy/Rakefile +7 -0
  70. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  71. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  72. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  73. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  74. data/spec/dummy/app/mailers/.gitkeep +0 -0
  75. data/spec/dummy/app/models/.gitkeep +0 -0
  76. data/spec/dummy/app/models/user.rb +5 -0
  77. data/spec/dummy/app/models/widget.rb +5 -0
  78. data/spec/dummy/app/views/application/index.html.erb +22 -0
  79. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  80. data/spec/dummy/config/application.rb +65 -0
  81. data/spec/dummy/config/boot.rb +10 -0
  82. data/spec/dummy/config/database.yml +19 -0
  83. data/spec/dummy/config/environment.rb +5 -0
  84. data/spec/dummy/config/environments/development.rb +37 -0
  85. data/spec/dummy/config/environments/production.rb +67 -0
  86. data/spec/dummy/config/environments/test.rb +37 -0
  87. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/spec/dummy/config/initializers/detour.rb +36 -0
  89. data/spec/dummy/config/initializers/inflections.rb +15 -0
  90. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  91. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  92. data/spec/dummy/config/initializers/session_store.rb +8 -0
  93. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  94. data/spec/dummy/config/locales/en.yml +5 -0
  95. data/spec/dummy/config/routes.rb +4 -0
  96. data/spec/dummy/config.ru +4 -0
  97. data/spec/dummy/db/migrate/20131218015844_create_users.rb +10 -0
  98. data/spec/dummy/db/migrate/20131218023124_create_widgets.rb +9 -0
  99. data/spec/dummy/db/migrate/20131218055352_add_user_id_to_widgets.rb +6 -0
  100. data/spec/dummy/db/migrate/20131221052201_setup_detour.rb +32 -0
  101. data/spec/dummy/db/schema.rb +59 -0
  102. data/spec/dummy/db/seeds.rb +10 -0
  103. data/spec/dummy/lib/assets/.gitkeep +0 -0
  104. data/spec/dummy/log/.gitkeep +0 -0
  105. data/spec/dummy/public/404.html +26 -0
  106. data/spec/dummy/public/422.html +26 -0
  107. data/spec/dummy/public/500.html +25 -0
  108. data/spec/dummy/public/favicon.ico +0 -0
  109. data/spec/dummy/script/rails +6 -0
  110. data/spec/factories/feature.rb +5 -0
  111. data/spec/factories/flag_in_flag.rb +6 -0
  112. data/spec/factories/group_flag.rb +7 -0
  113. data/spec/factories/opt_out_flag.rb +6 -0
  114. data/spec/factories/percentage_flag.rb +7 -0
  115. data/spec/factories/user.rb +6 -0
  116. data/spec/factories/widget.rb +5 -0
  117. data/spec/features/features_spec.rb +70 -0
  118. data/spec/features/flag_in_flags_spec.rb +118 -0
  119. data/spec/features/group_flags_spec.rb +49 -0
  120. data/spec/features/home_page_spec.rb +11 -0
  121. data/spec/features/opt_out_flags_spec.rb +105 -0
  122. data/spec/features/percentage_flags_spec.rb +63 -0
  123. data/spec/integration/group_rollout_spec.rb +1 -1
  124. data/spec/lib/detour/acts_as_flaggable_spec.rb +45 -0
  125. data/spec/lib/detour/configuration_spec.rb +23 -0
  126. data/spec/lib/detour/flag_form_spec.rb +84 -0
  127. data/spec/lib/{active_record/rollout → detour}/flaggable_spec.rb +19 -19
  128. data/spec/lib/tasks/{detour_rake_spec.rb → detour_spec.rb} +54 -54
  129. data/spec/{lib/active_record/rollout → models/detour}/feature_spec.rb +93 -67
  130. data/spec/models/detour/flag_in_flag_spec.rb +38 -0
  131. data/spec/{lib/active_record/rollout → models/detour}/flag_spec.rb +1 -1
  132. data/spec/models/detour/opt_out_flag_spec.rb +38 -0
  133. data/spec/{lib/active_record/rollout → models/detour}/percentage_flag_spec.rb +1 -1
  134. data/spec/spec_helper.rb +41 -21
  135. data/spec/support/shared_contexts/rake.rb +4 -14
  136. metadata +278 -95
  137. data/lib/detour/feature.rb +0 -312
  138. data/lib/detour/flaggable_flag.rb +0 -10
  139. data/lib/detour/group_flag.rb +0 -8
  140. data/lib/detour/percentage_flag.rb +0 -11
  141. data/spec/lib/active_record/rollout/acts_as_flaggable_spec.rb +0 -31
  142. data/spec/lib/active_record/rollout/flaggable_flag_spec.rb +0 -9
  143. data/spec/lib/active_record/rollout/opt_out_flag_spec.rb +0 -9
  144. data/spec/support/schema.rb +0 -13
  145. /data/lib/generators/{active_record_rollout_generator.rb → detour_generator.rb} +0 -0
  146. /data/lib/generators/templates/{active_record_rollout.rb → detour.rb} +0 -0
  147. /data/spec/{lib/active_record/rollout → models/detour}/group_flag_spec.rb +0 -0
@@ -1,312 +0,0 @@
1
- # Represents an individual feature that may be rolled out to a set of records
2
- # via individual flags, percentages, or defined groups.
3
- class Detour::Feature < ActiveRecord::Base
4
- # A hash representing the groups that have been defined.
5
- @defined_groups = {}
6
-
7
- # Directories to grep for feature tests
8
- @grep_dirs = []
9
-
10
- self.table_name = :detour_features
11
-
12
- has_many :flaggable_flags
13
- has_many :group_flags
14
- has_many :percentage_flags
15
- has_many :opt_out_flags
16
- has_many :flags, dependent: :destroy
17
-
18
- validates :name, presence: true, uniqueness: true
19
-
20
- attr_accessible :name
21
-
22
- # Returns an instance variable intended to hold an array of the lines of code
23
- # that this feature appears on.
24
- #
25
- # @return [Array<String>] The lines that this rollout appears on (if
26
- # {Detour::Feature.all_with_lines} has already been called).
27
- def lines
28
- @lines ||= []
29
- end
30
-
31
- # Determines whether or not the given instance has had the feature rolled out
32
- # to it either via direct flagging-in, percentage, or by group membership.
33
- #
34
- # @example
35
- # feature.match?(current_user)
36
- #
37
- # @param [ActiveRecord::Base] instance A record to be tested for feature
38
- # rollout.
39
- #
40
- # @return Whether or not the given instance has the feature rolled out to it.
41
- def match?(instance)
42
- match_id?(instance) || match_percentage?(instance) || match_groups?(instance)
43
- end
44
-
45
- # Determines whether or not the given instance has had the feature rolled out
46
- # to it via direct flagging-in.
47
- #
48
- # @example
49
- # feature.match_id?(current_user)
50
- #
51
- # @param [ActiveRecord::Base] instance A record to be tested for feature
52
- # rollout.
53
- #
54
- # @return Whether or not the given instance has the feature rolled out to it
55
- # via direct flagging-in.
56
- def match_id?(instance)
57
- flaggable_flags.where(flaggable_type: instance.class.to_s, flaggable_id: instance.id).any?
58
- end
59
-
60
- # Determines whether or not the given instance has had the feature rolled out
61
- # to it via percentage.
62
- #
63
- # @example
64
- # feature.match_percentage?(current_user)
65
- #
66
- # @param [ActiveRecord::Base] instance A record to be tested for feature
67
- # rollout.
68
- #
69
- # @return Whether or not the given instance has the feature rolled out to it
70
- # via direct percentage.
71
- def match_percentage?(instance)
72
- flag = percentage_flags.find(:first, conditions: ["flaggable_type = ?", instance.class.to_s])
73
- percentage = flag ? flag.percentage : 0
74
-
75
- instance.id % 10 < percentage / 10
76
- end
77
-
78
- # Determines whether or not the given instance has had the feature rolled out
79
- # to it via group membership.
80
- #
81
- # @example
82
- # feature.match_groups?(current_user)
83
- #
84
- # @param [ActiveRecord::Base] instance A record to be tested for feature
85
- # rollout.
86
- #
87
- # @return Whether or not the given instance has the feature rolled out to it
88
- # via direct group membership.
89
- def match_groups?(instance)
90
- klass = instance.class.to_s
91
-
92
- return unless self.class.defined_groups[klass]
93
-
94
- group_names = group_flags.find_all_by_flaggable_type(klass).collect(&:group_name)
95
-
96
- self.class.defined_groups[klass].collect { |group_name, block|
97
- block.call(instance) if group_names.include? group_name
98
- }.any?
99
- end
100
-
101
- class << self
102
- # Returns the defined groups.
103
- def defined_groups
104
- @defined_groups
105
- end
106
-
107
- # Returns the default flaggable class.
108
- def default_flaggable_class_name
109
- @default_flaggable_class_name
110
- end
111
-
112
- # Sets the default flaggable class.
113
- def default_flaggable_class_name=(klass)
114
- @default_flaggable_class_name = klass
115
- end
116
-
117
- # A list of directories to search through when finding feature checks.
118
- def grep_dirs
119
- @grep_dirs
120
- end
121
-
122
- # Set the list of directories to search through when finding feature checks.
123
- def grep_dirs=(grep_dirs)
124
- @grep_dirs = grep_dirs
125
- end
126
-
127
- # Return an array of both every feature in the database as well as every
128
- # feature that is checked for in `@grep_dirs`. Features that are checked
129
- # for but not persisted will be returned as unpersisted instances of this
130
- # class. Each instance returned will have its `@lines` set to an array
131
- # containing every line in `@grep_dirs` where it is checked for.
132
- #
133
- # @return [Array<Detour::Feature>] Every persisted and
134
- # checked-for feature.
135
- def all_with_lines
136
- obj = all.each_with_object({}) { |feature, obj| obj[feature.name] = feature }
137
-
138
- Dir[*@grep_dirs].each do |path|
139
- next if File.directory? path
140
-
141
- File.open path do |file|
142
- file.each_line.with_index(1) do |line, i|
143
- line.scan(/\.has_feature\?\s*\(*:(\w+)/).each do |match|
144
- match = match[0]
145
- obj[match] ||= find_or_initialize_by_name(match)
146
- obj[match].lines << "#{path}#L#{i}"
147
- end
148
- end
149
- end
150
- end
151
-
152
- obj.values
153
- end
154
-
155
- # Add a record to the given feature. If the feature is not found, an
156
- # ActiveRecord::RecordNotFound will be raised.
157
- #
158
- # @example
159
- # Detour::Feature.add_record_to_feature user, :new_ui
160
- #
161
- # @param [ActiveRecord::Base] record A record to add the feature to.
162
- # @param [String,Symbol] feature_name The feature to be added to the record.
163
- #
164
- # @return [Detour::Flag] The
165
- # {Detour::Flag Flag} created.
166
- def add_record_to_feature(record, feature_name)
167
- feature = find_by_name!(feature_name)
168
- feature.flaggable_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).first_or_create!
169
- end
170
-
171
- # Remove a record from the given feature. If the feature is not found, an
172
- # ActiveRecord::RecordNotFound will be raised.
173
- #
174
- # @example
175
- # Detour::Feature.remove_record_from_feature user, :new_ui
176
- #
177
- # @param [ActiveRecord::Base] record A record to remove the feature from.
178
- # @param [String,Symbol] feature_name The feature to be removed from the
179
- # record.
180
- def remove_record_from_feature(record, feature_name)
181
- feature = find_by_name!(feature_name)
182
- feature.flaggable_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).destroy_all
183
- end
184
-
185
- # Opt the given record out of a feature. If the feature is not found, an
186
- # ActiveRecord::RecordNotFound will be raised. An opt out ensures that no
187
- # matter what, `record.rollout?(:rollout)` will always return false for any
188
- # opted-out-of features.
189
- #
190
- # @param [ActiveRecord::Base] record A record to opt out of the feature.
191
- # @param [String,Symbol] feature_name The feature to be opted out of.
192
- #
193
- # @example
194
- # Detour::Feature.opt_record_out_of_feature user, :new_ui
195
- #
196
- # @return [Detour::OptOut] The
197
- # {Detour::OptOut OptOut} created.
198
- def opt_record_out_of_feature(record, feature_name)
199
- feature = find_by_name!(feature_name)
200
- feature.opt_out_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).first_or_create!
201
- end
202
-
203
- # Remove any opt out for the given record out of a feature. If the feature
204
- # is not found, an ActiveRecord::RecordNotFound will be raised.
205
- #
206
- # @example
207
- # Detour::Feature.un_opt_record_out_of_feature user, :new_ui
208
- #
209
- # @param [ActiveRecord::Base] record A record to un-opt-out of the feature.
210
- # @param [String,Symbol] feature_name The feature to be un-opted-out of.
211
- def un_opt_record_out_of_feature(record, feature_name)
212
- feature = find_by_name!(feature_name)
213
- feature.opt_out_flags.where(flaggable_type: record.class.to_s, flaggable_id: record.id).destroy_all
214
- end
215
-
216
- # Add a group to the given feature. If the feature is not found, an
217
- # ActiveRecord::RecordNotFound will be raised.
218
- #
219
- # @example
220
- # Detour::Feature.add_group_to_feature "User", "admin", :delete_records
221
- #
222
- # @param [String] flaggable_type The class (as a string) that the group
223
- # should be associated with.
224
- # @param [String] group_name The name of the group to have the feature
225
- # added to it.
226
- # @param [String,Symbol] feature_name The feature to be added to the group.
227
- #
228
- # @return [Detour::Flag] The
229
- # {Detour::Flag Flag} created.
230
- def add_group_to_feature(flaggable_type, group_name, feature_name)
231
- feature = find_by_name!(feature_name)
232
- feature.group_flags.where(flaggable_type: flaggable_type, group_name: group_name).first_or_create!
233
- end
234
-
235
- # Remove a group from agiven feature. If the feature is not found, an
236
- # ActiveRecord::RecordNotFound will be raised.
237
- #
238
- # @example
239
- # Detour::Feature.remove_group_from_feature "User", "admin", :delete_records
240
- #
241
- # @param [String] flaggable_type The class (as a string) that the group should
242
- # be removed from.
243
- # @param [String] group_name The name of the group to have the feature
244
- # removed from it.
245
- # @param [String,Symbol] feature_name The feature to be removed from the
246
- # group.
247
- def remove_group_from_feature(flaggable_type, group_name, feature_name)
248
- feature = find_by_name!(feature_name)
249
- feature.group_flags.where(flaggable_type: flaggable_type, group_name: group_name).destroy_all
250
- end
251
-
252
- # Add a percentage of records to the given feature. If the feature is not
253
- # found, an ActiveRecord::RecordNotFound will be raised.
254
- #
255
- # @example
256
- # Detour::Feature.add_percentage_to_feature "User", 75, :delete_records
257
- #
258
- # @param [String] flaggable_type The class (as a string) that the percetnage
259
- # should be associated with.
260
- # @param [Integer] percentage The percentage of `flaggable_type` records
261
- # that the feature will be available for.
262
- # @param [String,Symbol] feature_name The feature to be added to the
263
- # percentage of records.
264
- #
265
- # @return [Detour::Flag] The
266
- # {Detour::Flag Flag} created.
267
- def add_percentage_to_feature(flaggable_type, percentage, feature_name)
268
- feature = find_by_name!(feature_name)
269
-
270
- flag = feature.percentage_flags.where(flaggable_type: flaggable_type).first_or_initialize
271
- flag.update_attributes!(percentage: percentage)
272
- end
273
-
274
- # Remove any percentage flags for the given feature. If the feature is not
275
- # found, an ActiveRecord::RecordNotFound will be raised.
276
- #
277
- # @example
278
- # Detour::Feature.remove_percentage_from_feature "User", delete_records
279
- #
280
- # @param [String] flaggable_type The class (as a string) that the percetnage
281
- # should be removed from.
282
- # @param [String,Symbol] feature_name The feature to have the percentage
283
- # flag removed from.
284
- def remove_percentage_from_feature(flaggable_type, feature_name)
285
- feature = find_by_name!(feature_name)
286
- feature.percentage_flags.where(flaggable_type: flaggable_type).destroy_all
287
- end
288
-
289
- # Allows for methods of the form `define_user_group` that call the private
290
- # method `define_group_for_class`. A new group for any `User` records will
291
- # be created that rollouts can be attached to.
292
- #
293
- # @example
294
- # Detour::Feature.define_user_group :admins do |user|
295
- # user.admin?
296
- # end
297
- def method_missing(method, *args, &block)
298
- if /^define_(?<klass>[a-z0-9_]+)_group/ =~ method
299
- define_group_for_class(klass.classify, args[0], &block)
300
- else
301
- super
302
- end
303
- end
304
-
305
- private
306
-
307
- def define_group_for_class(klass, group_name, &block)
308
- @defined_groups[klass] ||= {}
309
- @defined_groups[klass][group_name] = block
310
- end
311
- end
312
- end
@@ -1,10 +0,0 @@
1
- # An individual record of a certain type may be flagged into a feature with
2
- # this class.
3
- class Detour::FlaggableFlag < Detour::Flag
4
- belongs_to :flaggable, polymorphic: true
5
-
6
- validates :flaggable_id, presence: true
7
- validates :feature_id, uniqueness: { scope: [:flaggable_type, :flaggable_id] }
8
-
9
- attr_accessible :flaggable
10
- end
@@ -1,8 +0,0 @@
1
- # A group of flaggable records of a given class may be flagged into a feature
2
- # with this class.
3
- class Detour::GroupFlag < Detour::Flag
4
- validates :group_name, presence: true
5
-
6
- attr_accessible :group_name
7
- validates :feature_id, uniqueness: { scope: [:flaggable_type, :group_name] }
8
- end
@@ -1,11 +0,0 @@
1
- # A percentage of flaggable records of a given class may be flagged into a feature
2
- # with this class.
3
- class Detour::PercentageFlag < Detour::Flag
4
- validates :percentage,
5
- presence: true,
6
- numericality: { greater_than: 0, less_than_or_equal_to: 100 }
7
-
8
- validates :feature_id, uniqueness: { scope: :flaggable_type }
9
-
10
- attr_accessible :percentage
11
- end
@@ -1,31 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Detour::ActsAsFlaggable do
4
- subject { User.new }
5
-
6
- it { should have_many :flaggable_flags }
7
- it { should have_many :opt_out_flags }
8
- it { should have_many(:features).through(:flaggable_flags) }
9
-
10
- it "includes Detour::Flaggable" do
11
- subject.class.ancestors.should include Detour::Flaggable
12
- end
13
-
14
- describe "#acts_as_flaggable" do
15
- context "when given a :find_by parameter" do
16
- class Foo < ActiveRecord::Base
17
- acts_as_flaggable find_by: :email
18
- end
19
-
20
- it "sets the appropriate class variable on the class" do
21
- Foo.instance_variable_get("@detour_flaggable_find_by").should eq :email
22
- end
23
- end
24
-
25
- context "when not given a :find_by parameter" do
26
- it "uses the default :id value for flaggable_find_by" do
27
- User.instance_variable_get("@detour_flaggable_find_by").should eq :id
28
- end
29
- end
30
- end
31
- end
@@ -1,9 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Detour::FlaggableFlag do
4
- it { should be_a Detour::Flag }
5
- it { should belong_to :flaggable }
6
- it { should validate_presence_of :flaggable_id }
7
- it { should allow_mass_assignment_of :flaggable }
8
- it { should validate_uniqueness_of :feature_id }
9
- end
@@ -1,9 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Detour::OptOutFlag do
4
- it { should be_a Detour::Flag }
5
- it { should belong_to :flaggable }
6
- it { should validate_presence_of :flaggable_id }
7
- it { should allow_mass_assignment_of :flaggable}
8
- it { should validate_uniqueness_of :feature_id }
9
- end
@@ -1,13 +0,0 @@
1
- ActiveRecord::Schema.define do
2
- self.verbose = false
3
-
4
- create_table :users, force: true do |t|
5
- t.string :name
6
- t.timestamps
7
- end
8
-
9
- create_table :organizations, force: true do |t|
10
- t.string :name
11
- t.timestamps
12
- end
13
- end