table_of_truth 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 50bb9868581d6c991ac2f8e69fdfcd26971f7ea512470d95e237e9e3c8b85fc1
4
+ data.tar.gz: f37b31b1c28366d72b5df453ff7337f38750a5a48ee6496a3779d0a0089cbd5f
5
+ SHA512:
6
+ metadata.gz: d99d102d9498a035ca8dc7a8d182a0915f1d3244fe6d4eb6371cf79a2ab3acb14528766807603cccafbf96f308e8382343a823b16dc7a6133fb9ca27d160bc2b
7
+ data.tar.gz: 45ac8bf7e63b557f40ba0ddeca77e069558c97c57bb0e16aaf7dac3ad8ec9b3f45b61e991a9a07059cfe796d5837db4698eb74d694ce18d31e33280f60ebb036
@@ -0,0 +1,7 @@
1
+ require_relative 'table_of_truth/table'
2
+
3
+ module TableOfTruth
4
+ def self.new(colorize: true, &block)
5
+ Table.new(colorize: colorize, &block)
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ module TableOfTruth
2
+ class DSL
3
+ # @return [Hash<(String or Symbol)->Array>]
4
+ attr_reader :inputs
5
+ # @return [Array<String or Symbol>]
6
+ attr_reader :input_names
7
+ # @return [Hash<(String or Symbol)->Proc>]
8
+ attr_reader :expressions
9
+ # @return [Array<String or Symbol>]
10
+ attr_reader :expression_names
11
+
12
+ def initialize
13
+ @inputs = {}
14
+ @input_names = []
15
+ @expressions = {}
16
+ @expression_names = []
17
+ end
18
+
19
+ # @param name [String or Symbol]
20
+ # @param block [Proc]
21
+ # @return [void]
22
+ def expression(name, &block)
23
+ @expressions[name] = block
24
+ @expression_names << name
25
+ end
26
+
27
+ # @param name [String or Symbol]
28
+ # @return [void]
29
+ def input(name, values = [false, true])
30
+ @inputs[name] = values
31
+ @input_names << name
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ module TableOfTruth
2
+ class Input
3
+ # @param inputs [Hash<(String or Symbol)->Boolean>]
4
+ def initialize(inputs)
5
+ @inputs = inputs
6
+ @inputs.each { |key, value| define_singleton_method(key) { value } }
7
+ end
8
+
9
+ # @param key [String or Symbol]
10
+ # @return [Boolean]
11
+ def [](key)
12
+ if @inputs.key?(key.to_s)
13
+ @inputs[key.to_s]
14
+ elsif @inputs.key?(key.to_sym)
15
+ @inputs[key.to_sym]
16
+ else
17
+ raise KeyError, "key not found: #{key}"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,93 @@
1
+ require 'colorize'
2
+ require 'stringio'
3
+ require_relative 'dsl'
4
+ require_relative 'input'
5
+
6
+ module TableOfTruth
7
+ class Table
8
+ # @return [Hash<(String or Symbol)->Array>]
9
+ attr_reader :inputs
10
+ # @return [Array<String or Symbol>]
11
+ attr_reader :input_names
12
+ # @return [Hash<(String or Symbol)->Proc>]
13
+ attr_reader :expressions
14
+ # @return [Array<String or Symbol>]
15
+ attr_reader :expression_names
16
+
17
+ def initialize(colorize: true, &block)
18
+ String.disable_colorization = !colorize
19
+
20
+ dsl = DSL.new
21
+ dsl.instance_eval(&block)
22
+
23
+ @inputs = dsl.inputs
24
+ @input_names = dsl.input_names
25
+ @expressions = dsl.expressions
26
+ @expression_names = dsl.expression_names
27
+ end
28
+
29
+ # @return [Array<Hash{String->Boolean}>]
30
+ def results
31
+ @results ||= input_table.map do |inputs|
32
+ result = inputs.dup
33
+ expressions.each { |name, expression| result[name] = expression.call(Input.new(inputs)) }
34
+
35
+ result
36
+ end
37
+ end
38
+
39
+ # @return [void]
40
+ def print!
41
+ builder = StringIO.new
42
+
43
+ # Header
44
+ input_header = input_names.join(' | ')
45
+ expression_header = expression_names.join(' | ')
46
+ builder.puts("#{input_header} || #{expression_header}")
47
+
48
+ # Rows
49
+ results.each do |result|
50
+ inputs_string = input_names.map { |name| output_string(result[name]).center(name.length) }.join(' | ')
51
+
52
+ outputs_string = expression_names.map { |name| output_string(result[name]).center(name.length) }.join(' | ')
53
+ outputs = expression_names.map { |name| result[name] }
54
+ outputs_string = outputs.uniq.length == 1 ? outputs_string.on_green : outputs_string.on_red
55
+
56
+ builder.puts [inputs_string, outputs_string].join(' || ')
57
+ end
58
+
59
+ puts builder.string
60
+ end
61
+
62
+ # @return [Boolean]
63
+ def equivalent?
64
+ results.all? { |result| result.values_at(*expression_names).uniq.length == 1 }
65
+ end
66
+
67
+ private
68
+
69
+ # @param value [Object]
70
+ # @return [String]
71
+ def output_string(value)
72
+ case value
73
+ when true then '✔'
74
+ when false then '✗'
75
+ when nil then '-'
76
+ else value.to_s
77
+ end
78
+ end
79
+
80
+ # @param names [Array<[String]>]
81
+ # @return [Array<Hash{String->Boolean}>]
82
+ def input_table(names = input_names)
83
+ return [{}] if names.empty?
84
+
85
+ names = names.dup
86
+ name = names.shift
87
+ table = input_table(names)
88
+ inputs[name].each_with_object([]) do |value, lines|
89
+ lines.concat(table.map { |line| line.merge(name => value) })
90
+ end
91
+ end
92
+ end
93
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: table_of_truth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Booth
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-11-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.13.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.13.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ description:
56
+ email: andrew@andrewbooth.xyz
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - lib/table_of_truth.rb
62
+ - lib/table_of_truth/dsl.rb
63
+ - lib/table_of_truth/input.rb
64
+ - lib/table_of_truth/table.rb
65
+ homepage: https://github.com/broothie/table_of_truth#readme
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubygems_version: 3.1.3
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: A gem for comparing boolean expressions
88
+ test_files: []