hypothesis-specs 0.2.0 → 0.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.
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