nonsense 1.0.0

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