nonsense 1.0.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,133 @@
1
+ require 'yaml'
2
+
3
+ class Nonsense
4
+ VERSION = '1.0.0'
5
+
6
+ attr_accessor :template, :data, :state, :debug
7
+
8
+ module Data
9
+ DEFAULT = YAML.load_file(File.dirname(__FILE__) + '/default.yml')
10
+ end
11
+
12
+ def initialize(template, data = {})
13
+ @template = template
14
+ @data = Data::DEFAULT.merge(data)
15
+ @state = {}
16
+ end
17
+
18
+ def result
19
+ parse_template self.template
20
+ end
21
+
22
+ def parse_template(t) #:nodoc:
23
+ return '' unless t
24
+ t = t.dup
25
+ copy = t.gsub!(/\{[^}]+\}/) { |tag| parse tag[1..-2] }
26
+ copy ? copy : t
27
+ end
28
+
29
+ def parse(tag) #:nodoc:
30
+ return '' unless tag
31
+ parse_case = nil
32
+ parsed = case tag
33
+ when /^#(\d+)-(\d+)$/ then number_in_range($1.to_i, $2.to_i).to_s
34
+ when /^\@([^|]+)$/ then format_current_time($1)
35
+ when /^\@(.*?)\|\$(\w+)\|(\d+)$/ then format_assigned_time($1, $2, $3)
36
+ when /^\@(.*?)\|(\d+)\|(\d+)$/ then format_current_time($1, $2.to_i, $3.to_i)
37
+ when /^\[(.*)$/ then choose_from_list($1)
38
+ when /^\\(.*)$/ then embed_character($1)
39
+ when /^(.*?):=(.*)$/ then assign_command($1, $2)
40
+ when /^(.*?)=(.*)$/ then assign_literal($1, $2)
41
+ when /^[\$<](.*)$/
42
+ parse_case = $1
43
+ retrieve_assigned($1)
44
+ when /^(.*?)#(\d+)-(\d+)$/
45
+ parse_case = $1
46
+ retrieve_multiple($1, $2.to_i, $3.to_i)
47
+ else
48
+ parse_case = tag
49
+ retrieve_data tag.gsub(/\W/, '')
50
+ end
51
+
52
+ parsed = parse_template(parsed)
53
+
54
+ parsed = adjust_case parsed, parse_case
55
+ end
56
+
57
+ def number_in_range(low, high) #:nodoc:
58
+ rand(high - low).to_i + low
59
+ end
60
+
61
+ def format_current_time(format, low = nil, high = nil) #:nodoc:
62
+ diff = (low && high) ? number_in_range(low, high) : 0
63
+ (Time.now - diff).strftime format
64
+ end
65
+
66
+ def format_assigned_time(format, key, high) #:nodoc:
67
+ existing_time = state[key.downcase]
68
+ elapsed = rand(high)
69
+ time = if existing_time
70
+ existing_time - elapsed
71
+ else
72
+ Time.now - elapsed
73
+ end
74
+ state[key] = time
75
+ time.strftime format
76
+ end
77
+
78
+ def choose_from_list(list) #:nodoc:
79
+ items = list.split('|')
80
+ choice = if items.size > 1
81
+ items[rand(items.size)] # pick one of the elements
82
+ else
83
+ rand(2) == 0 ? items[0] : '' # pick it or pick nothing
84
+ end
85
+ end
86
+
87
+ def embed_character(character) #:nodoc:
88
+ case character
89
+ when 'n' then "\n" # newline
90
+ when '0' then '' # null
91
+ when 'L' then '{' # left bracket
92
+ when 'R' then '}' # right bracket
93
+ when /^\d+/ then character.to_i.chr # ASCII code in decimal
94
+ else '' # not in list
95
+ end
96
+ end
97
+
98
+ def assign_command(key, command) #:nodoc:
99
+ state[key.downcase] = parse(command)
100
+ ''
101
+ end
102
+
103
+ def assign_literal(key, value) #:nodoc:
104
+ state[key.downcase] = value
105
+ ''
106
+ end
107
+
108
+ def retrieve_assigned(key) #:nodoc:
109
+ value = state[key.downcase]
110
+ value ? value : parse(key)
111
+ end
112
+
113
+ def retrieve_multiple(key, low, high) #:nodoc:
114
+ n = number_in_range(low, high)
115
+ return '' if n == 0
116
+ (1..n).collect { |i| parse(key) }.join(" ")
117
+ end
118
+
119
+ def retrieve_data(key) #:nodoc:
120
+ return '' unless key
121
+ choices = data[key.downcase]
122
+ choices ? choices[rand(choices.size)] : ''
123
+ end
124
+
125
+ def adjust_case(parsed, parse_case) #:nodoc:
126
+ case parse_case
127
+ when /^[A-Z0-9]+$/ then parsed.upcase
128
+ when /^[a-z0-9]+$/ then parsed.downcase
129
+ when /^\^/ then parsed.capitalize
130
+ else parsed
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,241 @@
1
+ require File.dirname(__FILE__) + "/../lib/nonsense"
2
+ require 'rubygems'
3
+ require 'test/spec'
4
+ require 'mocha'
5
+ require 'time'
6
+
7
+ describe 'nonsense' do
8
+ attr_accessor :nonsense
9
+
10
+ before do
11
+ @nonsense = Nonsense.new(:template)
12
+ end
13
+
14
+ it "should parse the template to get the result" do
15
+ nonsense.expects(:parse_template).with(:template)
16
+ nonsense.result
17
+ end
18
+
19
+ it "should parse a template" do
20
+ nonsense.expects(:parse).with('template')
21
+ nonsense.parse_template "{template}"
22
+ end
23
+
24
+ it "should parse a number range" do
25
+ tag = "#2-5"
26
+ nonsense.expects(:number_in_range).with(2, 5)
27
+
28
+ nonsense.parse tag
29
+ end
30
+
31
+ it "should pick a random number in a range" do
32
+ nonsense.expects(:rand).with(3).returns(2)
33
+ number = nonsense.number_in_range(2, 5)
34
+
35
+ number.should == 4
36
+ end
37
+
38
+ it "should parse a time" do
39
+ tag = "@%A"
40
+ nonsense.expects(:format_current_time).with('%A')
41
+
42
+ nonsense.parse tag
43
+ end
44
+
45
+ it "formats current time" do
46
+ time = Time.parse('2008-05-01 19:00')
47
+ Time.expects(:now).returns(time)
48
+
49
+ nonsense.format_current_time('%Y').should == "2008"
50
+ end
51
+
52
+ it "should parse a time and range" do
53
+ tag = "@%A|0|86400"
54
+ nonsense.expects(:format_current_time).with('%A', 0, 86400)
55
+
56
+ nonsense.parse tag
57
+ end
58
+
59
+ it "formats current time less a random value in range" do
60
+ time = Time.parse('2008-05-01 19:00')
61
+ Time.expects(:now).returns(time)
62
+ nonsense.expects(:number_in_range).with(0, 86400).returns(0)
63
+
64
+ nonsense.format_current_time('%A', 0, 86400).should == "Thursday"
65
+ end
66
+
67
+ it "should parse a time and store in key" do
68
+ tag = "@%A|$key|86400"
69
+ nonsense.expects(:format_assigned_time).with('%A', 'key', '86400')
70
+
71
+ nonsense.parse tag
72
+ end
73
+
74
+ it "stores time for later use" do
75
+ time = Time.parse('2008-05-01 19:00')
76
+ Time.expects(:now).returns(time)
77
+ nonsense.expects(:rand).returns(0)
78
+
79
+ nonsense.format_assigned_time('%A', 'key', 0)
80
+ nonsense.state['key'].should == time
81
+ end
82
+
83
+ it "retrieves time from earlier" do
84
+ time = Time.parse('2008-05-01 19:00')
85
+ nonsense.state['key'] = time
86
+ nonsense.expects(:rand).returns(0)
87
+
88
+ nonsense.format_assigned_time('%A', 'key', 0)
89
+ nonsense.state['key'].should == time
90
+ end
91
+
92
+ it "should parse list of values" do
93
+ tag = "[list of values"
94
+ nonsense.expects(:choose_from_list).with('list of values')
95
+
96
+ nonsense.parse tag
97
+ end
98
+
99
+ it "returns a random value from list of multiple values" do
100
+ nonsense.expects(:rand).returns(1)
101
+ nonsense.choose_from_list("item 1|item 2|item 3").should == "item 2"
102
+ end
103
+
104
+ it "randomly returns value when list has one item" do
105
+ nonsense.expects(:rand).returns(0)
106
+ nonsense.choose_from_list("item 1").should == "item 1"
107
+ end
108
+
109
+ it "randomly returns nothing when list has one item" do
110
+ nonsense.expects(:rand).returns(1)
111
+ nonsense.choose_from_list("item 1").should == ''
112
+ end
113
+
114
+ it "should parse special characters" do
115
+ tag = '\n'
116
+ nonsense.expects(:embed_character).with('n')
117
+
118
+ nonsense.parse tag
119
+ end
120
+
121
+ it "returns newline from embeded n" do
122
+ nonsense.embed_character('n').should == "\n"
123
+ end
124
+
125
+ it "returns nothing from embedded 0" do
126
+ nonsense.embed_character('0').should == ''
127
+ end
128
+
129
+ it "returns left bracket from embedded L" do
130
+ nonsense.embed_character('L').should == '{'
131
+ end
132
+
133
+ it "returns right bracket from embedded R" do
134
+ nonsense.embed_character('R').should == '}'
135
+ end
136
+
137
+ it "returns ASCII from embedded int" do
138
+ nonsense.embed_character('65').should == 'A'
139
+ end
140
+
141
+ it "returns nothing for unknown char" do
142
+ nonsense.embed_character('z').should == ''
143
+ end
144
+
145
+ it "assigns a command for later use" do
146
+ tag = "key:=command"
147
+ nonsense.expects(:assign_command).with('key', 'command')
148
+ nonsense.parse tag
149
+ end
150
+
151
+ it "returns nothing when assigning a command" do
152
+ nonsense.assign_command('key', 'command').should == ''
153
+ end
154
+
155
+ it "parses the command for later use" do
156
+ nonsense.expects(:parse).returns('result')
157
+ nonsense.assign_command('key', 'command')
158
+ nonsense.state['key'].should == 'result'
159
+ end
160
+
161
+ it "assigns a command for later use" do
162
+ tag = "key=literal"
163
+ nonsense.expects(:assign_literal).with('key', 'literal')
164
+ nonsense.parse tag
165
+ end
166
+
167
+ it "returns nothing when assigning a literal" do
168
+ nonsense.assign_literal('key', 'literal').should == ''
169
+ end
170
+
171
+ it "stores the command for later use" do
172
+ nonsense.assign_literal('key', 'literal')
173
+ nonsense.state['key'].should == 'literal'
174
+ end
175
+
176
+ it "retrieves previously assigned earlier" do
177
+ tag = "$key"
178
+ nonsense.expects(:retrieve_assigned).with('key')
179
+ nonsense.parse tag
180
+ end
181
+
182
+ it "retrieves the assigned value by the key" do
183
+ nonsense.state['key'] = 'value'
184
+ nonsense.retrieve_assigned('key').should == 'value'
185
+ end
186
+
187
+ it "retrieves value multiple times" do
188
+ tag = 'tag#1-4'
189
+ nonsense.expects(:retrieve_multiple).with('tag', 1, 4)
190
+ nonsense.parse tag
191
+ end
192
+
193
+ it "should retrieve parsed value of tag a random number of times" do
194
+ nonsense.expects(:number_in_range).with(1, 4).returns(2)
195
+ nonsense.expects(:parse).times(2)
196
+ nonsense.retrieve_multiple('tag', 1, 4)
197
+ end
198
+
199
+ it "should retrieve parsed value of tag a random number of times" do
200
+ nonsense.expects(:number_in_range).with(1, 4).returns(2)
201
+ nonsense.stubs(:parse).returns('result')
202
+ nonsense.retrieve_multiple('tag', 1, 4).should == "result result"
203
+ end
204
+
205
+ it "retrieves previously assigned earlier" do
206
+ tag = "tag"
207
+ nonsense.expects(:retrieve_data).with('tag')
208
+ nonsense.parse tag
209
+ end
210
+
211
+ it "returns nothing when retrieving data with no key" do
212
+ nonsense.retrieve_data(nil).should == ''
213
+ end
214
+
215
+ it "returns nothing when there is not data that matches key" do
216
+ nonsense.retrieve_data('nothing').should == ''
217
+ end
218
+
219
+ it "returns random choices that matches key" do
220
+ nonsense.data['key'] = ['choice 1', 'choice 2']
221
+ nonsense.expects(:rand).returns(1)
222
+ nonsense.retrieve_data('key').should == 'choice 2'
223
+ end
224
+
225
+ it "upcases the result when key is all caps" do
226
+ nonsense.adjust_case('result', 'KEY').should == 'RESULT'
227
+ end
228
+
229
+ it "downcases the result when key is all lowercase" do
230
+ nonsense.adjust_case('Result', 'key').should == 'result'
231
+ end
232
+
233
+ it "capitalizes the result when key starts with ^" do
234
+ nonsense.adjust_case('result', '^Key').should == 'Result'
235
+ end
236
+
237
+ it "returns the result when the case is not recognize" do
238
+ nonsense.adjust_case('RESult', 'kEy').should == 'RESult'
239
+ end
240
+
241
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nonsense
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Geoffrey Dagley
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-25 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.6.0
24
+ version:
25
+ description: "port of http://nonsense.sourceforge.net/ Taken from Nonsense website: Nonsense generates random (and sometimes humorous) text from datafiles and templates using a very simple, recursive grammar. It's like having a million monkeys sitting in front of a million typewriters, without having to feed or clean up after them."
26
+ email:
27
+ - gdagley@gmail.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - LICENSE.txt
35
+ - Manifest.txt
36
+ - README.txt
37
+ files:
38
+ - History.txt
39
+ - LICENSE.txt
40
+ - Manifest.txt
41
+ - README.txt
42
+ - Rakefile
43
+ - lib/default.yml
44
+ - lib/nonsense.rb
45
+ - test/test_nonsense.rb
46
+ has_rdoc: true
47
+ homepage:
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --main
53
+ - README.txt
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ requirements: []
69
+
70
+ rubyforge_project: nonsense
71
+ rubygems_version: 1.3.5
72
+ signing_key:
73
+ specification_version: 2
74
+ summary: "port of http://nonsense.sourceforge.net/ Taken from Nonsense website: Nonsense generates random (and sometimes humorous) text from datafiles and templates using a very simple, recursive grammar"
75
+ test_files:
76
+ - test/test_nonsense.rb