mongoid 7.2.0.rc1 → 7.3.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.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +45 -10
  5. data/lib/config/locales/en.yml +2 -2
  6. data/lib/mongoid/association/accessors.rb +1 -1
  7. data/lib/mongoid/association/constrainable.rb +1 -1
  8. data/lib/mongoid/association/depending.rb +4 -4
  9. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  10. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  11. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
  12. data/lib/mongoid/association/nested/many.rb +1 -1
  13. data/lib/mongoid/association/nested/one.rb +4 -2
  14. data/lib/mongoid/association/proxy.rb +6 -1
  15. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  16. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  17. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  18. data/lib/mongoid/association/referenced/has_one/buildable.rb +8 -0
  19. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  20. data/lib/mongoid/association/referenced/has_one/proxy.rb +6 -1
  21. data/lib/mongoid/attributes.rb +32 -14
  22. data/lib/mongoid/attributes/projector.rb +120 -0
  23. data/lib/mongoid/cacheable.rb +2 -2
  24. data/lib/mongoid/clients.rb +1 -1
  25. data/lib/mongoid/clients/factory.rb +22 -8
  26. data/lib/mongoid/config.rb +19 -2
  27. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  28. data/lib/mongoid/copyable.rb +6 -2
  29. data/lib/mongoid/criteria.rb +4 -5
  30. data/lib/mongoid/criteria/findable.rb +1 -1
  31. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  32. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  33. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  34. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  35. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  36. data/lib/mongoid/criteria/queryable/selector.rb +0 -4
  37. data/lib/mongoid/document.rb +4 -17
  38. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  39. data/lib/mongoid/evolvable.rb +1 -1
  40. data/lib/mongoid/extensions.rb +1 -0
  41. data/lib/mongoid/extensions/boolean.rb +1 -2
  42. data/lib/mongoid/extensions/false_class.rb +1 -1
  43. data/lib/mongoid/extensions/hash.rb +2 -2
  44. data/lib/mongoid/extensions/true_class.rb +1 -1
  45. data/lib/mongoid/fields.rb +46 -5
  46. data/lib/mongoid/inspectable.rb +1 -1
  47. data/lib/mongoid/interceptable.rb +3 -1
  48. data/lib/mongoid/matcher.rb +26 -43
  49. data/lib/mongoid/matcher/bits.rb +41 -0
  50. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  51. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  52. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  53. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  54. data/lib/mongoid/matcher/elem_match.rb +2 -1
  55. data/lib/mongoid/matcher/expression.rb +9 -14
  56. data/lib/mongoid/matcher/field_expression.rb +4 -5
  57. data/lib/mongoid/matcher/field_operator.rb +13 -11
  58. data/lib/mongoid/matcher/mod.rb +17 -0
  59. data/lib/mongoid/matcher/type.rb +99 -0
  60. data/lib/mongoid/persistable/deletable.rb +1 -2
  61. data/lib/mongoid/persistable/destroyable.rb +8 -2
  62. data/lib/mongoid/persistable/updatable.rb +27 -2
  63. data/lib/mongoid/query_cache.rb +35 -29
  64. data/lib/mongoid/reloadable.rb +5 -0
  65. data/lib/mongoid/selectable.rb +5 -7
  66. data/lib/mongoid/shardable.rb +21 -5
  67. data/lib/mongoid/stringified_symbol.rb +53 -0
  68. data/lib/mongoid/touchable.rb +23 -4
  69. data/lib/mongoid/version.rb +1 -1
  70. data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
  71. data/spec/README.md +19 -4
  72. data/spec/integration/app_spec.rb +175 -88
  73. data/spec/integration/associations/embeds_many_spec.rb +68 -0
  74. data/spec/integration/associations/embeds_one_spec.rb +24 -0
  75. data/spec/integration/associations/has_many_spec.rb +60 -0
  76. data/spec/integration/associations/has_one_spec.rb +108 -0
  77. data/spec/integration/callbacks_models.rb +49 -0
  78. data/spec/integration/callbacks_spec.rb +216 -0
  79. data/spec/integration/criteria/date_field_spec.rb +1 -1
  80. data/spec/integration/document_spec.rb +30 -0
  81. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  82. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  83. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  84. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  85. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  86. data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
  87. data/spec/integration/matcher_operator_data/gt_types.yml +63 -0
  88. data/spec/integration/matcher_operator_data/gte_types.yml +15 -0
  89. data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
  90. data/spec/integration/matcher_operator_data/in.yml +16 -0
  91. data/spec/integration/matcher_operator_data/lt_types.yml +15 -0
  92. data/spec/integration/matcher_operator_data/lte_types.yml +15 -0
  93. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  94. data/spec/integration/matcher_operator_data/ne_types.yml +15 -0
  95. data/spec/integration/matcher_operator_data/type.yml +70 -0
  96. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  97. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  98. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  99. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  100. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  101. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  102. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  103. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  104. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  105. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  106. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  107. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  108. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  109. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  110. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  111. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  112. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  113. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  114. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  115. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  116. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  117. data/spec/integration/stringified_symbol_field_spec.rb +190 -0
  118. data/spec/lite_spec_helper.rb +9 -7
  119. data/spec/mongoid/association/depending_spec.rb +391 -352
  120. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +50 -0
  121. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  122. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  123. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  124. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  125. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  126. data/spec/mongoid/association/referenced/has_many_models.rb +12 -0
  127. data/spec/mongoid/association/referenced/has_one_models.rb +20 -0
  128. data/spec/mongoid/association/referenced/has_one_spec.rb +1 -1
  129. data/spec/mongoid/atomic/paths_spec.rb +105 -12
  130. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  131. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  132. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  133. data/spec/mongoid/attributes_spec.rb +333 -0
  134. data/spec/mongoid/clients/factory_spec.rb +48 -0
  135. data/spec/mongoid/config_spec.rb +32 -0
  136. data/spec/mongoid/contextual/atomic_spec.rb +17 -4
  137. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  138. data/spec/mongoid/copyable_spec.rb +44 -17
  139. data/spec/mongoid/copyable_spec_models.rb +14 -0
  140. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  141. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  142. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  143. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  144. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +265 -24
  145. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  146. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  147. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  148. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  149. data/spec/mongoid/criteria_spec.rb +0 -275
  150. data/spec/mongoid/document_fields_spec.rb +26 -0
  151. data/spec/mongoid/document_spec.rb +13 -13
  152. data/spec/mongoid/equality_spec.rb +0 -1
  153. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  154. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  155. data/spec/mongoid/extensions/string_spec.rb +5 -5
  156. data/spec/mongoid/extensions/stringified_symbol_spec.rb +85 -0
  157. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  158. data/spec/mongoid/fields/localized_spec.rb +4 -4
  159. data/spec/mongoid/fields_spec.rb +4 -4
  160. data/spec/mongoid/inspectable_spec.rb +12 -4
  161. data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
  162. data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
  163. data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
  164. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  165. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  166. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  167. data/spec/mongoid/persistable/settable_spec.rb +30 -0
  168. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  169. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  170. data/spec/mongoid/reloadable_spec.rb +18 -1
  171. data/spec/mongoid/shardable_spec.rb +44 -0
  172. data/spec/mongoid/touchable_spec.rb +104 -16
  173. data/spec/mongoid/touchable_spec_models.rb +52 -0
  174. data/spec/mongoid/validatable_spec.rb +1 -1
  175. data/spec/shared/LICENSE +20 -0
  176. data/spec/shared/bin/get-mongodb-download-url +17 -0
  177. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  178. data/spec/shared/lib/mrss/cluster_config.rb +221 -0
  179. data/spec/shared/lib/mrss/constraints.rb +354 -0
  180. data/spec/shared/lib/mrss/docker_runner.rb +265 -0
  181. data/spec/shared/lib/mrss/lite_constraints.rb +191 -0
  182. data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
  183. data/spec/shared/lib/mrss/spec_organizer.rb +162 -0
  184. data/spec/shared/lib/mrss/utils.rb +15 -0
  185. data/spec/shared/share/Dockerfile.erb +231 -0
  186. data/spec/shared/shlib/distro.sh +73 -0
  187. data/spec/shared/shlib/server.sh +290 -0
  188. data/spec/shared/shlib/set_env.sh +128 -0
  189. data/spec/spec_helper.rb +7 -1
  190. data/spec/support/client_registry.rb +9 -0
  191. data/spec/support/constraints.rb +0 -226
  192. data/spec/support/models/bolt.rb +8 -0
  193. data/spec/support/models/customer.rb +11 -0
  194. data/spec/support/models/customer_address.rb +12 -0
  195. data/spec/support/models/dictionary.rb +6 -0
  196. data/spec/support/models/hole.rb +13 -0
  197. data/spec/support/models/mop.rb +9 -0
  198. data/spec/support/models/nut.rb +8 -0
  199. data/spec/support/models/order.rb +11 -0
  200. data/spec/support/models/person.rb +8 -0
  201. data/spec/support/models/sealer.rb +8 -0
  202. data/spec/support/models/series.rb +1 -0
  203. data/spec/support/models/shirt.rb +12 -0
  204. data/spec/support/models/spacer.rb +8 -0
  205. data/spec/support/models/threadlocker.rb +8 -0
  206. data/spec/support/models/washer.rb +8 -0
  207. data/spec/support/models/wiki_page.rb +1 -0
  208. data/spec/support/spec_config.rb +8 -0
  209. metadata +655 -507
  210. metadata.gz.sig +0 -0
  211. data/spec/support/child_process_helper.rb +0 -79
  212. data/spec/support/cluster_config.rb +0 -158
  213. data/spec/support/lite_constraints.rb +0 -22
  214. data/spec/support/spec_organizer.rb +0 -130
metadata.gz.sig CHANGED
Binary file
@@ -1,79 +0,0 @@
1
- # frozen_string_literal: true
2
- # encoding: utf-8
3
-
4
- gem 'childprocess'
5
- require 'childprocess'
6
- require 'tempfile'
7
-
8
- module ChildProcessHelper
9
- class SpawnError < StandardError; end
10
-
11
- module_function def call(cmd, env: nil, cwd: nil)
12
- process = ChildProcess.new(*cmd)
13
- process.io.inherit!
14
- if cwd
15
- process.cwd = cwd
16
- end
17
- if env
18
- env.each do |k, v|
19
- process.environment[k.to_s] = v
20
- end
21
- end
22
- process.start
23
- process.wait
24
- process
25
- end
26
-
27
- module_function def check_call(cmd, env: nil, cwd: nil)
28
- process = call(cmd, env: env, cwd: cwd)
29
- unless process.exit_code == 0
30
- raise "Failed to execute: #{cmd}"
31
- end
32
- end
33
-
34
- module_function def get_output(cmd, env: nil, cwd: nil)
35
- process = ChildProcess.new(*cmd)
36
- process.io.inherit!
37
- if cwd
38
- process.cwd = cwd
39
- end
40
- if env
41
- env.each do |k, v|
42
- process.environment[k.to_s] = v
43
- end
44
- end
45
-
46
- output = ''
47
- r, w = IO.pipe
48
-
49
- begin
50
- process.io.stdout = w
51
- process.start
52
- w.close
53
-
54
- thread = Thread.new do
55
- begin
56
- loop do
57
- output << r.readpartial(16384)
58
- end
59
- rescue EOFError
60
- end
61
- end
62
-
63
- process.wait
64
- thread.join
65
- ensure
66
- r.close
67
- end
68
-
69
- [process, output]
70
- end
71
-
72
- module_function def check_output(*args)
73
- process, output = get_output(*args)
74
- unless process.exit_code == 0
75
- raise "Failed to execute: #{args}"
76
- end
77
- output
78
- end
79
- end
@@ -1,158 +0,0 @@
1
- # frozen_string_literal: true
2
- # encoding: utf-8
3
-
4
- require 'singleton'
5
-
6
- class ClusterConfig
7
- include Singleton
8
-
9
- def single_server?
10
- determine_cluster_config
11
- @single_server
12
- end
13
-
14
- def replica_set_name
15
- determine_cluster_config
16
- @replica_set_name
17
- end
18
-
19
- def server_version
20
- determine_cluster_config
21
- @server_version
22
- end
23
-
24
- def short_server_version
25
- server_version.split('.')[0..1].join('.')
26
- end
27
-
28
- def fcv
29
- determine_cluster_config
30
- @fcv
31
- end
32
-
33
- # Per https://jira.mongodb.org/browse/SERVER-39052, working with FCV
34
- # in sharded topologies is annoying. Also, FCV doesn't exist in servers
35
- # less than 3.4. This method returns FCV on 3.4+ servers when in single
36
- # or RS topologies, and otherwise returns the major.minor server version.
37
- def fcv_ish
38
- if server_version >= '3.4' && topology != :sharded
39
- fcv
40
- else
41
- if short_server_version == '4.1'
42
- '4.2'
43
- else
44
- short_server_version
45
- end
46
- end
47
- end
48
-
49
- def primary_address
50
- determine_cluster_config
51
- @primary_address
52
- end
53
-
54
- def primary_address_str
55
- determine_cluster_config
56
- @primary_address.seed
57
- end
58
-
59
- def primary_address_host
60
- both = primary_address_str
61
- both.split(':').first
62
- end
63
-
64
- def primary_address_port
65
- both = primary_address_str
66
- both.split(':')[1] || 27017
67
- end
68
-
69
- def primary_description
70
- determine_cluster_config
71
- @primary_description
72
- end
73
-
74
- # Try running a command on the admin database to see if the mongod was
75
- # started with auth.
76
- def auth_enabled?
77
- if @auth_enabled.nil?
78
- @auth_enabled = begin
79
- basic_client.use(:admin).command(getCmdLineOpts: 1).first["argv"].include?("--auth")
80
- rescue => e
81
- e.message =~ /(not authorized)|(unauthorized)|(no users authenticated)|(requires authentication)/
82
- end
83
- end
84
- @auth_enabled
85
- end
86
-
87
- def topology
88
- determine_cluster_config
89
- @topology
90
- end
91
-
92
- def storage_engine
93
- @storage_engine ||= begin
94
- # 2.6 does not have wired tiger
95
- if short_server_version == '2.6'
96
- :mmapv1
97
- else
98
- client = ClientRegistry.instance.global_client('root_authorized')
99
- if topology == :sharded
100
- shards = client.use(:admin).command(listShards: 1).first
101
- shard = shards['shards'].first
102
- address_str = shard['host'].sub(/\A.*\//, '').sub(/,.*/, '')
103
- client = ClusterTools.instance.direct_client(address_str,
104
- SpecConfig.instance.test_options.merge(SpecConfig.instance.auth_options).merge(connect: :direct))
105
- end
106
- rv = client.use(:admin).command(serverStatus: 1).first
107
- rv = rv['storageEngine']['name']
108
- rv_map = {
109
- 'wiredTiger' => :wired_tiger,
110
- 'mmapv1' => :mmapv1,
111
- }
112
- rv_map[rv] || rv
113
- end
114
- end
115
- end
116
-
117
- private
118
-
119
- def determine_cluster_config
120
- return if @primary_address
121
-
122
- # Run all commands to figure out the cluster configuration from the same
123
- # client. This is somewhat wasteful when running a single test, but reduces
124
- # test runtime for the suite overall because all commands are sent on the
125
- # same connection rather than each command connecting to the cluster by
126
- # itself.
127
- client = Mongoid::Clients.default
128
-
129
- primary = client.cluster.next_primary
130
- @primary_address = primary.address
131
- @primary_description = primary.description
132
- @replica_set_name = client.cluster.topology.replica_set_name
133
-
134
- @topology ||= begin
135
- topology = client.cluster.topology.class.name.sub(/.*::/, '')
136
- topology = topology.gsub(/([A-Z])/) { |match| '_' + match.downcase }.sub(/\A_/, '')
137
- if topology =~ /\Areplica_set/
138
- topology = 'replica_set'
139
- end
140
- topology.to_sym
141
- end
142
-
143
- @single_server = client.cluster.send(:servers_list).length == 1
144
-
145
- @server_version = client.database.command(buildInfo: 1).first['version']
146
-
147
- if @topology != :sharded && short_server_version >= '3.4'
148
- rv = client.use(:admin).command(getParameter: 1, featureCompatibilityVersion: 1).first['featureCompatibilityVersion']
149
- @fcv = rv['version'] || rv
150
- end
151
- end
152
-
153
- def basic_client
154
- # Do not cache the result here so that if the client gets closed,
155
- # client registry reconnects it in subsequent tests
156
- ClientRegistry.instance.global_client('basic')
157
- end
158
- end
@@ -1,22 +0,0 @@
1
- module LiteConstraints
2
- # Constrain tests that use TimeoutInterrupt to MRI (and Unix)
3
- def only_mri
4
- before do
5
- unless SpecConfig.instance.mri?
6
- skip "MRI required, we have #{SpecConfig.instance.platform}"
7
- end
8
- end
9
- end
10
-
11
- # This is for marking tests that fail on jruby that should
12
- # in principle work (as opposed to being fundamentally incompatible
13
- # with jruby).
14
- # Often times these failures happen only in Evergreen.
15
- def fails_on_jruby
16
- before do
17
- unless SpecConfig.instance.mri?
18
- skip "Fails on jruby"
19
- end
20
- end
21
- end
22
- end
@@ -1,130 +0,0 @@
1
- require 'support/child_process_helper'
2
- require 'json'
3
-
4
- autoload :FileUtils, 'fileutils'
5
- autoload :Find, 'find'
6
-
7
- # Organizes and runs all of the tests in the test suite in batches.
8
- #
9
- # Organizing the tests in batches serves two purposes:
10
- #
11
- # 1. This allows running unit tests before integration tests, therefore
12
- # in theory revealing failures quicker on average.
13
- # 2. This allows running some tests that have high intermittent failure rate
14
- # in their own test process.
15
- #
16
- # This class aggregates RSpec results after the test runs.
17
- class SpecOrganizer
18
- CLASSIFIERS = [
19
- [%r,^mongoid/attribute,, :attributes],
20
- [%r,^mongoid/association/[or],, :associations_referenced],
21
- [%r,^mongoid/association,, :associations],
22
- [%r,^mongoid,, :unit],
23
- [%r,^integration,, :integration],
24
- [%r,^rails,, :rails],
25
- ]
26
-
27
- RUN_PRIORITY = %i(
28
- unit attributes associations_referenced associations
29
- integration rails
30
- )
31
-
32
- SPEC_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
33
- ROOT = File.expand_path(File.join(SPEC_ROOT, '..'))
34
- RSPEC_JSON_PATH = File.join(ROOT, 'tmp/rspec.json')
35
- RSPEC_ALL_JSON_PATH = File.join(ROOT, 'tmp/rspec-all.json')
36
-
37
- def run
38
- FileUtils.rm_f(RSPEC_ALL_JSON_PATH)
39
-
40
- buckets = {}
41
- Find.find(SPEC_ROOT) do |path|
42
- next unless File.file?(path)
43
- next unless path =~ /_spec\.rb\z/
44
- rel_path = path[(SPEC_ROOT.length + 1)..path.length]
45
-
46
- found = false
47
- CLASSIFIERS.each do |(regexp, category)|
48
- if regexp =~ rel_path
49
- buckets[category] ||= []
50
- buckets[category] << rel_path
51
- found = true
52
- break
53
- end
54
- end
55
-
56
- unless found
57
- buckets[nil] ||= []
58
- buckets[nil] << rel_path
59
- end
60
- end
61
-
62
- failed = []
63
-
64
- RUN_PRIORITY.each do |category|
65
- if files = buckets.delete(category)
66
- unless run_files(category, files)
67
- failed << category
68
- end
69
- end
70
- end
71
- if files = buckets.delete(nil)
72
- unless run_files('remaining', files)
73
- failed << 'remaining'
74
- end
75
- end
76
-
77
- unless buckets.empty?
78
- raise "Some buckets were not executed: #{buckets.keys.map(&:to_s).join(', ')}"
79
- end
80
-
81
- if failed.any?
82
- raise "The following buckets failed: #{failed.map(&:to_s).join(', ')}"
83
- end
84
- end
85
-
86
- def run_files(category, paths)
87
- paths = paths.map do |path|
88
- File.join('spec', path)
89
- end
90
-
91
- puts "Running #{category.to_s.gsub('_', ' ')} tests"
92
- FileUtils.rm_f(RSPEC_JSON_PATH)
93
- cmd = %w(rspec) + paths
94
-
95
- begin
96
- ChildProcessHelper.check_call(cmd)
97
- ensure
98
- if File.exist?(RSPEC_JSON_PATH)
99
- if File.exist?(RSPEC_ALL_JSON_PATH)
100
- merge_rspec_results
101
- else
102
- FileUtils.cp(RSPEC_JSON_PATH, RSPEC_ALL_JSON_PATH)
103
- end
104
- end
105
- end
106
-
107
- true
108
- rescue ChildProcessHelper::SpawnError
109
- false
110
- end
111
-
112
- def merge_rspec_results
113
- all = JSON.parse(File.read(RSPEC_ALL_JSON_PATH))
114
- new = JSON.parse(File.read(RSPEC_JSON_PATH))
115
- all['examples'] += new.delete('examples')
116
- new.delete('summary').each do |k, v|
117
- all['summary'][k] += v
118
- end
119
- new.delete('version')
120
- new.delete('summary_line')
121
- unless new.empty?
122
- raise "Unhandled rspec results keys: #{new.keys.join(', ')}"
123
- end
124
- # We do not merge summary lines, delete them from aggregated results
125
- all.delete('summary_line')
126
- File.open(RSPEC_ALL_JSON_PATH, 'w') do |f|
127
- f << JSON.dump(all)
128
- end
129
- end
130
- end