hypothesis-specs 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ceb7e5a7e7c564c26e971e6e5aacce7599ef8c3b810b879141c8ea9e97f2b7f
4
- data.tar.gz: f5de9db4207eea15c790475cc43540faf30d69e5587be623dedf6b954b556f04
3
+ metadata.gz: 77c742dcfc65dfcab8e0eac24498eff24b10461abf17f502961ac9fc30bd1810
4
+ data.tar.gz: 6a73fbe38f860e2b2b9f9fd68cde16a33657eb05d0117a3a2e78ab5dfa8e2226
5
5
  SHA512:
6
- metadata.gz: 79c6389fefaca46af95d01f1b285a6e2cc1f9dc30c185da5efd6363e65b00f00794a9ca21ee5b551e6bb06df235c10b00777b0a8d27b3c09d8e10cdf834944ff
7
- data.tar.gz: 5129459dbc559cb3b08354e3c0e36f691a2f9aea7f58dacf01a69760bcd9d6b06d7a7e905ac19b768b31d285ce30a7c587ab8dab54a546eb600e5e14b42d069c
6
+ metadata.gz: 8b0da0f3b0820c93b32af05eb040fd6d88e86748a8fd99c38609a204944a84b773f2e53bf757c103c0c0f5a6e66097fd65c839ca95c0ec8360c9ac1ae1814153
7
+ data.tar.gz: 0a2d28a1fbc0e3b87fa96452a6028d0f0f8e00d223eb1440f1daf86eb3e40ec33c25c21222c9a2fc585d053dcca63e9de6d9d0e96ca7eb277e452e0baa77c2ac
@@ -1,3 +1,9 @@
1
+ # Hypothesis for Ruby 0.3.0 (2021-01-08)
2
+
3
+ This release converts Hypothesis for Ruby to use [RuTie](https://github.com/danielpclark/rutie)
4
+ instead of the deprecated [Helix](https://github.com/tildeio/helix), restoring compatibility
5
+ with recent versions of Rust. Thanks to Alex Weisberger for taking this on!
6
+
1
7
  # Hypothesis for Ruby 0.2.0 (2018-10-24)
2
8
 
3
9
  This release adds an example database to Hypothesis for Ruby. This means that when a test fails,
data/Cargo.toml CHANGED
@@ -1,12 +1,14 @@
1
1
  [package]
2
2
  name = "hypothesis-ruby"
3
3
  version = "0.1.0"
4
- authors = ["David R. MacIver <david@drmaciver.com>"]
4
+ authors = ["David R. MacIver <david@drmaciver.com>", "Alex Wiesberger <alex.m.weisberger@gmail.com>"]
5
5
 
6
6
  [lib]
7
+ name="hypothesis_ruby_core"
7
8
  crate-type = ["cdylib"]
8
9
 
9
10
  [dependencies]
10
- helix = '0.7.5'
11
+ rutie = {version="0.8.1"}
12
+ lazy_static = "1.4.0"
11
13
  rand = '0.3'
12
14
  conjecture = '0.4.0'
@@ -1,7 +1,7 @@
1
1
  Copyright (c) 2018, David R. MacIver
2
2
 
3
3
  All code in this repository except where explicitly noted otherwise is released
4
- under the Mozilla Public License v 2.0. You can obtain a copy at http://mozilla.org/MPL/2.0/.
4
+ under the Mozilla Public License v 2.0. You can obtain a copy at https://mozilla.org/MPL/2.0/.
5
5
 
6
6
  Some code in this repository may come from other projects. Where applicable, the
7
7
  original copyright and license are noted and any modifications made are released
@@ -32,7 +32,7 @@ RSpec.describe "removing an element from a list" do
32
32
 
33
33
  values.delete_at(values.index(to_remove))
34
34
 
35
- # Will fail if the value ws duplicated in the list.
35
+ # Will fail if the value was duplicated in the list.
36
36
  expect(values.include?(to_remove)).to be false
37
37
 
38
38
  end
data/Rakefile CHANGED
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rubygems'
4
- require 'helix_runtime/build_task'
5
4
  require 'date'
6
5
  require 'open3'
7
6
 
7
+ task :build do
8
+ system('cargo build --release')
9
+ end
10
+
8
11
  begin
9
12
  require 'rspec/core/rake_task'
10
13
  RSpec::Core::RakeTask.new(:spec)
@@ -20,8 +23,6 @@ begin
20
23
  rescue LoadError
21
24
  end
22
25
 
23
- HelixRuntime::BuildTask.new
24
-
25
26
  def rubocop(fix:)
26
27
  sh "bundle exec rubocop #{'-a' if fix} lib spec minitests " \
27
28
  'Rakefile hypothesis-specs.gemspec'
@@ -19,6 +19,23 @@ require_relative 'hypothesis/world'
19
19
  module Hypothesis
20
20
  # @!visibility private
21
21
  HYPOTHESIS_LOCATION = File.dirname(__FILE__)
22
+ # rubocop:disable ClassVars
23
+ @@setup_called = false
24
+ # rubocop:enable RuleByName
25
+
26
+ def self.setup_called
27
+ @@setup_called == true
28
+ end
29
+
30
+ def self.included(*)
31
+ if setup_called == false
32
+ Rutie.new(:hypothesis_ruby_core).init(
33
+ 'Init_rutie_hypothesis_core',
34
+ __dir__
35
+ )
36
+ end
37
+ @@setup_called = true
38
+ end
22
39
 
23
40
  # @!visibility private
24
41
  def hypothesis_stable_identifier
@@ -188,6 +205,7 @@ module Hypothesis
188
205
  unless World.current_engine.nil?
189
206
  raise UsageError, 'Cannot nest hypothesis calls'
190
207
  end
208
+
191
209
  begin
192
210
  World.current_engine = Engine.new(
193
211
  hypothesis_stable_identifier,
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'helix_runtime'
4
-
5
- require_relative '../hypothesis-ruby/native'
3
+ require 'rutie'
6
4
 
7
5
  require 'rspec/expectations'
8
6
 
data/src/lib.rs CHANGED
@@ -1,190 +1,469 @@
1
- // "Bridging" root code that exists exclusively to provide
2
- // a ruby -> Hypothesis engine binding.
3
-
4
- #![recursion_limit = "256"]
5
- #![deny(warnings, missing_debug_implementations)]
6
-
7
- extern crate core;
8
1
  #[macro_use]
9
- extern crate helix;
10
- extern crate rand;
2
+ extern crate rutie;
3
+ #[macro_use]
4
+ extern crate lazy_static;
11
5
  extern crate conjecture;
12
6
 
13
7
  use std::mem;
14
8
 
9
+ use rutie::{AnyException, AnyObject, Boolean, Class, Float, Integer, NilClass, Object, RString, VM};
10
+
15
11
  use conjecture::data::{DataSource, Status, TestResult};
16
- use conjecture::distributions::Repeat;
12
+ use conjecture::database::{BoxedDatabase, DirectoryDatabase, NoDatabase};
17
13
  use conjecture::distributions;
14
+ use conjecture::distributions::Repeat;
18
15
  use conjecture::engine::Engine;
19
- use conjecture::database::{BoxedDatabase, NoDatabase, DirectoryDatabase};
20
16
 
21
- ruby! {
22
- class HypothesisCoreDataSource {
23
- struct {
24
- source: Option<DataSource>,
17
+ pub struct HypothesisCoreDataSourceStruct {
18
+ source: Option<DataSource>,
19
+ }
20
+
21
+ impl HypothesisCoreDataSourceStruct {
22
+ fn new(engine: &mut HypothesisCoreEngineStruct) -> HypothesisCoreDataSourceStruct {
23
+ HypothesisCoreDataSourceStruct {
24
+ source: mem::take(&mut engine.pending),
25
+ }
25
26
  }
26
27
 
27
- def initialize(helix, engine: &mut HypothesisCoreEngine){
28
- let mut result = HypothesisCoreDataSource{helix, source: None};
29
- mem::swap(&mut result.source, &mut engine.pending);
30
- return result;
28
+ fn start_draw(&mut self) {
29
+ if let Some(ref mut source) = self.source {
30
+ source.start_draw();
31
+ }
31
32
  }
32
33
 
33
- def start_draw(&mut self){
34
- if let &mut Some(ref mut source) = &mut self.source {
35
- source.start_draw();
36
- }
34
+ fn stop_draw(&mut self) {
35
+ if let Some(ref mut source) = self.source {
36
+ source.stop_draw();
37
+ }
37
38
  }
39
+ }
38
40
 
39
- def stop_draw(&mut self){
40
- if let &mut Some(ref mut source) = &mut self.source {
41
- source.stop_draw();
42
- }
41
+ wrappable_struct!(
42
+ HypothesisCoreDataSourceStruct,
43
+ HypothesisCoreDataSourceStructWrapper,
44
+ HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER
45
+ );
46
+
47
+ class!(HypothesisCoreDataSource);
48
+
49
+ methods!(
50
+ HypothesisCoreDataSource,
51
+ itself,
52
+ fn ruby_hypothesis_core_data_source_start_draw() -> NilClass {
53
+ itself
54
+ .get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER)
55
+ .start_draw();
56
+
57
+ NilClass::new()
43
58
  }
44
- }
59
+ fn ruby_hypothesis_core_data_source_stop_draw() -> NilClass {
60
+ itself
61
+ .get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER)
62
+ .stop_draw();
45
63
 
46
- class HypothesisCoreEngine {
47
- struct {
48
- engine: Engine,
49
- pending: Option<DataSource>,
50
- interesting_examples: Vec<TestResult>,
64
+ NilClass::new()
51
65
  }
66
+ );
67
+
68
+ pub struct HypothesisCoreEngineStruct {
69
+ engine: Engine,
70
+ pending: Option<DataSource>,
71
+ interesting_examples: Vec<TestResult>,
72
+ }
52
73
 
53
- def initialize(helix, name: String, database_path: Option<String>, seed: u64, max_examples: u64){
54
- let xs: [u32; 2] = [seed as u32, (seed >> 32) as u32];
55
- let db: BoxedDatabase = match database_path {
56
- None => Box::new(NoDatabase),
57
- Some(path) => Box::new(DirectoryDatabase::new(path)),
58
- };
74
+ impl HypothesisCoreEngineStruct {
75
+ fn new(
76
+ name: String,
77
+ database_path: Option<String>,
78
+ seed: u64,
79
+ max_examples: u64,
80
+ ) -> HypothesisCoreEngineStruct {
81
+ let xs: [u32; 2] = [seed as u32, (seed >> 32) as u32];
82
+ let db: BoxedDatabase = match database_path {
83
+ None => Box::new(NoDatabase),
84
+ Some(path) => Box::new(DirectoryDatabase::new(path)),
85
+ };
59
86
 
60
- HypothesisCoreEngine{
61
- helix,
62
- engine: Engine::new(name, max_examples, &xs, db),
63
- pending: None,
64
- interesting_examples: Vec::new(),
65
- }
87
+ HypothesisCoreEngineStruct {
88
+ engine: Engine::new(name, max_examples, &xs, db),
89
+ pending: None,
90
+ interesting_examples: Vec::new(),
91
+ }
66
92
  }
67
93
 
68
- def new_source(&mut self) -> Option<HypothesisCoreDataSource> {
69
- match self.engine.next_source() {
70
- None => {
71
- self.interesting_examples = self.engine.list_minimized_examples();
72
- None
73
- },
74
- Some(source) => {
75
- self.pending = Some(source);
76
- Some(HypothesisCoreDataSource::new(self))
77
- },
78
- }
94
+ fn new_source(&mut self) -> Option<HypothesisCoreDataSourceStruct> {
95
+ match self.engine.next_source() {
96
+ None => {
97
+ self.interesting_examples = self.engine.list_minimized_examples();
98
+ None
99
+ }
100
+ Some(source) => {
101
+ self.pending = Some(source);
102
+ Some(HypothesisCoreDataSourceStruct::new(self))
103
+ }
104
+ }
79
105
  }
80
106
 
81
- def count_failing_examples(&self) -> usize {
82
- self.interesting_examples.len()
107
+ fn count_failing_examples(&self) -> usize {
108
+ self.interesting_examples.len()
83
109
  }
84
110
 
85
- def failing_example(&mut self, i: usize) -> HypothesisCoreDataSource {
86
- self.pending = Some(
87
- DataSource::from_vec(self.interesting_examples[i].record.clone())
88
- );
89
- HypothesisCoreDataSource::new(self)
111
+ fn failing_example(&mut self, i: usize) -> HypothesisCoreDataSourceStruct {
112
+ self.pending = Some(DataSource::from_vec(
113
+ self.interesting_examples[i].record.clone(),
114
+ ));
115
+ HypothesisCoreDataSourceStruct::new(self)
90
116
  }
91
117
 
92
- def was_unsatisfiable(&mut self) -> bool {
93
- self.engine.was_unsatisfiable()
118
+ fn was_unsatisfiable(&mut self) -> bool {
119
+ self.engine.was_unsatisfiable()
94
120
  }
95
121
 
96
- def finish_overflow(&mut self, child: &mut HypothesisCoreDataSource){
97
- mark_child_status(&mut self.engine, child, Status::Overflow);
122
+ fn finish_overflow(&mut self, child: &mut HypothesisCoreDataSourceStruct) {
123
+ mark_child_status(&mut self.engine, child, Status::Overflow);
98
124
  }
99
125
 
100
- def finish_invalid(&mut self, child: &mut HypothesisCoreDataSource){
101
- mark_child_status(&mut self.engine, child, Status::Invalid);
126
+ fn finish_valid(&mut self, child: &mut HypothesisCoreDataSourceStruct) {
127
+ mark_child_status(&mut self.engine, child, Status::Valid);
102
128
  }
103
129
 
104
- def finish_interesting(&mut self, child: &mut HypothesisCoreDataSource, label: u64){
105
- mark_child_status(&mut self.engine, child, Status::Interesting(label));
130
+ fn finish_invalid(&mut self, child: &mut HypothesisCoreDataSourceStruct) {
131
+ mark_child_status(&mut self.engine, child, Status::Invalid);
106
132
  }
107
133
 
108
- def finish_valid(&mut self, child: &mut HypothesisCoreDataSource){
109
- mark_child_status(&mut self.engine, child, Status::Valid);
134
+ fn finish_interesting(&mut self, child: &mut HypothesisCoreDataSourceStruct, label: u64) {
135
+ mark_child_status(&mut self.engine, child, Status::Interesting(label));
110
136
  }
111
- }
137
+ }
138
+
139
+ wrappable_struct!(
140
+ HypothesisCoreEngineStruct,
141
+ HypothesisCoreEngineStructWrapper,
142
+ HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER
143
+ );
144
+
145
+ class!(HypothesisCoreEngine);
146
+
147
+ methods!(
148
+ HypothesisCoreEngine,
149
+ itself,
150
+ fn ruby_hypothesis_core_engine_new(
151
+ name: RString,
152
+ database_path: RString,
153
+ seed: Integer,
154
+ max_example: Integer
155
+ ) -> AnyObject {
156
+ let core_engine = HypothesisCoreEngineStruct::new(
157
+ safe_access(name).to_string(),
158
+ database_path.ok().map(|p| p.to_string()),
159
+ safe_access(seed).to_u64(),
160
+ safe_access(max_example).to_u64(),
161
+ );
112
162
 
113
- class HypothesisCoreBitPossible{
114
- struct {
115
- n_bits: u64,
163
+ Class::from_existing("HypothesisCoreEngine")
164
+ .wrap_data(core_engine, &*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER)
116
165
  }
166
+ fn ruby_hypothesis_core_engine_new_source() -> AnyObject {
167
+ match itself
168
+ .get_data_mut(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER)
169
+ .new_source()
170
+ {
171
+ Some(ds) => Class::from_existing("HypothesisCoreDataSource")
172
+ .wrap_data(ds, &*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER),
173
+ None => NilClass::new().into(),
174
+ }
175
+ }
176
+ fn ruby_hypothesis_core_engine_finish_overflow(child: AnyObject) -> NilClass {
177
+ let core_engine = itself.get_data_mut(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER);
178
+ let mut rdata_source = safe_access(child);
179
+ let data_source = rdata_source.get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER);
180
+
181
+ core_engine.finish_overflow(data_source);
117
182
 
118
- def initialize(helix, n_bits: u64){
119
- return HypothesisCoreBitPossible{helix, n_bits: n_bits};
183
+ NilClass::new()
120
184
  }
185
+ fn ruby_hypothesis_core_engine_finish_valid(child: AnyObject) -> NilClass {
186
+ let core_engine = itself.get_data_mut(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER);
187
+ let mut rdata_source = safe_access(child);
188
+ let data_source = rdata_source.get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER);
189
+
190
+ core_engine.finish_valid(data_source);
121
191
 
122
- def provide(&mut self, data: &mut HypothesisCoreDataSource) -> Option<u64>{
123
- match &mut data.source {
124
- &mut None => None,
125
- &mut Some(ref mut source) => source.bits(self.n_bits).ok(),
126
- }
192
+ NilClass::new()
127
193
  }
128
- }
194
+ fn ruby_hypothesis_core_engine_finish_invalid(child: AnyObject) -> NilClass {
195
+ let core_engine = itself.get_data_mut(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER);
196
+ let mut rdata_source = safe_access(child);
197
+ let data_source = rdata_source.get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER);
129
198
 
130
- class HypothesisCoreRepeatValues{
131
- struct {
132
- repeat: Repeat,
199
+ core_engine.finish_invalid(data_source);
200
+
201
+ NilClass::new()
133
202
  }
203
+ fn ruby_hypothesis_core_engine_finish_interesting(
204
+ child: AnyObject,
205
+ label: Integer
206
+ ) -> NilClass {
207
+ let core_engine = itself.get_data_mut(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER);
208
+ let mut rdata_source = safe_access(child);
209
+ let data_source = rdata_source.get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER);
210
+
211
+ core_engine.finish_interesting(data_source, safe_access(label).to_u64());
134
212
 
135
- def initialize(helix, min_count: u64, max_count: u64, expected_count: f64){
136
- return HypothesisCoreRepeatValues{
137
- helix, repeat: Repeat::new(min_count, max_count, expected_count)
138
- }
213
+ NilClass::new()
139
214
  }
215
+ fn ruby_hypothesis_core_engine_count_failing_examples() -> Integer {
216
+ let core_engine = itself.get_data(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER);
140
217
 
141
- def _should_continue(&mut self, data: &mut HypothesisCoreDataSource) -> Option<bool>{
142
- return data.source.as_mut().and_then(|ref mut source| {
143
- self.repeat.should_continue(source).ok()
144
- })
218
+ Integer::new(core_engine.count_failing_examples() as i64)
145
219
  }
220
+ fn ruby_hypothesis_core_failing_example(i: Integer) -> AnyObject {
221
+ let core_engine = itself.get_data_mut(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER);
222
+ let int = safe_access(i).to_u64() as usize;
146
223
 
147
- def reject(&mut self){
148
- self.repeat.reject();
224
+ let data_source = core_engine.failing_example(int);
225
+
226
+ Class::from_existing("HypothesisCoreDataSource")
227
+ .wrap_data(data_source, &*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER)
149
228
  }
150
- }
229
+ fn ruby_hypothesis_core_engine_was_unsatisfiable() -> Boolean {
230
+ let core_engine = itself.get_data_mut(&*HYPOTHESIS_CORE_ENGINE_STRUCT_WRAPPER);
151
231
 
152
- class HypothesisCoreIntegers{
153
- struct {
154
- bitlengths: distributions::Sampler,
232
+ Boolean::new(core_engine.was_unsatisfiable())
155
233
  }
156
- def initialize(helix){
157
- return HypothesisCoreIntegers{helix,bitlengths: distributions::good_bitlengths()};
234
+ );
235
+
236
+ pub struct HypothesisCoreIntegersStruct {
237
+ bitlengths: distributions::Sampler,
238
+ }
239
+
240
+ impl HypothesisCoreIntegersStruct {
241
+ fn new() -> HypothesisCoreIntegersStruct {
242
+ HypothesisCoreIntegersStruct {
243
+ bitlengths: distributions::good_bitlengths(),
244
+ }
158
245
  }
159
- def provide(&mut self, data: &mut HypothesisCoreDataSource) -> Option<i64>{
160
- data.source.as_mut().and_then(|ref mut source| {
161
- distributions::integer_from_bitlengths(source, &self.bitlengths).ok()
162
- })
246
+
247
+ fn provide(&mut self, data: &mut HypothesisCoreDataSourceStruct) -> Option<i64> {
248
+ data.source.as_mut().and_then(|ref mut source| {
249
+ distributions::integer_from_bitlengths(source, &self.bitlengths).ok()
250
+ })
163
251
  }
164
- }
252
+ }
253
+
254
+ wrappable_struct!(
255
+ HypothesisCoreIntegersStruct,
256
+ HypothesisCoreIntegersStructWrapper,
257
+ HYPOTHESIS_CORE_INTEGERS_STRUCT_WRAPPER
258
+ );
259
+
260
+ class!(HypothesisCoreIntegers);
165
261
 
166
- class HypothesisCoreBoundedIntegers{
167
- struct {
168
- max_value: u64,
262
+ methods!(
263
+ HypothesisCoreIntegers,
264
+ itself,
265
+ fn ruby_hypothesis_core_integers_new() -> AnyObject {
266
+ let core_integers = HypothesisCoreIntegersStruct::new();
267
+
268
+ Class::from_existing("HypothesisCoreIntegers")
269
+ .wrap_data(core_integers, &*HYPOTHESIS_CORE_INTEGERS_STRUCT_WRAPPER)
169
270
  }
170
- def initialize(helix, max_value: u64){
171
- return HypothesisCoreBoundedIntegers{helix, max_value: max_value};
271
+ fn ruby_hypothesis_core_integers_provide(data: AnyObject) -> AnyObject {
272
+ let core_integers = itself.get_data_mut(&*HYPOTHESIS_CORE_INTEGERS_STRUCT_WRAPPER);
273
+ let mut rdata = safe_access(data);
274
+ let data_source = rdata.get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER);
275
+
276
+ match core_integers.provide(data_source) {
277
+ Some(i) => Integer::new(i).into(),
278
+ None => NilClass::new().into(),
279
+ }
172
280
  }
281
+ );
282
+
283
+ pub struct HypothesisCoreRepeatValuesStruct {
284
+ repeat: Repeat,
285
+ }
173
286
 
174
- def provide(&mut self, data: &mut HypothesisCoreDataSource) -> Option<u64>{
175
- data.source.as_mut().and_then(|ref mut source| {
176
- distributions::bounded_int(source, self.max_value).ok()
177
- })
287
+ impl HypothesisCoreRepeatValuesStruct {
288
+ fn new(
289
+ min_count: u64,
290
+ max_count: u64,
291
+ expected_count: f64,
292
+ ) -> HypothesisCoreRepeatValuesStruct {
293
+ HypothesisCoreRepeatValuesStruct {
294
+ repeat: Repeat::new(min_count, max_count, expected_count),
295
+ }
178
296
  }
179
- }
297
+
298
+ fn _should_continue(&mut self, data: &mut HypothesisCoreDataSourceStruct) -> Option<bool> {
299
+ return data
300
+ .source
301
+ .as_mut()
302
+ .and_then(|ref mut source| self.repeat.should_continue(source).ok());
303
+ }
304
+
305
+ fn reject(&mut self) {
306
+ self.repeat.reject();
307
+ }
308
+ }
309
+
310
+ wrappable_struct!(
311
+ HypothesisCoreRepeatValuesStruct,
312
+ HypothesisCoreRepeatValuesStructWrapper,
313
+ HYPOTHESIS_CORE_REPEAT_VALUES_STRUCT_WRAPPER
314
+ );
315
+
316
+ class!(HypothesisCoreRepeatValues);
317
+
318
+ methods!(
319
+ HypothesisCoreRepeatValues,
320
+ itself,
321
+ fn ruby_hypothesis_core_repeat_values_new(
322
+ min_count: Integer,
323
+ max_count: Integer,
324
+ expected_count: Float
325
+ ) -> AnyObject {
326
+ let repeat_values = HypothesisCoreRepeatValuesStruct::new(
327
+ safe_access(min_count).to_u64(),
328
+ safe_access(max_count).to_u64(),
329
+ safe_access(expected_count).to_f64(),
330
+ );
331
+
332
+ Class::from_existing("HypothesisCoreRepeatValues").wrap_data(
333
+ repeat_values,
334
+ &*HYPOTHESIS_CORE_REPEAT_VALUES_STRUCT_WRAPPER,
335
+ )
336
+ }
337
+ fn ruby_hypothesis_core_repeat_values_should_continue(data: AnyObject) -> AnyObject {
338
+ let mut rdata = safe_access(data);
339
+ let mut data_source = rdata.get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER);
340
+
341
+ let should_continue = itself
342
+ .get_data_mut(&*HYPOTHESIS_CORE_REPEAT_VALUES_STRUCT_WRAPPER)
343
+ ._should_continue(data_source);
344
+
345
+ match should_continue {
346
+ Some(b) => Boolean::new(b).into(),
347
+ None => NilClass::new().into(),
348
+ }
349
+ }
350
+ fn ruby_hypothesis_core_repeat_values_reject() -> NilClass {
351
+ let repeat_values = itself.get_data_mut(&*HYPOTHESIS_CORE_REPEAT_VALUES_STRUCT_WRAPPER);
352
+
353
+ repeat_values.reject();
354
+
355
+ NilClass::new()
356
+ }
357
+ );
358
+
359
+ pub struct HypothesisCoreBoundedIntegersStruct {
360
+ max_value: u64,
180
361
  }
181
362
 
182
- fn mark_child_status(engine: &mut Engine, child: &mut HypothesisCoreDataSource, status: Status) {
183
- let mut replacement = None;
184
- mem::swap(&mut replacement, &mut child.source);
363
+ impl HypothesisCoreBoundedIntegersStruct {
364
+ fn provide(&mut self, data: &mut HypothesisCoreDataSourceStruct) -> Option<u64> {
365
+ data.source
366
+ .as_mut()
367
+ .and_then(|ref mut source| distributions::bounded_int(source, self.max_value).ok())
368
+ }
369
+ }
370
+
371
+ wrappable_struct!(
372
+ HypothesisCoreBoundedIntegersStruct,
373
+ HypothesisCoreBoundedIntegersStructWrapper,
374
+ HYPOTHESIS_CORE_BOUNDED_INTEGERS_STRUCT_WRAPPER
375
+ );
376
+
377
+ class!(HypothesisCoreBoundedIntegers);
378
+
379
+ methods!(
380
+ HypothesisCoreBoundedIntegers,
381
+ itself,
382
+ fn ruby_hypothesis_core_bounded_integers_new(max_value: Integer) -> AnyObject {
383
+ let bounded_integers = HypothesisCoreBoundedIntegersStruct {
384
+ max_value: safe_access(max_value).to_u64(),
385
+ };
185
386
 
186
- match replacement {
187
- Some(source) => engine.mark_finished(source, status),
188
- None => (),
387
+ Class::from_existing("HypothesisCoreBoundedIntegers").wrap_data(
388
+ bounded_integers,
389
+ &*HYPOTHESIS_CORE_BOUNDED_INTEGERS_STRUCT_WRAPPER,
390
+ )
189
391
  }
392
+ fn ruby_hypothesis_core_bounded_integers_provide(data: AnyObject) -> AnyObject {
393
+ let mut rdata = safe_access(data);
394
+ let data_source = rdata.get_data_mut(&*HYPOTHESIS_CORE_DATA_SOURCE_STRUCT_WRAPPER);
395
+ let bounded_integers =
396
+ itself.get_data_mut(&*HYPOTHESIS_CORE_BOUNDED_INTEGERS_STRUCT_WRAPPER);
397
+
398
+ match bounded_integers.provide(data_source) {
399
+ Some(i) => Integer::from(i).into(),
400
+ None => NilClass::new().into(),
401
+ }
402
+ }
403
+ );
404
+
405
+ #[allow(non_snake_case)]
406
+ #[no_mangle]
407
+ pub extern "C" fn Init_rutie_hypothesis_core() {
408
+ Class::new("HypothesisCoreEngine", None).define(|klass| {
409
+ klass.def_self("new", ruby_hypothesis_core_engine_new);
410
+ klass.def("new_source", ruby_hypothesis_core_engine_new_source);
411
+ klass.def(
412
+ "count_failing_examples",
413
+ ruby_hypothesis_core_engine_count_failing_examples,
414
+ );
415
+ klass.def("failing_example", ruby_hypothesis_core_failing_example);
416
+ klass.def(
417
+ "was_unsatisfiable",
418
+ ruby_hypothesis_core_engine_was_unsatisfiable,
419
+ );
420
+ klass.def(
421
+ "finish_overflow",
422
+ ruby_hypothesis_core_engine_finish_overflow,
423
+ );
424
+ klass.def("finish_valid", ruby_hypothesis_core_engine_finish_valid);
425
+ klass.def("finish_invalid", ruby_hypothesis_core_engine_finish_invalid);
426
+ klass.def(
427
+ "finish_interesting",
428
+ ruby_hypothesis_core_engine_finish_interesting,
429
+ );
430
+ });
431
+
432
+ Class::new("HypothesisCoreDataSource", None).define(|klass| {
433
+ klass.def("start_draw", ruby_hypothesis_core_data_source_start_draw);
434
+ klass.def("stop_draw", ruby_hypothesis_core_data_source_stop_draw);
435
+ });
436
+
437
+ Class::new("HypothesisCoreIntegers", None).define(|klass| {
438
+ klass.def_self("new", ruby_hypothesis_core_integers_new);
439
+ klass.def("provide", ruby_hypothesis_core_integers_provide);
440
+ });
441
+
442
+ Class::new("HypothesisCoreRepeatValues", None).define(|klass| {
443
+ klass.def_self("new", ruby_hypothesis_core_repeat_values_new);
444
+ klass.def(
445
+ "_should_continue",
446
+ ruby_hypothesis_core_repeat_values_should_continue,
447
+ );
448
+ klass.def("reject", ruby_hypothesis_core_repeat_values_reject);
449
+ });
450
+
451
+ Class::new("HypothesisCoreBoundedIntegers", None).define(|klass| {
452
+ klass.def_self("new", ruby_hypothesis_core_bounded_integers_new);
453
+ klass.def("provide", ruby_hypothesis_core_bounded_integers_provide);
454
+ });
455
+ }
456
+
457
+ fn mark_child_status(
458
+ engine: &mut Engine,
459
+ child: &mut HypothesisCoreDataSourceStruct,
460
+ status: Status,
461
+ ) {
462
+ if let Some(source) = mem::take(&mut child.source) {
463
+ engine.mark_finished(source, status)
464
+ }
465
+ }
466
+
467
+ fn safe_access<T>(value: Result<T, AnyException>) -> T {
468
+ value.map_err(VM::raise_ex).unwrap()
190
469
  }
metadata CHANGED
@@ -1,29 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hypothesis-specs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David R. Maciver
8
+ - Alex Weisberger
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2018-10-24 00:00:00.000000000 Z
12
+ date: 2021-01-08 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: helix_runtime
15
+ name: rutie
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
18
  - - "~>"
18
19
  - !ruby/object:Gem::Version
19
- version: 0.7.0
20
+ version: 0.0.3
20
21
  type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - "~>"
25
26
  - !ruby/object:Gem::Version
26
- version: 0.7.0
27
+ version: 0.0.3
27
28
  - !ruby/object:Gem::Dependency
28
29
  name: rake
29
30
  requirement: !ruby/object:Gem::Requirement
@@ -88,8 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
89
  - !ruby/object:Gem::Version
89
90
  version: '0'
90
91
  requirements: []
91
- rubyforge_project:
92
- rubygems_version: 2.7.6
92
+ rubygems_version: 3.2.4
93
93
  signing_key:
94
94
  specification_version: 4
95
95
  summary: Hypothesis is a powerful, flexible, and easy to use library for property-based