codeless_code 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|