codeless_code 0.1.7 → 0.1.8
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/.gitmodules +1 -1
- data/.reek.yml +14 -0
- data/.rubocop.yml +18 -0
- data/.ruby-version +1 -0
- data/{test/test_codeless_code.rb → .travis.yml} +12 -10
- data/Gemfile +5 -0
- data/Gemfile.lock +21 -0
- data/Guardfile +13 -1
- data/README.md +6 -0
- data/Rakefile +26 -11
- data/VERSION +1 -1
- data/bin/codeless_code +3 -1
- data/codeless_code.gemspec +33 -12
- data/lib/codeless_code/catalog.rb +3 -1
- data/lib/codeless_code/cli.rb +56 -24
- data/lib/codeless_code/commands/filter_fables.rb +15 -10
- data/lib/codeless_code/commands/list_translations.rb +3 -0
- data/lib/codeless_code/fable.rb +42 -53
- data/lib/codeless_code/fable_set.rb +8 -6
- data/lib/codeless_code/filters/builders.rb +4 -2
- data/lib/codeless_code/filters/composite.rb +3 -1
- data/lib/codeless_code/filters/date.rb +40 -30
- data/lib/codeless_code/filters/from_options.rb +45 -28
- data/lib/codeless_code/filters/headers/base.rb +61 -0
- data/lib/codeless_code/filters/{header_integer.rb → headers/integer.rb} +16 -19
- data/lib/codeless_code/filters/{header_string.rb → headers/string.rb} +12 -22
- data/lib/codeless_code/filters/lang.rb +3 -0
- data/lib/codeless_code/filters/translator.rb +7 -2
- data/lib/codeless_code/filters.rb +16 -8
- data/lib/codeless_code/formats/base.rb +20 -7
- data/lib/codeless_code/formats/parsers/base.rb +106 -0
- data/lib/codeless_code/formats/parsers/plain.rb +49 -0
- data/lib/codeless_code/formats/parsers/term.rb +79 -0
- data/lib/codeless_code/formats/plain.rb +21 -12
- data/lib/codeless_code/formats/raw.rb +2 -0
- data/lib/codeless_code/formats/term.rb +21 -15
- data/lib/codeless_code/language_set.rb +7 -4
- data/lib/codeless_code/options.rb +5 -3
- data/lib/codeless_code/renderers/fable.rb +13 -8
- data/lib/codeless_code/renderers/term_page.rb +46 -31
- data/lib/codeless_code.rb +119 -106
- data/test/codeless_code/commands/test_filter_fables.rb +89 -0
- data/test/codeless_code/filters/headers/test_integer.rb +86 -0
- data/test/codeless_code/filters/headers/test_string.rb +86 -0
- data/test/codeless_code/filters/test_builders.rb +4 -2
- data/test/codeless_code/filters/test_composite.rb +70 -0
- data/test/codeless_code/filters/test_date.rb +99 -0
- data/test/codeless_code/filters/test_langs.rb +50 -0
- data/test/codeless_code/filters/test_translator.rb +51 -0
- data/test/codeless_code/renderers/test_fable.rb +98 -0
- data/test/codeless_code/renderers/test_term_page.rb +87 -0
- data/test/codeless_code/test_catalog.rb +12 -5
- data/test/codeless_code/test_cli.rb +85 -0
- data/test/codeless_code/test_fable.rb +19 -10
- data/test/codeless_code/test_fable_set.rb +17 -5
- data/test/codeless_code/test_language_set.rb +16 -3
- data/test/codeless_code/test_options.rb +3 -11
- data/test/helper.rb +36 -10
- data/test/support/fs.rb +103 -0
- metadata +65 -11
- data/.document +0 -5
- data/data/README.md +0 -34
- data/lib/codeless_code/formats/plain_generator.rb +0 -157
- data/lib/codeless_code/formats/term_generator.rb +0 -167
- data/test/codeless_code/filters/test_header_integer.rb +0 -82
- data/test/codeless_code/filters/test_header_string.rb +0 -82
data/lib/codeless_code.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -15,6 +17,7 @@
|
|
15
17
|
# this program. If not, see <https://www.gnu.org/licenses/>.
|
16
18
|
require 'pathname'
|
17
19
|
|
20
|
+
# +CodelessCode+ filters and renders {Fable fables}.
|
18
21
|
module CodelessCode
|
19
22
|
autoload :Catalog, 'codeless_code/catalog'
|
20
23
|
autoload :Cli, 'codeless_code/cli'
|
@@ -24,20 +27,28 @@ module CodelessCode
|
|
24
27
|
autoload :LanguageSet, 'codeless_code/language_set'
|
25
28
|
autoload :Options, 'codeless_code/options'
|
26
29
|
|
30
|
+
# The "main" methods this applications supports
|
27
31
|
module Commands
|
28
32
|
autoload :FilterFables, 'codeless_code/commands/filter_fables'
|
29
33
|
autoload :ListTranslations, 'codeless_code/commands/list_translations'
|
30
34
|
end
|
31
35
|
|
36
|
+
# The methods in which {Fable fables} may be rendered as text.
|
32
37
|
module Formats
|
33
38
|
autoload :Base, 'codeless_code/formats/base'
|
34
39
|
autoload :Plain, 'codeless_code/formats/plain'
|
35
|
-
autoload :PlainGenerator, 'codeless_code/formats/plain_generator'
|
36
40
|
autoload :Raw, 'codeless_code/formats/raw'
|
37
41
|
autoload :Term, 'codeless_code/formats/term'
|
38
|
-
|
42
|
+
|
43
|
+
# Custom parsers for the syntax tree generated by the +MediaCloth+ gem.
|
44
|
+
module Parsers
|
45
|
+
autoload :Base, 'codeless_code/formats/parsers/base'
|
46
|
+
autoload :Plain, 'codeless_code/formats/parsers/plain'
|
47
|
+
autoload :Term, 'codeless_code/formats/parsers/term'
|
48
|
+
end
|
39
49
|
end
|
40
50
|
|
51
|
+
# The methods in which a {Fable fables's} body may be rendered as text.
|
41
52
|
module Renderers
|
42
53
|
autoload :Fable, 'codeless_code/renderers/fable'
|
43
54
|
autoload :TermPage, 'codeless_code/renderers/term_page'
|
@@ -45,7 +56,7 @@ module CodelessCode
|
|
45
56
|
|
46
57
|
VERSION = Pathname.new(__dir__).join('..', 'VERSION').read.strip.freeze
|
47
58
|
DEFAULT_DATA = Pathname.new(__dir__)
|
48
|
-
|
59
|
+
.join('..', 'data', 'the-codeless-code').freeze
|
49
60
|
|
50
61
|
BANNERS = [
|
51
62
|
'%<cmd>s [INFO]',
|
@@ -53,108 +64,110 @@ module CodelessCode
|
|
53
64
|
'%<cmd>s [OPTION]... [FILTER]... [NUMBER]'
|
54
65
|
].freeze
|
55
66
|
|
56
|
-
OPTIONS = proc do |cmd,
|
57
|
-
banner =
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
67
|
+
OPTIONS = proc do |cmd, opt|
|
68
|
+
banner =
|
69
|
+
[[BANNERS[0]] + BANNERS[1..-1].map { |str| "\n #{str}" }].join
|
70
|
+
|
71
|
+
opt.banner = format("Usage: #{banner}", cmd: cmd)
|
72
|
+
opt.separator ''
|
73
|
+
opt.separator 'Print or filter Codeless Code fables.'
|
74
|
+
|
75
|
+
opt.separator ''
|
76
|
+
opt.separator 'Info'
|
77
|
+
opt.boolean '-h', '--help'
|
78
|
+
opt.boolean '--list-translations'
|
79
|
+
opt.boolean '--version'
|
80
|
+
|
81
|
+
opt.separator ''
|
82
|
+
opt.separator 'Options'
|
83
|
+
opt.boolean '-c', '--columns', 'when listing fables, format the output ' \
|
84
|
+
'into columns'
|
85
|
+
opt.array '-e', '--headers', 'headers to include in the list output. ' \
|
86
|
+
'may be repeated'
|
87
|
+
opt.string '-f', '--format', 'one of: raw, plain, or term (default)'
|
88
|
+
opt.string '-o', '--output', 'write to the given file. "-" for STDOUT'
|
89
|
+
opt.string '-p', '--path', 'path to directory of fables. ' \
|
90
|
+
'see github.com/aldesantis/the-codeless-code'
|
91
|
+
opt.boolean '--random', 'select one random fable from the filtered list'
|
92
|
+
opt.string '--random-set', 'select n random fables from the filtered list'
|
93
|
+
opt.boolean '--daily', 'select one fable, randomly, from the filtered ' \
|
94
|
+
'list based on today\'s date'
|
95
|
+
opt.boolean '--trace', 'print full error message if a fable fails to parse'
|
96
|
+
|
97
|
+
opt.string '-s', '--sort', 'when listing fables, sort by the given header'
|
98
|
+
opt.boolean '-r', '--reverse', 'when listing fables, reverse the order'
|
99
|
+
|
100
|
+
opt.separator ''
|
101
|
+
opt.separator 'Series Filters'
|
102
|
+
opt.string '-S', '--series'
|
103
|
+
opt.string '-Ss', '--series-start', 'series starts with'
|
104
|
+
opt.string '-Se', '--series-end', 'series ends with'
|
105
|
+
opt.boolean '-hS', '--has-series', 'has series listed'
|
106
|
+
opt.boolean '-nS', '--no-series', 'no series listed'
|
107
|
+
|
108
|
+
opt.separator ''
|
109
|
+
opt.separator 'Title Filters'
|
110
|
+
opt.string '-T', '--title'
|
111
|
+
opt.string '-Ts', '--title-start', 'title starts with'
|
112
|
+
opt.string '-Te', '--title-end', 'title ends with'
|
113
|
+
opt.boolean '-hT', '--has-title', 'has title listed'
|
114
|
+
opt.boolean '-nT', '--no-title', 'no title listed'
|
115
|
+
|
116
|
+
opt.separator ''
|
117
|
+
opt.separator 'Number Filters'
|
118
|
+
opt.string '-N', '--number', 'number (this is the default argument)'
|
119
|
+
opt.string '-Ng', '--number-gte', 'number or greater'
|
120
|
+
opt.string '-Nl', '--number-lte', 'number or lower'
|
121
|
+
opt.boolean '-hN', '--has-number', 'has number listed'
|
122
|
+
opt.boolean '-nN', '--no-number', 'no number listed'
|
123
|
+
|
124
|
+
opt.separator ''
|
125
|
+
opt.separator 'Language Filters'
|
126
|
+
opt.string '-L', '--lang', 'language code (default: en)'
|
127
|
+
|
128
|
+
opt.separator ''
|
129
|
+
opt.separator 'Translator Filters'
|
130
|
+
opt.string '-R', '--translator', 'translator\'s name (default: first ' \
|
131
|
+
'one, alphabetically)'
|
132
|
+
opt.string '-Rx', '--translator-exact',
|
133
|
+
'translator\'s name, case-sensitive (default: first one, ' \
|
134
|
+
'alphabetically)'
|
135
|
+
|
136
|
+
opt.separator ''
|
137
|
+
opt.separator 'Date Filters'
|
138
|
+
opt.string '-D', '--date', 'publish date'
|
139
|
+
opt.string '-Da', '--date-after', 'publish date or after'
|
140
|
+
opt.string '-Db', '--date-before', 'publish date or before'
|
141
|
+
opt.boolean '-nD', '--no-date', 'no publish date listed'
|
142
|
+
|
143
|
+
opt.separator ''
|
144
|
+
opt.separator 'Geekiness Filters'
|
145
|
+
opt.string '-G', '--geekiness', 'geekiness rating'
|
146
|
+
opt.string '-Gg', '--geekiness-gte', 'geekiness rating or greater'
|
147
|
+
opt.string '-Gl', '--geekiness-lte', 'geekiness rating or lower'
|
148
|
+
opt.boolean '-nG', '--no-geekiness', 'no geekiness rating'
|
149
|
+
|
150
|
+
opt.separator ''
|
151
|
+
opt.separator 'Name Filters'
|
152
|
+
opt.string '-A', '--name'
|
153
|
+
opt.string '-As', '--name-start', 'name starts with'
|
154
|
+
opt.string '-Ae', '--name-end', 'name ends with'
|
155
|
+
opt.boolean '-nA', '--no-name', 'no name listed'
|
156
|
+
|
157
|
+
opt.separator ''
|
158
|
+
opt.separator 'Credits Filters'
|
159
|
+
opt.string '-C', '--credits'
|
160
|
+
opt.string '-Cs', '--credits-start', 'credits starts with'
|
161
|
+
opt.string '-Ce', '--credits-end', 'credits ends with'
|
162
|
+
opt.boolean '-hC', '--has-credits', 'has credits listed'
|
163
|
+
opt.boolean '-nC', '--no-credits', 'no credits listed'
|
164
|
+
|
165
|
+
opt.separator ''
|
166
|
+
opt.separator 'Tagline Filters'
|
167
|
+
opt.string '-I', '--tagline'
|
168
|
+
opt.string '-Is', '--tagline-start', 'tagline starts with'
|
169
|
+
opt.string '-Ie', '--tagline-end', 'tagline ends with'
|
170
|
+
opt.boolean '-hI', '--has-tagline', 'has tagline listed'
|
171
|
+
opt.boolean '-nI', '--no-tagline', 'no tagline listed'
|
159
172
|
end
|
160
173
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# codeless_code filters and prints fables from http://thecodelesscode.com
|
4
|
+
# Copyright (C) 2018 Jon Sangster
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU General Public License as published by the Free Software
|
8
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
9
|
+
# version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License along with
|
17
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
require 'helper'
|
19
|
+
require 'minitest/mock'
|
20
|
+
|
21
|
+
module Commands
|
22
|
+
class TestFilterFables < UnitTest
|
23
|
+
def setup
|
24
|
+
@pager = ENV.delete('PAGER')
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
ENV['PAGER'] = @pager
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_call_default
|
32
|
+
expected = ['00123 Test Case', '00234 Test Case 2', ''].join("\n")
|
33
|
+
assert_output(expected) { command.call }
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_call_single_by_number
|
37
|
+
[
|
38
|
+
" Test Case\n" \
|
39
|
+
"==================\n" \
|
40
|
+
"Number: 123\n" \
|
41
|
+
" Date: 2018-12-23\n" \
|
42
|
+
"------------------\n" \
|
43
|
+
"\n" \
|
44
|
+
"body\n"
|
45
|
+
].each { |expected| assert_output(expected) { command('123').call } }
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_call_match_none
|
49
|
+
assert_output(nil, "None found.\n") { command('9999').call }
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_call_reverse
|
53
|
+
expected = ['00234 Test Case 2', '00123 Test Case', ''].join("\n")
|
54
|
+
assert_output(expected) { command('-r').call }
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_call_sort
|
58
|
+
expected = ['00234 Test Case 2', '00123 Test Case', ''].join("\n")
|
59
|
+
assert_output(expected) { command('-s', 'Date').call }
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def command(*args)
|
65
|
+
opts = options(*args)
|
66
|
+
opts.instance_variable_set(:@data_dir, fake_fs)
|
67
|
+
Commands::FilterFables.new(catalog, opts)
|
68
|
+
end
|
69
|
+
|
70
|
+
def fake_fs # rubocop:disable Metrics/MethodLength
|
71
|
+
FakeDir.new('/').tap do |fs|
|
72
|
+
fs.create_path('en-test/case-123.txt', <<-FABLE)
|
73
|
+
Title: Test Case
|
74
|
+
Number: 123
|
75
|
+
Date: 2018-12-23
|
76
|
+
|
77
|
+
body
|
78
|
+
FABLE
|
79
|
+
fs.create_path('en-test/case-234.txt', <<-FABLE)
|
80
|
+
Title: Test Case 2
|
81
|
+
Number: 234
|
82
|
+
Date: 2000-12-23
|
83
|
+
|
84
|
+
body 2
|
85
|
+
FABLE
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# codeless_code filters and prints fables from http://thecodelesscode.com
|
4
|
+
# Copyright (C) 2018 Jon Sangster
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU General Public License as published by the Free Software
|
8
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
9
|
+
# version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License along with
|
17
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
require 'helper'
|
19
|
+
|
20
|
+
module Filters
|
21
|
+
module Headers
|
22
|
+
class TestInteger < UnitTest
|
23
|
+
def test_enabled?
|
24
|
+
refute_predicate filter('Test'), :enabled?
|
25
|
+
refute_predicate filter('Test', exclude: false), :enabled?
|
26
|
+
|
27
|
+
assert_predicate filter('Test', exact: 1), :enabled?
|
28
|
+
assert_predicate filter('Test', min: 1), :enabled?
|
29
|
+
assert_predicate filter('Test', max: 1), :enabled?
|
30
|
+
assert_predicate filter('Test', exclude: true), :enabled?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_call_exact
|
34
|
+
assert_filter(exact: 100)
|
35
|
+
|
36
|
+
refute_filter(exact: 123)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_call_min
|
40
|
+
assert_filter(min: 99)
|
41
|
+
assert_filter(min: 100)
|
42
|
+
|
43
|
+
refute_filter(min: 101)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_call_max
|
47
|
+
assert_filter(max: 100)
|
48
|
+
assert_filter(max: 101)
|
49
|
+
|
50
|
+
refute_filter(max: 99)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_call_exclude
|
54
|
+
assert_filter('MissingHeader', exclude: true)
|
55
|
+
|
56
|
+
refute_filter(exclude: true)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def filter(key, **opts)
|
62
|
+
Filters::Headers::Integer.new(key, **opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
def assert_filter(key = 'Test', **opts)
|
66
|
+
fab = create_fable
|
67
|
+
filt = filter(key, **opts)
|
68
|
+
assert filt.call(fab), format('Expected %p to match %p', opts, fab)
|
69
|
+
end
|
70
|
+
|
71
|
+
def refute_filter(key = 'Test', **opts)
|
72
|
+
fab = create_fable
|
73
|
+
filt = filter(key, **opts)
|
74
|
+
refute filt.call(fab), format('Expected %p not to match %p', opts, fab)
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_fable
|
78
|
+
mock_fable(<<-BODY.strip)
|
79
|
+
Test: 100
|
80
|
+
|
81
|
+
body
|
82
|
+
BODY
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# codeless_code filters and prints fables from http://thecodelesscode.com
|
4
|
+
# Copyright (C) 2018 Jon Sangster
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU General Public License as published by the Free Software
|
8
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
9
|
+
# version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License along with
|
17
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
require 'helper'
|
19
|
+
|
20
|
+
module Filters
|
21
|
+
module Headers
|
22
|
+
class TestString < UnitTest
|
23
|
+
def test_enabled?
|
24
|
+
refute_predicate filter('Test'), :enabled?
|
25
|
+
refute_predicate filter('Test', exclude: false), :enabled?
|
26
|
+
|
27
|
+
assert_predicate filter('Test', exact: 'foo'), :enabled?
|
28
|
+
assert_predicate filter('Test', start_with: 'foo'), :enabled?
|
29
|
+
assert_predicate filter('Test', end_with: 'foo'), :enabled?
|
30
|
+
assert_predicate filter('Test', exclude: true), :enabled?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_call_exact
|
34
|
+
assert_filter(exact: 'some text')
|
35
|
+
|
36
|
+
refute_filter(exact: 'something else')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_call_start_with
|
40
|
+
assert_filter(start_with: 'some')
|
41
|
+
assert_filter(start_with: '')
|
42
|
+
|
43
|
+
refute_filter(start_with: 'something else')
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_call_end_with
|
47
|
+
assert_filter(end_with: 'text')
|
48
|
+
assert_filter(end_with: '')
|
49
|
+
|
50
|
+
refute_filter(end_with: 'something else')
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_call_exclude
|
54
|
+
assert_filter('MissingHeader', exclude: true)
|
55
|
+
|
56
|
+
refute_filter(exclude: true)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def filter(key, **opts)
|
62
|
+
Filters::Headers::String.new(key, **opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
def assert_filter(key = 'Test', **opts)
|
66
|
+
fab = create_fable
|
67
|
+
filt = filter(key, **opts)
|
68
|
+
assert filt.call(fab), format('Expected %p to match %p', opts, fab)
|
69
|
+
end
|
70
|
+
|
71
|
+
def refute_filter(key = 'Test', **opts)
|
72
|
+
fab = create_fable
|
73
|
+
filt = filter(key, **opts)
|
74
|
+
refute filt.call(fab), format('Expected %p not to match %p', opts, fab)
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_fable
|
78
|
+
mock_fable(<<-BODY.strip)
|
79
|
+
Test: some text
|
80
|
+
|
81
|
+
body
|
82
|
+
BODY
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# codeless_code filters and prints fables from http://thecodelesscode.com
|
2
4
|
# Copyright (C) 2018 Jon Sangster
|
3
5
|
#
|
@@ -19,13 +21,13 @@ module Filters
|
|
19
21
|
class TestBuilders < UnitTest
|
20
22
|
def test_header_integer_filter
|
21
23
|
assert_kind_of Class, Filters::Builders.header_integer_filter('FooOne')
|
22
|
-
assert_kind_of Filters::
|
24
|
+
assert_kind_of Filters::Headers::Integer,
|
23
25
|
Filters::Builders.header_integer_filter('FooTwo').new
|
24
26
|
end
|
25
27
|
|
26
28
|
def test_header_string_filter
|
27
29
|
assert_kind_of Class, Filters::Builders.header_string_filter('BarOne')
|
28
|
-
assert_kind_of Filters::
|
30
|
+
assert_kind_of Filters::Headers::String,
|
29
31
|
Filters::Builders.header_string_filter('BarTwo').new
|
30
32
|
end
|
31
33
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# codeless_code filters and prints fables from http://thecodelesscode.com
|
4
|
+
# Copyright (C) 2018 Jon Sangster
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify it under
|
7
|
+
# the terms of the GNU General Public License as published by the Free Software
|
8
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
9
|
+
# version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
12
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
13
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
14
|
+
# details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License along with
|
17
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
18
|
+
require 'helper'
|
19
|
+
|
20
|
+
module Filters
|
21
|
+
class TestComposite < UnitTest
|
22
|
+
def test_enabled?
|
23
|
+
assert_predicate filter(matching_filter), :enabled?
|
24
|
+
assert_predicate filter(matchless_filter), :enabled?
|
25
|
+
assert_predicate filter(filter(matching_filter)), :enabled?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_not_enabled?
|
29
|
+
refute_predicate filter, :enabled?
|
30
|
+
refute_predicate filter(filter(filter)), :enabled?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_call_matching
|
34
|
+
assert filter(matching_filter).call(create_fable),
|
35
|
+
'Expected composite filter to match'
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_call_matchless
|
39
|
+
refute filter(matchless_filter).call(create_fable),
|
40
|
+
'Expected composite filter to match'
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_call_empty
|
44
|
+
refute filter.call(create_fable),
|
45
|
+
'Expected an empty composite to match nothing'
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def filter(*filters)
|
51
|
+
Filters::Composite.new(*filters)
|
52
|
+
end
|
53
|
+
|
54
|
+
def matching_filter
|
55
|
+
Filters::Number.new(exact: 123)
|
56
|
+
end
|
57
|
+
|
58
|
+
def matchless_filter
|
59
|
+
Filters::Date.new(exact: '2018')
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_fable
|
63
|
+
mock_fable(<<-BODY.strip)
|
64
|
+
Number: 123
|
65
|
+
|
66
|
+
body
|
67
|
+
BODY
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|