stroop 1.0.0 → 1.1.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: 964e287156e79b56d6b6210bf1b7a5934e38e6178352904e23c7d8d84206a193
4
- data.tar.gz: 3d6648046d0ecb62ec85da53f102910a07c7ddd855bc0174ee2507baca328fba
3
+ metadata.gz: 733eff782edc5ce54cc80b6bf947eefb79ee5d6f04bb1d2ef84ad9229e223c40
4
+ data.tar.gz: e2b826afb1dbdd6b90f90e992765a0eace4e82bb66940cb1cf28995567ef01bb
5
5
  SHA512:
6
- metadata.gz: a45e2802db6fe67fe7adb3e3d7690142b994c0548fecf2fdbf21b04c1bf95a54d69db4272d60c0926578070b961f82c3faf71e828db8dfc8b857b11b992744ed
7
- data.tar.gz: d49000f0bcc7ccb7677a953d8a3788fcacbd9b9f6e94c5863d55111c2eb244af26b88c112c01f3504835dca011fabe9d6a365e3e91bd1b4d94c0fce14554baf2
6
+ metadata.gz: '0822ec8086aafb19daf6708be6898103902e0a75251de66faed092a2171598e1c141c02acded3d33c3543ffc79827869547e1d0a2d63c4e6319a76017f3c2349'
7
+ data.tar.gz: 3d3b2e43a6de919e2a63e4ddc259a19279d5dda2b8283218cebfe3211bd5ff8633e8e8136b0ad89413d893c164c00d873eb522eb6c6013dcce05c830f0d11d12
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+ - A `seed:` keyword argument for `Stroop::Set`
12
+ - `--seed`/`-s` CLI option to pass a random seed which is used to generate the color words
13
+
10
14
  ## [1.0.0] - 2020-05-21
11
15
  ### Removed
12
16
  - Drop support for Ruby <= v2.4
data/README.md CHANGED
@@ -39,6 +39,16 @@ This will print you a Stroop test of 10 lines of words with 5 words in each of t
39
39
 
40
40
  You can adjust the rows and columns of words by changing the `CxR` param as you like (e.g. `5x2`). If you leave it out a default of `5x10` is used.
41
41
 
42
+ For each print out you will find the random seed that was used to generate the color words.
43
+
44
+ You can also pass a seed by using the `--seed` or `-s` option:
45
+
46
+ ```bash
47
+ $ stroop neutral --seed=1234
48
+ $ stroop congruent -s 1234
49
+ $ stroop incongruent -s 1234
50
+ ```
51
+
42
52
  If you want to use Stroop in Ruby you can run the following code:
43
53
 
44
54
  ```ruby
@@ -47,6 +57,10 @@ require 'stroop'
47
57
  # adjust rows and columns to whatever you like
48
58
  set = Stroop::Set.new(columns: 5, rows: 10, mode: Stroop::Set::NEUTRAL)
49
59
  set.to_s # => returns the string of colorized words
60
+
61
+ # or if you want to pass a specific random seed that is used to generate the set:
62
+ set = Stroop::Set.new(columns: 5, rows: 10, mode: Stroop::Set::NEUTRAL, seed: 1234)
63
+ set.seed # => returns the random seed that was used to create the color words
50
64
  ```
51
65
 
52
66
  The available Stroop::Set modes are:
@@ -5,29 +5,32 @@ module Stroop
5
5
  class CLI < Thor
6
6
  DEFAULT_SIZE = 5.freeze
7
7
 
8
+ class_option :seed, type: :numeric, aliases: "-s", description: "The random seed to generate the color words"
9
+
8
10
  desc 'neutral COLSxROWS', 'prints neutral color words in COLS columns and ROWS rows'
9
11
  def neutral(size = '10x5')
10
- print(size: size, mode: Set::NEUTRAL)
12
+ print(size: size, mode: Set::NEUTRAL, seed: options[:seed])
11
13
  end
12
14
 
13
15
  desc 'congruent COLSxROWS', 'prints congruent color words in COLS columns and ROWS rows'
14
16
  def congruent(size = '10x5')
15
- print(size: size, mode: Set::CONGRUENT)
17
+ print(size: size, mode: Set::CONGRUENT, seed: options[:seed])
16
18
  end
17
19
 
18
20
  desc 'incongruent COLSxROWS', 'prints incongruent color words in COLS columns and ROWS rows'
19
21
  def incongruent(size = '10x5')
20
- print(size: size, mode: Set::INCONGRUENT)
22
+ print(size: size, mode: Set::INCONGRUENT, seed: options[:seed])
21
23
  end
22
24
 
23
25
  private
24
26
 
25
- def print(size:, mode:)
27
+ def print(size:, mode:, seed:)
26
28
  rows, columns = dimensions(size)
27
29
  rows = apply_default_size(rows)
28
30
  columns = apply_default_size(columns)
29
31
 
30
- puts Set.new(rows: rows, columns: columns, mode: mode).to_s
32
+ set = Stroop::Set.new(rows: rows, columns: columns, mode: mode, seed: seed)
33
+ puts set, "🌱 Generated with seed: #{set.seed}"
31
34
  end
32
35
 
33
36
  def dimensions(size)
@@ -0,0 +1,41 @@
1
+ module Stroop
2
+ class ColorGenerator
3
+ COLORS = %w{ black white red green blue yellow }.freeze
4
+
5
+ attr_reader :seed
6
+
7
+ def initialize(seed: nil)
8
+ @seed = seed || Random.new_seed
9
+ @single_random = Random.new(@seed)
10
+ @pair_random = Random.new(@seed)
11
+ end
12
+
13
+ def generate
14
+ selected = random_select(@single_random)
15
+
16
+ while selected == @last_generated do
17
+ selected = random_select(@single_random)
18
+ end
19
+
20
+ @last_generated = selected
21
+ end
22
+
23
+ def generate_pair
24
+ first = generate
25
+ second = random_select(@pair_random)
26
+
27
+ while first == second || second == @last_generated_second do
28
+ second = random_select(@pair_random)
29
+ end
30
+
31
+ @last_generated_second = second
32
+ [first, second]
33
+ end
34
+
35
+ private
36
+
37
+ def random_select(random)
38
+ COLORS.sample(random: random)
39
+ end
40
+ end
41
+ end
@@ -1,10 +1,9 @@
1
1
  require 'colorize'
2
2
  require_relative 'exceptions'
3
+ require_relative 'color_generator'
3
4
 
4
5
  module Stroop
5
6
  class Set
6
- COLORS = %w{ black white red green blue yellow }.freeze
7
-
8
7
  NEUTRAL = :neutral
9
8
  CONGRUENT = :congruent
10
9
  INCONGRUENT = :incongruent
@@ -20,14 +19,16 @@ module Stroop
20
19
  bottom_right: "┘"
21
20
  }.transform_values(&:light_black).freeze
22
21
 
23
- attr_reader :rows, :columns, :mode
22
+ attr_reader :rows, :columns, :mode, :seed
24
23
 
25
- def initialize(rows:, columns:, mode:)
24
+ def initialize(rows:, columns:, mode:, seed: nil)
26
25
  raise SetModeNotAvailable.new unless MODES.include?(mode)
27
26
 
28
- @rows = rows.to_i.abs
27
+ @rows = rows.to_i.abs
29
28
  @columns = columns.to_i.abs
30
- @mode = mode.to_sym
29
+ @mode = mode.to_sym
30
+ @generator = ColorGenerator.new(seed: seed)
31
+ @seed = @generator.seed
31
32
  end
32
33
 
33
34
  def to_s
@@ -65,37 +66,20 @@ module Stroop
65
66
  def word_color_pair
66
67
  case mode
67
68
  when :neutral
68
- word = random_color
69
+ word = @generator.generate
69
70
  color = :black
70
71
  when :congruent
71
- word = random_color
72
+ word = @generator.generate
72
73
  color = word
73
74
  when :incongruent
74
- word, color = random_different_colors
75
+ word, color = @generator.generate_pair
75
76
  end
76
77
 
77
78
  [word, color]
78
79
  end
79
80
 
80
- def random_different_colors
81
- first = random_color
82
- second = random_color
83
-
84
- while first == second
85
- second = random_color
86
- end
87
-
88
- [first, second]
89
- end
90
-
91
- def random_color
92
- color = COLORS.sample
93
- color = random_color if color == @latest_random_color
94
- @latest_random_color = color
95
- end
96
-
97
81
  def max_word_length
98
- @max_word_length ||= COLORS.map { |color| color.chars.count }.max
82
+ @max_word_length ||= ColorGenerator::COLORS.map { |color| color.chars.count }.max
99
83
  end
100
84
 
101
85
  def total_word_width
@@ -1,5 +1,5 @@
1
1
  module Stroop
2
- VERSION = "1.0.0".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
4
4
 
5
5
 
@@ -1,2 +1,15 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require 'stroop'
3
+
4
+ def capture(stream)
5
+ begin
6
+ stream = stream.to_s
7
+ eval "$#{stream} = StringIO.new"
8
+ yield
9
+ result = eval("$#{stream}").string
10
+ ensure
11
+ eval("$#{stream} = #{stream.upcase}")
12
+ end
13
+
14
+ result
15
+ end
@@ -1,32 +1,35 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Stroop::CLI do
4
+ let(:seed) { 1234 }
4
5
 
5
6
  before do
7
+ allow_any_instance_of(Stroop::Set).to receive(:seed) { seed }
6
8
  allow_any_instance_of(Stroop::Set).to receive(:to_s) { '' }
7
9
  allow($stdout).to receive(:puts) { '' }
8
10
  end
9
11
 
12
+ subject { described_class.new([seed]) }
13
+
10
14
  [:neutral, :congruent, :incongruent].each do |method|
11
15
  it { is_expected.to respond_to method }
12
16
 
13
17
  describe "##{method}" do
14
- let(:size) { '1x1' }
18
+ let(:columns) { 1 }
19
+ let(:rows) { 1 }
20
+ let(:args) { "#{columns}x#{rows}" }
15
21
 
16
- it 'should create a new Stroop::Set' do
17
- expect(Stroop::Set).to receive(:new).once
18
- subject.send(method, size)
22
+ it 'prints to the standard output' do
23
+ expect { subject.send(method, args) }.to output.to_stdout
19
24
  end
20
25
 
21
- it 'should convert the Stroop::Set to a string' do
22
- expect_any_instance_of(Stroop::Set).to receive(:to_s).once
23
- subject.send(method, size)
24
- end
26
+ it 'prints the stroop set' do
27
+ set = Stroop::Set.new(columns: columns, rows: rows, mode: method, seed: seed)
28
+ output = capture(:stdout) { subject.send(method, args) }
25
29
 
26
- it 'should print to the standard output' do
27
- expect { subject.send(method, size) }.to output.to_stdout
30
+ expect(output).to include set.to_s
31
+ expect(output).to include "Generated with seed: #{seed}"
28
32
  end
29
33
  end
30
34
  end
31
-
32
35
  end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stroop::ColorGenerator do
4
+ describe 'without seed' do
5
+ subject { described_class.new }
6
+
7
+ describe '#generate' do
8
+ it 'returns a random color' do
9
+ expect(Stroop::ColorGenerator::COLORS).to include subject.generate
10
+ end
11
+ end
12
+
13
+ describe '#generate_pair' do
14
+ it 'returns a pair of colors that are different' do
15
+ 20.times do
16
+ first, second = subject.generate_pair
17
+ expect(first).to_not eq second
18
+ end
19
+ end
20
+
21
+ it 'returns another pair in subsequent calls' do
22
+ previous_colors = subject.generate_pair
23
+
24
+ 20.times do
25
+ new_colors = subject.generate_pair
26
+ expect(new_colors).to_not eq previous_colors
27
+ previous_colors = new_colors
28
+ end
29
+ end
30
+ end
31
+
32
+ describe 'with seed' do
33
+ let(:seed) { 1234 }
34
+ let(:generator) { described_class.new(seed: seed) }
35
+ let(:other_generator) { described_class.new(seed: seed) }
36
+
37
+ describe '#generate' do
38
+ it 'uses the given seed to generate colors deterministically' do
39
+ 20.times { expect(generator.generate).to eq other_generator.generate }
40
+ end
41
+ end
42
+
43
+ describe '#generate_pair' do
44
+ it 'uses the given seed to generate colors deterministically' do
45
+ 20.times { expect(generator.generate_pair).to eq other_generator.generate_pair }
46
+ end
47
+ end
48
+
49
+ it 'generates the same colors for #generate and #generate_pair (first color only)' do
50
+ generated_colors = 20.times.map { generator.generate }
51
+ generated_pairs_first_colors = 20.times.map { other_generator.generate_pair.first }
52
+
53
+ expect(generated_colors).to eq generated_pairs_first_colors
54
+ end
55
+ end
56
+ end
57
+ end
@@ -1,51 +1,82 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Stroop::Set do
4
+ [:neutral, :incongruent, :congruent].each do |mode|
5
+ let(:arguments) { {rows: 1, columns: 2, mode: mode } }
6
+ subject { described_class.new(**arguments) }
4
7
 
5
- let(:arguments) { {rows: 1, columns: 2, mode: :neutral } }
6
- subject { described_class.new(**arguments) }
8
+ describe 'creating a new instance' do
9
+ it 'raises an error if the given mode is not available' do
10
+ expect {
11
+ described_class.new(**arguments.merge({ mode: :not_existing }))
12
+ }.to raise_error Stroop::SetModeNotAvailable
13
+ end
7
14
 
8
- describe 'creating a new instance' do
9
- it 'should raise an error if the given mode is not available' do
10
- expect {
11
- described_class.new(**arguments.merge({ mode: :not_existing }))
12
- }.to raise_error Stroop::SetModeNotAvailable
15
+ it 'does not raise an error if the given mode is available' do
16
+ expect {
17
+ described_class.new(**arguments.merge({ mode: :neutral }))
18
+ described_class.new(**arguments.merge({ mode: :congruent }))
19
+ described_class.new(**arguments.merge({ mode: :incongruent }))
20
+ }.not_to raise_error
21
+ end
13
22
  end
14
23
 
15
- it 'should not raise an error if the given mode is available' do
16
- expect {
17
- described_class.new(**arguments.merge({ mode: :neutral }))
18
- described_class.new(**arguments.merge({ mode: :congruent }))
19
- described_class.new(**arguments.merge({ mode: :incongruent }))
20
- }.not_to raise_error
24
+ [:NEUTRAL, :CONGRUENT, :INCONGRUENT, :MODES].each do |name|
25
+ it "has a constant '#{name}'" do
26
+ expect(described_class.constants).to include name
27
+ end
21
28
  end
22
- end
23
29
 
24
- [:NEUTRAL, :CONGRUENT, :INCONGRUENT, :COLORS, :MODES].each do |name|
25
- it "should have a constant '#{name}'" do
26
- expect(described_class.constants).to include name
30
+ [:rows, :columns, :mode, :seed].each do |method|
31
+ it "responds to ##{method}" do
32
+ expect(subject).to respond_to method
33
+ end
27
34
  end
28
- end
29
35
 
30
- [:rows, :columns, :mode].each do |method|
31
- it "should respond to ##{method}" do
32
- expect(subject).to respond_to method
33
- end
34
- end
36
+ describe '#to_s' do
37
+ it 'returns a text with the instantiated number of lines' do
38
+ actual_rows = subject.to_s.lines.count
39
+ expected_rows = subject.rows + 2 # 2 wrapping empty lines (first & last)
35
40
 
36
- it 'should return a text with the instantiated number of lines' do
37
- actual_rows = subject.to_s.lines.count
38
- expected_rows = subject.rows + 2 # 2 wrapping empty lines (first & last)
41
+ expect(actual_rows).to eq expected_rows
42
+ end
39
43
 
40
- expect(actual_rows).to eq expected_rows
41
- end
44
+ it 'returns a text with the defined number of words per line' do
45
+ color_regex = /(#{Stroop::ColorGenerator::COLORS.join('|')})/
46
+ line = subject.to_s.lines[1] # first line with words
47
+ words = line.scan(color_regex).flatten
42
48
 
43
- it 'should return a text with the defined number of words per line' do
44
- color_regex = /(#{described_class::COLORS.join('|')})/
45
- line = subject.to_s.lines[1] # first line with words
46
- words = line.scan(color_regex).flatten
49
+ expect(words.count).to eq subject.columns
50
+ end
47
51
 
48
- expect(words.count).to eq subject.columns
49
- end
52
+ it 'returns the same text for the same seed' do
53
+ args = arguments.merge(seed: 1234)
54
+ set = described_class.new(**args)
55
+ other_set = described_class.new(**args)
56
+
57
+ expect(set.to_s).to eq other_set.to_s
58
+ end
50
59
 
60
+ it 'returns different texts for the different seeds' do
61
+ set = described_class.new(**arguments.merge(seed: 1))
62
+ other_set = described_class.new(**arguments.merge(seed: 2))
63
+
64
+ expect(set.to_s).to_not eq other_set.to_s
65
+ end
66
+ end
67
+
68
+ describe '#seed' do
69
+ it 'returns the seed the set was initialized with' do
70
+ seed = Random.rand(100)
71
+ args = arguments.merge(seed: seed)
72
+ expect(described_class.new(**args).seed).to eq seed
73
+ end
74
+
75
+ it "returns a random seed if none was given" do
76
+ set = described_class.new(**arguments)
77
+ expect(set.seed).to_not be_nil
78
+ expect(set.seed).to be_a Integer
79
+ end
80
+ end
81
+ end
51
82
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stroop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Götze
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-21 00:00:00.000000000 Z
11
+ date: 2020-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -86,11 +86,13 @@ files:
86
86
  - bin/stroop
87
87
  - lib/stroop.rb
88
88
  - lib/stroop/cli.rb
89
+ - lib/stroop/color_generator.rb
89
90
  - lib/stroop/exceptions.rb
90
91
  - lib/stroop/set.rb
91
92
  - lib/stroop/version.rb
92
93
  - spec/spec_helper.rb
93
94
  - spec/stroop/cli_spec.rb
95
+ - spec/stroop/color_generator_spec.rb
94
96
  - spec/stroop/set_spec.rb
95
97
  - stroop.gemspec
96
98
  homepage: https://github.com/paulgoetze/stroop
@@ -112,11 +114,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
114
  - !ruby/object:Gem::Version
113
115
  version: '0'
114
116
  requirements: []
115
- rubygems_version: 3.0.3
117
+ rubygems_version: 3.1.3
116
118
  signing_key:
117
119
  specification_version: 4
118
120
  summary: Stroop effect
119
121
  test_files:
120
122
  - spec/spec_helper.rb
121
123
  - spec/stroop/cli_spec.rb
124
+ - spec/stroop/color_generator_spec.rb
122
125
  - spec/stroop/set_spec.rb