ocg 1.0.0 → 1.1.4
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 +4 -4
- data/README.md +44 -46
- data/lib/ocg/main.rb +11 -0
- data/lib/ocg/operator/abstract.rb +3 -1
- data/lib/ocg/operator/mix.rb +1 -1
- data/lib/ocg/options.rb +2 -2
- data/lib/ocg/version.rb +1 -1
- metadata +38 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59aa6a751c46f2c5df99170cbc90b6d588a31cd6c58c0c1442405545346196e6
|
4
|
+
data.tar.gz: 51ad926c4f636f950e478537d68694743997d5edbc510d801163666819dc18b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e369db994e082505ac85c156a0c92801e14a148ee1c139be7a9edf7834cb6bbcf13534638d33ebb848de8edb455afca054ac8efe21f5b1882f54238f3a379cb
|
7
|
+
data.tar.gz: '0729c7969f7d29adf70a3ef0a03ba65f4cb2b11092cafc8e963532d82f145b9f61a466a9e622ba57e573272ec1c138bd6ca0155c13ff083b1aac04ccd6f7e29a'
|
data/README.md
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
# Option combination generator
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
[](https://circleci.com/gh/andrew-aladev/ocg/tree/master)
|
3
|
+
| Travis | AppVeyor | Circle | Codecov |
|
4
|
+
| :---: | :---: | :---: | :---: |
|
5
|
+
| [](https://travis-ci.com/andrew-aladev/ocg) | [](https://ci.appveyor.com/project/andrew-aladev/ocg/branch/master) | [](https://circleci.com/gh/andrew-aladev/ocg/tree/master) | [](https://codecov.io/gh/andrew-aladev/ocg) |
|
7
6
|
|
8
7
|
## Installation
|
9
8
|
|
@@ -18,6 +17,8 @@ rake gem
|
|
18
17
|
gem install pkg/ocg-*.gem
|
19
18
|
```
|
20
19
|
|
20
|
+
You can also use [overlay](https://github.com/andrew-aladev/overlay) for gentoo.
|
21
|
+
|
21
22
|
## Usage
|
22
23
|
|
23
24
|
```ruby
|
@@ -40,15 +41,31 @@ generator = OCG.new(
|
|
40
41
|
:h => 7..8
|
41
42
|
)
|
42
43
|
|
43
|
-
until generator.finished?
|
44
|
-
pp generator.next
|
45
|
-
end
|
44
|
+
puts generator.next until generator.finished?
|
46
45
|
```
|
47
46
|
|
48
47
|
It will populate all option combinations.
|
49
48
|
|
50
49
|
## Docs
|
51
50
|
|
51
|
+
`OCG.new options` will prepare a generator.
|
52
|
+
It will provide all possible option combinations.
|
53
|
+
|
54
|
+
| Method | Description |
|
55
|
+
|-------------|-------------|
|
56
|
+
| `and` | provides all combinations between generators |
|
57
|
+
| `mix` | merges combinations without combining, guarantees that both left and right generator combinations will be provided at least once |
|
58
|
+
| `or` | concats generator combinations without merging |
|
59
|
+
| `reset` | allows to receive combinations once again |
|
60
|
+
| `next` | returns next combination |
|
61
|
+
| `last` | returns last combination |
|
62
|
+
| `started?` | returns true when at least one combination was generated |
|
63
|
+
| `finished?` | returns true when all combination were generated |
|
64
|
+
| `length` | returns combinations length |
|
65
|
+
| `to_a` | returns combinations array |
|
66
|
+
|
67
|
+
You can combine generators using `and`, `mix` and `or`.
|
68
|
+
|
52
69
|
Options should be prepared in the following form:
|
53
70
|
|
54
71
|
```ruby
|
@@ -63,32 +80,12 @@ Options hash should not be empty.
|
|
63
80
|
`option_values` should be convertable to array using `to_a`.
|
64
81
|
`option_values` should not be empty.
|
65
82
|
|
66
|
-
`OCG.new options` will prepare a generator.
|
67
|
-
It will provide all possible option combinations.
|
68
|
-
|
69
|
-
You can combine generators using `and`, `mix` and `or`.
|
70
|
-
|
71
|
-
`and` method will provide all combinations between generators.
|
72
|
-
`mix` method will merge right generator combinations into left without combining. `mix` guarantees that both left and right generator combinations will be provided at least once.
|
73
|
-
`or` method will concat generator combinations without merging.
|
74
|
-
|
75
|
-
`reset` method allows to receive combinations once again.
|
76
|
-
|
77
|
-
`next` method returns next combination.
|
78
|
-
|
79
|
-
`last` method returns last combination.
|
80
|
-
|
81
|
-
`started?` method returns true when at least one combination was generated.
|
82
|
-
|
83
|
-
`finished?` method returns true when all combination were generated.
|
84
|
-
|
85
|
-
`length` returns combinations length.
|
86
|
-
|
87
83
|
## Why?
|
88
84
|
|
89
85
|
Many software uses multiple options and have complex relations between them.
|
90
86
|
We want to test this software.
|
91
87
|
We need to provide optimal option combination to maximize test coverage.
|
88
|
+
The amount of combinations can be more than billion, it is not possible to store them (fuzzing testing).
|
92
89
|
|
93
90
|
Let's look at [zstd compressor options](http://facebook.github.io/zstd/zstd_manual.html#Chapter5).
|
94
91
|
|
@@ -102,7 +99,7 @@ general_generator = OCG.new(
|
|
102
99
|
)
|
103
100
|
.or(
|
104
101
|
:windowLog => 0..10,
|
105
|
-
:hashLog
|
102
|
+
:hashLog => 0..10,
|
106
103
|
...
|
107
104
|
)
|
108
105
|
```
|
@@ -116,8 +113,8 @@ ldm_generator = OCG.new(
|
|
116
113
|
)
|
117
114
|
.or(
|
118
115
|
:enableLongDistanceMatching => [true],
|
119
|
-
:ldmHashLog
|
120
|
-
:ldmMinMatch
|
116
|
+
:ldmHashLog => 0..10,
|
117
|
+
:ldmMinMatch => 0..10,
|
121
118
|
...
|
122
119
|
)
|
123
120
|
```
|
@@ -130,37 +127,38 @@ main_generator = general_generator.and ldm_generator
|
|
130
127
|
```
|
131
128
|
|
132
129
|
`contentSizeFlag`, `checksumFlag`, `dictIDFlag` options are additional options.
|
133
|
-
These options
|
134
|
-
We want just to mix their values with main options.
|
130
|
+
These options may correlate between each other but don't correlate with main options.
|
135
131
|
|
136
132
|
```ruby
|
137
133
|
almost_complete_generator = main_generator.mix(
|
138
|
-
:contentSizeFlag => [true, false]
|
139
|
-
|
140
|
-
|
141
|
-
:checksumFlag => [true, false]
|
142
|
-
)
|
143
|
-
.mix(
|
144
|
-
:dictIDFlag => [true, false]
|
134
|
+
:contentSizeFlag => [true, false],
|
135
|
+
:checksumFlag => [true, false],
|
136
|
+
:dictIDFlag => [true, false]
|
145
137
|
)
|
146
138
|
```
|
147
139
|
|
148
140
|
`nbWorkers`, `jobSize` and `overlapLog` options are thread related options.
|
141
|
+
When `nbWorkers` equals `0`, `jobSize` and `overlapLog` should not be used.
|
149
142
|
These options correlate between each other but don't correlate with main options.
|
150
143
|
|
151
144
|
```ruby
|
152
145
|
complete_generator = almost_complete_generator.mix(
|
153
|
-
|
154
|
-
|
155
|
-
|
146
|
+
OCG.new(
|
147
|
+
:nbWorkers => [0]
|
148
|
+
)
|
149
|
+
.or(
|
150
|
+
:nbWorkers => 1..2,
|
151
|
+
:jobSize => 1..10,
|
152
|
+
:overlapLog => 0..9
|
153
|
+
)
|
156
154
|
)
|
157
155
|
```
|
158
156
|
|
159
157
|
## CI
|
160
158
|
|
161
|
-
|
162
|
-
|
163
|
-
|
159
|
+
See universal test script [scripts/ci_test.sh](scripts/ci_test.sh) for CI.
|
160
|
+
Please visit [scripts/test-images](scripts/test-images).
|
161
|
+
You can run this test script using many native and cross images.
|
164
162
|
|
165
163
|
## License
|
166
164
|
|
data/lib/ocg/main.rb
CHANGED
@@ -34,6 +34,17 @@ class OCG
|
|
34
34
|
def or(generator_or_options)
|
35
35
|
Operator::OR.new self, generator_or_options
|
36
36
|
end
|
37
|
+
|
38
|
+
def to_a
|
39
|
+
reset
|
40
|
+
|
41
|
+
result = []
|
42
|
+
result << send("next") until finished?
|
43
|
+
|
44
|
+
reset
|
45
|
+
|
46
|
+
result
|
47
|
+
end
|
37
48
|
end
|
38
49
|
|
39
50
|
require_relative "operator/and"
|
@@ -6,7 +6,7 @@ require_relative "../error"
|
|
6
6
|
class OCG
|
7
7
|
module Operator
|
8
8
|
class Abstract < OCG
|
9
|
-
def initialize(left_generator_or_options, right_generator_or_options)
|
9
|
+
def initialize(left_generator_or_options, right_generator_or_options) # rubocop:disable Lint/MissingSuper
|
10
10
|
@left_generator = OCG.prepare_generator left_generator_or_options
|
11
11
|
@right_generator = OCG.prepare_generator right_generator_or_options
|
12
12
|
|
@@ -20,6 +20,7 @@ class OCG
|
|
20
20
|
nil
|
21
21
|
end
|
22
22
|
|
23
|
+
# :nocov:
|
23
24
|
def next
|
24
25
|
raise NotImplementedError, "\"next\" is not implemented"
|
25
26
|
end
|
@@ -39,6 +40,7 @@ class OCG
|
|
39
40
|
def length
|
40
41
|
raise NotImplementedError, "\"length\" is not implemented"
|
41
42
|
end
|
43
|
+
# :nocov:
|
42
44
|
end
|
43
45
|
end
|
44
46
|
end
|
data/lib/ocg/operator/mix.rb
CHANGED
data/lib/ocg/options.rb
CHANGED
@@ -7,7 +7,7 @@ class OCG
|
|
7
7
|
class Options
|
8
8
|
def initialize(options)
|
9
9
|
Validation.validate_options options
|
10
|
-
@options =
|
10
|
+
@options = options.transform_values(&:to_a)
|
11
11
|
|
12
12
|
# End to start is more traditional way of making combinations.
|
13
13
|
@keys = @options.keys.reverse
|
@@ -20,7 +20,7 @@ class OCG
|
|
20
20
|
end
|
21
21
|
|
22
22
|
protected def reset_value_indexes
|
23
|
-
@value_indexes =
|
23
|
+
@value_indexes = @options.transform_values { |_values| 0 }
|
24
24
|
end
|
25
25
|
|
26
26
|
def reset
|
data/lib/ocg/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ocg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Aladjev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: codecov
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: minitest
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +38,20 @@ dependencies:
|
|
24
38
|
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '5.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rubocop
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,19 +81,19 @@ dependencies:
|
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '1.5'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
84
|
+
name: simplecov
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
|
-
- - "
|
87
|
+
- - ">="
|
60
88
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
89
|
+
version: '0'
|
62
90
|
type: :development
|
63
91
|
prerelease: false
|
64
92
|
version_requirements: !ruby/object:Gem::Requirement
|
65
93
|
requirements:
|
66
|
-
- - "
|
94
|
+
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
96
|
+
version: '0'
|
69
97
|
description:
|
70
98
|
email: aladjev.andrew@gmail.com
|
71
99
|
executables: []
|
@@ -95,16 +123,16 @@ require_paths:
|
|
95
123
|
- lib
|
96
124
|
required_ruby_version: !ruby/object:Gem::Requirement
|
97
125
|
requirements:
|
98
|
-
- - "
|
126
|
+
- - "~>"
|
99
127
|
- !ruby/object:Gem::Version
|
100
|
-
version: '
|
128
|
+
version: '2.7'
|
101
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
130
|
requirements:
|
103
131
|
- - ">="
|
104
132
|
- !ruby/object:Gem::Version
|
105
133
|
version: '0'
|
106
134
|
requirements: []
|
107
|
-
rubygems_version: 3.
|
135
|
+
rubygems_version: 3.1.2
|
108
136
|
signing_key:
|
109
137
|
specification_version: 4
|
110
138
|
summary: Option combination generator.
|