structr 0.0.2
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.
- data/.gitignore +5 -0
- data/.watchr +21 -0
- data/README.rdoc +74 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/examples/invoice.rb +42 -0
- data/examples/top.rb +47 -0
- data/lib/structr.rb +112 -0
- data/structr.gemspec +57 -0
- data/test/helper.rb +6 -0
- data/test/test_field_descriptor.rb +31 -0
- data/test/test_structr.rb +146 -0
- metadata +86 -0
data/.watchr
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
def run(*args)
|
3
|
+
system "ruby -rubygems -Ilib:test #{args.join(' ')}"
|
4
|
+
end
|
5
|
+
|
6
|
+
def run_tests
|
7
|
+
system "rake test"
|
8
|
+
end
|
9
|
+
|
10
|
+
def underscore(file)
|
11
|
+
file.gsub('/', '_')
|
12
|
+
end
|
13
|
+
|
14
|
+
watch('test/test_.*\.rb') {|md| run md[0] }
|
15
|
+
watch('lib/(.*)\.rb') { run_tests }
|
16
|
+
watch('test/helper.rb') { run_tests }
|
17
|
+
|
18
|
+
run_tests
|
19
|
+
|
20
|
+
Signal.trap("QUIT") { abort("\n") }
|
21
|
+
Signal.trap("INT") { run_tests }
|
data/README.rdoc
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
= Structr
|
2
|
+
|
3
|
+
Bind plain text to Ruby classes.
|
4
|
+
NO TESTS!
|
5
|
+
|
6
|
+
Inspired by ROXML http://github.com/Empact/roxml/tree/master
|
7
|
+
|
8
|
+
== Usage
|
9
|
+
|
10
|
+
require 'structr'
|
11
|
+
|
12
|
+
Load = Struct.new(:one, :five, :fifteen)
|
13
|
+
ProcessItem = Struct.new(:pid, :user)
|
14
|
+
|
15
|
+
class Top
|
16
|
+
include Structr
|
17
|
+
|
18
|
+
converter :load do |(one, five, fifteen)|
|
19
|
+
Load.new(one.to_f, five.to_f, fifteen.to_f)
|
20
|
+
end
|
21
|
+
|
22
|
+
converter :process do |(pid, user)|
|
23
|
+
ProcessItem.new(pid.to_i, user)
|
24
|
+
end
|
25
|
+
|
26
|
+
field_accessor :uptime, /top - (\d+):(\d+):(\d+)/ do |h, m, s|
|
27
|
+
h.to_i * 3600 + m.to_i * 60 + s.to_i
|
28
|
+
end
|
29
|
+
field_accessor :cpu_string, /(Cpu.*?)\n/
|
30
|
+
load_accessor :load, /load average: (\d+\.\d+), (\d+\.\d+), (\d+\.\d+)/
|
31
|
+
int_accessor :tasks, /Tasks:\s+(\d+)/
|
32
|
+
int_accessor :memory, /Mem:\s+(\d+)/
|
33
|
+
field :processes, /^\s*(\d+)\s(\S+)/, &converter(:process)
|
34
|
+
|
35
|
+
def processes
|
36
|
+
@processes
|
37
|
+
end
|
38
|
+
|
39
|
+
def users
|
40
|
+
@processes.map {|p| p.user }.uniq
|
41
|
+
end
|
42
|
+
|
43
|
+
def highest_pid
|
44
|
+
@processes.map {|p| p.pid }.sort.last
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
top = Top.structr(`top -b -n 1`)
|
49
|
+
|
50
|
+
puts "Load is #{top.load.one}"
|
51
|
+
puts "Up since #{top.uptime} seconds"
|
52
|
+
puts top.cpu_string
|
53
|
+
puts "#{top.tasks} Tasks"
|
54
|
+
puts "#{top.memory / 1024}MB memory available"
|
55
|
+
puts "Users: #{top.users.join(", ")}"
|
56
|
+
puts "Highest PID: #{top.highest_pid}"
|
57
|
+
|
58
|
+
=== Examples
|
59
|
+
|
60
|
+
See examples/ for further examples
|
61
|
+
|
62
|
+
== Installation
|
63
|
+
|
64
|
+
=== Gem
|
65
|
+
|
66
|
+
gem source -a http://gems.github.com
|
67
|
+
gem install splattael-structr
|
68
|
+
|
69
|
+
== Authors:
|
70
|
+
* Peter Suschlik
|
71
|
+
|
72
|
+
== Changelog
|
73
|
+
|
74
|
+
See CHANGELOG file.
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
require 'jeweler'
|
9
|
+
Jeweler::Tasks.new do |gem|
|
10
|
+
gem.name = "structr"
|
11
|
+
gem.summary = 'Parse plain text to Ruby classes.'
|
12
|
+
gem.email = "peter-structr@suschlik.de"
|
13
|
+
gem.homepage = "http://github.com/splattael/structr"
|
14
|
+
gem.authors = ["Peter Suschlik"]
|
15
|
+
|
16
|
+
gem.has_rdoc = true
|
17
|
+
gem.extra_rdoc_files = [ "README.rdoc" ]
|
18
|
+
|
19
|
+
gem.add_development_dependency "riot", ">= 0.10.4"
|
20
|
+
gem.add_development_dependency "riot_notifier", ">= 0.0.5"
|
21
|
+
|
22
|
+
gem.test_files = Dir.glob('test/test_*.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
Jeweler::GemcutterTasks.new
|
26
|
+
|
27
|
+
# Test
|
28
|
+
require 'rake/testtask'
|
29
|
+
Rake::TestTask.new(:test) do |test|
|
30
|
+
test.test_files = FileList.new('test/test_*.rb')
|
31
|
+
test.libs << 'test'
|
32
|
+
test.verbose = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# RDoc
|
36
|
+
Rake::RDocTask.new do |rd|
|
37
|
+
rd.title = "Parse plain text with Ruby classes"
|
38
|
+
rd.main = "README.rdoc"
|
39
|
+
rd.rdoc_files.include("README.rdoc", "lib/*.rb")
|
40
|
+
rd.rdoc_dir = "doc"
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# Misc
|
45
|
+
desc "Tag files for vim"
|
46
|
+
task :ctags do
|
47
|
+
dirs = $LOAD_PATH.select {|path| File.directory?(path) }
|
48
|
+
system "ctags -R #{dirs.join(" ")}"
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Find whitespace at line ends"
|
52
|
+
task :eol do
|
53
|
+
system "grep -nrE ' +$' *"
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/examples/invoice.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'structr'
|
2
|
+
|
3
|
+
LineItem = Struct.new(:number, :description, :price)
|
4
|
+
|
5
|
+
class Invoice
|
6
|
+
include Structr
|
7
|
+
|
8
|
+
converter :line_item do |*matched|
|
9
|
+
LineItem.new(*matched)
|
10
|
+
end
|
11
|
+
|
12
|
+
int_accessor :number, /#(\d+)/
|
13
|
+
field_accessor :address, /Address:\n(.*?)\n(.*?)\n(.*?)\n/
|
14
|
+
date_accessor :date, /on (\d+-\d+-\d+)/
|
15
|
+
line_item :line_items, /^(\d+)\.\s+(.*?)\s+(\d+,\d+)$/
|
16
|
+
|
17
|
+
def items
|
18
|
+
Array(@line_items)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
string = (STDIN.tty? ? DATA : STDIN).read
|
23
|
+
|
24
|
+
invoice = Invoice.structr(string)
|
25
|
+
p invoice
|
26
|
+
p invoice.items
|
27
|
+
p invoice.number
|
28
|
+
|
29
|
+
__END__
|
30
|
+
This is #23 on 2009-04-30
|
31
|
+
|
32
|
+
Address:
|
33
|
+
Evergreen Street 23
|
34
|
+
12345 Malrose
|
35
|
+
Nirvana
|
36
|
+
|
37
|
+
1. Root server 23,42
|
38
|
+
2. Domain 45,00
|
39
|
+
3. Another 32,00
|
40
|
+
|
41
|
+
# TODO
|
42
|
+
* Subtypes? LineItem
|
data/examples/top.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'structr'
|
2
|
+
|
3
|
+
Load = Struct.new(:one, :five, :fifteen)
|
4
|
+
ProcessItem = Struct.new(:pid, :user)
|
5
|
+
|
6
|
+
class Top
|
7
|
+
include Structr
|
8
|
+
|
9
|
+
converter :load do |(one, five, fifteen)|
|
10
|
+
Load.new(one.to_f, five.to_f, fifteen.to_f)
|
11
|
+
end
|
12
|
+
|
13
|
+
converter :process do |(pid, user)|
|
14
|
+
ProcessItem.new(pid.to_i, user)
|
15
|
+
end
|
16
|
+
|
17
|
+
field_accessor :uptime, /top - (\d+):(\d+):(\d+)/ do |h, m, s|
|
18
|
+
h.to_i * 3600 + m.to_i * 60 + s.to_i
|
19
|
+
end
|
20
|
+
field_accessor :cpu_string, /(Cpu.*?)\n/
|
21
|
+
load_accessor :load, /load average: (\d+\.\d+), (\d+\.\d+), (\d+\.\d+)/
|
22
|
+
int_accessor :tasks, /Tasks:\s+(\d+)/
|
23
|
+
int_accessor :memory, /Mem:\s+(\d+)/
|
24
|
+
field :processes, /^\s*(\d+)\s(\S+)/, &converter(:process)
|
25
|
+
|
26
|
+
def processes
|
27
|
+
@processes
|
28
|
+
end
|
29
|
+
|
30
|
+
def users
|
31
|
+
@processes.map {|p| p.user }.uniq
|
32
|
+
end
|
33
|
+
|
34
|
+
def highest_pid
|
35
|
+
@processes.map {|p| p.pid }.sort.last
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
top = Top.structr(`top -b -n 1`)
|
40
|
+
|
41
|
+
puts "Load is #{top.load.one}"
|
42
|
+
puts "Up since #{top.uptime} seconds"
|
43
|
+
puts top.cpu_string
|
44
|
+
puts "#{top.tasks} Tasks"
|
45
|
+
puts "#{top.memory / 1024}MB memory available"
|
46
|
+
puts "Users: #{top.users.join(", ")}"
|
47
|
+
puts "Highest PID: #{top.highest_pid}"
|
data/lib/structr.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
|
2
|
+
module Structr
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
Converter = {
|
11
|
+
:int => proc {|m| m.to_i },
|
12
|
+
:float => proc {|m| m.to_f },
|
13
|
+
:date => proc {|m| Date.parse(m) },
|
14
|
+
:string => proc {|m| m },
|
15
|
+
}
|
16
|
+
|
17
|
+
def field(name, regexp, options={}, &block)
|
18
|
+
fields << FieldDefinition.new(name, regexp, &block)
|
19
|
+
|
20
|
+
case options[:accessor]
|
21
|
+
when :reader
|
22
|
+
attr_reader(name)
|
23
|
+
when :writer
|
24
|
+
attr_writer(name)
|
25
|
+
when :accessor, true
|
26
|
+
attr_accessor(name)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def field_accessor(name, regexp, &block)
|
31
|
+
field(name, regexp, :accessor => true, &block)
|
32
|
+
end
|
33
|
+
|
34
|
+
def field_reader(name, regexp, &block)
|
35
|
+
field(name, regexp, :accessor => :reader, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def field_writer(name, regexp, &block)
|
39
|
+
field(name, regexp, :accessor => :writer, &block)
|
40
|
+
end
|
41
|
+
|
42
|
+
def fields
|
43
|
+
@fields ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def structr(content, *options)
|
47
|
+
instance = new(*options)
|
48
|
+
fields.each do |field|
|
49
|
+
value = field.match(content)
|
50
|
+
value = value.first if value.size < 2
|
51
|
+
if instance.respond_to?(field.setter)
|
52
|
+
instance.send(field.setter, value)
|
53
|
+
else
|
54
|
+
instance.instance_variable_set(field.ivar, value)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
instance
|
58
|
+
end
|
59
|
+
|
60
|
+
def converter(name, proc=nil, &block)
|
61
|
+
if block = proc || block
|
62
|
+
Converter[name] = block
|
63
|
+
else
|
64
|
+
Converter[name]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def method_missing(method, *args, &block)
|
69
|
+
name = method.to_s.gsub(/_(accessor|reader|writer)/, '')
|
70
|
+
if converter = converter(name.to_sym)
|
71
|
+
field(args[0], args[1], :accessor => $1 ? $1.to_sym : nil, &converter)
|
72
|
+
else
|
73
|
+
super(method, *args, &block)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
class FieldDefinition
|
80
|
+
|
81
|
+
attr_accessor :name, :block
|
82
|
+
|
83
|
+
def initialize(name, regexp, &block)
|
84
|
+
@name, @regexp, @block = name.to_s, regexp, block
|
85
|
+
end
|
86
|
+
|
87
|
+
def setter
|
88
|
+
:"#{name}="
|
89
|
+
end
|
90
|
+
|
91
|
+
def getter
|
92
|
+
:"#{name}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def ivar
|
96
|
+
:"@#{name}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def match(string)
|
100
|
+
string.scan(@regexp).map do |matched|
|
101
|
+
matched = matched.first if matched.size == 1
|
102
|
+
if @block
|
103
|
+
@block.call(*matched)
|
104
|
+
else
|
105
|
+
matched
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/structr.gemspec
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{structr}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Peter Suschlik"]
|
12
|
+
s.date = %q{2009-12-07}
|
13
|
+
s.email = %q{peter-structr@suschlik.de}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"README.rdoc"
|
16
|
+
]
|
17
|
+
s.files = [
|
18
|
+
".gitignore",
|
19
|
+
".watchr",
|
20
|
+
"README.rdoc",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"examples/invoice.rb",
|
24
|
+
"examples/top.rb",
|
25
|
+
"lib/structr.rb",
|
26
|
+
"structr.gemspec",
|
27
|
+
"test/helper.rb",
|
28
|
+
"test/test_field_descriptor.rb",
|
29
|
+
"test/test_structr.rb"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/splattael/structr}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.5}
|
35
|
+
s.summary = %q{Parse plain text to Ruby classes.}
|
36
|
+
s.test_files = [
|
37
|
+
"test/test_field_descriptor.rb",
|
38
|
+
"test/test_structr.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<riot>, [">= 0.10.4"])
|
47
|
+
s.add_development_dependency(%q<riot_notifier>, [">= 0.0.5"])
|
48
|
+
else
|
49
|
+
s.add_dependency(%q<riot>, [">= 0.10.4"])
|
50
|
+
s.add_dependency(%q<riot_notifier>, [">= 0.0.5"])
|
51
|
+
end
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<riot>, [">= 0.10.4"])
|
54
|
+
s.add_dependency(%q<riot_notifier>, [">= 0.0.5"])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
include Structr
|
4
|
+
|
5
|
+
context Struct::FieldDefinition do
|
6
|
+
context "with single" do
|
7
|
+
setup { FieldDefinition.new(:number, /(\d+)/) }
|
8
|
+
|
9
|
+
asserts("name") { topic.name }.equals("number")
|
10
|
+
asserts("getter") { topic.getter }.equals(:number)
|
11
|
+
asserts("setter") { topic.setter }.equals(:number=)
|
12
|
+
asserts("ivar") { topic.ivar }.equals(:@number)
|
13
|
+
asserts("no block") { topic.block }.nil
|
14
|
+
asserts("no match") { topic.match("no match") }.equals([])
|
15
|
+
asserts("match without block") { topic.match("23 < 42") }.equals(["23", "42"])
|
16
|
+
asserts("match with block") do
|
17
|
+
topic.block = proc { |m| m.to_i }
|
18
|
+
topic.match("23 < 42")
|
19
|
+
end.equals([23, 42])
|
20
|
+
end
|
21
|
+
|
22
|
+
context "multiple" do
|
23
|
+
setup { FieldDefinition.new(:number, /(\d+),(\d+)/) }
|
24
|
+
|
25
|
+
asserts("match without block") { topic.match("costs 23,42$") }.equals([["23", "42"]])
|
26
|
+
asserts("matech with block") do
|
27
|
+
topic.block = proc {|(dollar, cents)| dollar.to_i * 100 + cents.to_i }
|
28
|
+
topic.match("costs 23,42$")
|
29
|
+
end.equals([2342])
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
context Structr do
|
4
|
+
setup do
|
5
|
+
Class.new do
|
6
|
+
include Structr
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
asserts("module inclusion") { topic.included_modules.include?(Structr) }
|
11
|
+
%w(field field_reader field_writer field_accessor converter structr fields).each do |method|
|
12
|
+
asserts("responds to #{method}").respond_to(method)
|
13
|
+
end
|
14
|
+
asserts("no fields") { topic.fields.empty? }
|
15
|
+
|
16
|
+
asserts("error on no field name") { topic.field }.raises(ArgumentError)
|
17
|
+
asserts("error on no regexp") { topic.field(:name) }.raises(ArgumentError)
|
18
|
+
|
19
|
+
context "with field" do
|
20
|
+
context "added" do
|
21
|
+
setup do
|
22
|
+
topic.field :foo, %r{}
|
23
|
+
topic.field :bar, %r{}
|
24
|
+
topic.field :baz, %r{}
|
25
|
+
topic
|
26
|
+
end
|
27
|
+
|
28
|
+
asserts("3 added") { topic.fields.size }.equals(3)
|
29
|
+
end
|
30
|
+
|
31
|
+
context "defaults" do
|
32
|
+
setup do
|
33
|
+
topic.field(:no_acc_1, %r{})
|
34
|
+
topic.field(:no_acc_2, %r{}, :accessor => false)
|
35
|
+
end
|
36
|
+
[ :acc_1, :acc_2 ].each do |field|
|
37
|
+
asserts("no getter for #{field}") { !topic.respond_to?(field) }
|
38
|
+
asserts("no setter for #{field}") { !topic.respond_to?(:"#{field}=") }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "accessors" do
|
43
|
+
setup do
|
44
|
+
topic.field(:acc_1, %r{}, :accessor => true)
|
45
|
+
topic.field(:acc_2, %r{}, :accessor => :accessor)
|
46
|
+
topic.field_accessor(:acc_3, %r{})
|
47
|
+
topic.new
|
48
|
+
end
|
49
|
+
|
50
|
+
[ :acc_1, :acc_2, :acc_3 ].each do |method|
|
51
|
+
asserts("has getter for #{method}") { topic.respond_to?(method) }
|
52
|
+
asserts("has setter for #{method}") { topic.respond_to?(:"#{method}=") }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "readers" do
|
57
|
+
setup do
|
58
|
+
topic.field(:rdr_1, %r{}, :accessor => :reader)
|
59
|
+
topic.field_reader(:rdr_2, %r{})
|
60
|
+
topic.new
|
61
|
+
end
|
62
|
+
|
63
|
+
[ :rdr_1, :rdr_2 ].each do |method|
|
64
|
+
asserts("has getter for #{method}") { topic.respond_to?(method) }
|
65
|
+
asserts("has no sett for #{method}") { !topic.respond_to?(:"#{method}=") }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "writers" do
|
70
|
+
setup do
|
71
|
+
topic.field(:wrt_1, %r{}, :accessor => :writer)
|
72
|
+
topic.field_writer(:wrt_2, %r{})
|
73
|
+
topic.new
|
74
|
+
end
|
75
|
+
|
76
|
+
[ :wrt_1, :wrt_2 ].each do |method|
|
77
|
+
asserts("has no getter for #{method}") { !topic.respond_to?(method) }
|
78
|
+
asserts("has setter for #{method}") { topic.respond_to?(:"#{method}=") }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end # with field
|
82
|
+
|
83
|
+
context "with converter" do
|
84
|
+
[ :int, :float, :date, :string ].each do |name|
|
85
|
+
asserts("default converter #{name} is a Proc") { topic.converter(name) }.kind_of(Proc)
|
86
|
+
end
|
87
|
+
|
88
|
+
[ :unkn, :unkn_reader, :unkn_writer, :unkn_accessor ].each do |field_name|
|
89
|
+
asserts("raises NoMethodError for #{field_name}") { topic.send(field_name, %r{}) }.raises(NoMethodError)
|
90
|
+
end
|
91
|
+
|
92
|
+
context "added" do
|
93
|
+
setup do
|
94
|
+
topic.converter(:proced, proc { |p| p })
|
95
|
+
topic.converter(:blocked) { |p| p }
|
96
|
+
topic
|
97
|
+
end
|
98
|
+
|
99
|
+
asserts("proced converter is a Proc") { topic.converter(:proced) }.kind_of(Proc)
|
100
|
+
asserts("blocked converter is a Proc") { topic.converter(:blocked) }.kind_of(Proc)
|
101
|
+
end
|
102
|
+
|
103
|
+
context "by-passed" do
|
104
|
+
setup do
|
105
|
+
pass = proc { |p| p }
|
106
|
+
|
107
|
+
topic.converter :pass, &pass
|
108
|
+
topic.field(:block, /(\d+)/) { |p| pass.call(p) }
|
109
|
+
topic.field(:param, /(\d+)/, &topic.converter(:pass))
|
110
|
+
topic.pass(:mm, /(\d+)/)
|
111
|
+
topic.pass(:mm_overwritten, /(\d+)/) { |i| fail("I am overwritten") }
|
112
|
+
topic
|
113
|
+
end
|
114
|
+
|
115
|
+
asserts("block field passes 1") { topic.fields[0].block.call(1) }.equals(1)
|
116
|
+
asserts("param field passes 1") { topic.fields[1].block.call(1) }.equals(1)
|
117
|
+
asserts("mm field passes 1") { topic.fields[2].block.call(1) }.equals(1)
|
118
|
+
asserts("mm_overwritten field passes 1") { topic.fields[3].block.call(1) }.equals(1)
|
119
|
+
end
|
120
|
+
|
121
|
+
context "using method missing" do
|
122
|
+
setup do
|
123
|
+
topic.int(:no_acc, %r{})
|
124
|
+
topic.int_reader(:rdr, %r{})
|
125
|
+
topic.int_writer(:wrt, %r{})
|
126
|
+
topic.int_accessor(:acc, %r{})
|
127
|
+
topic.new
|
128
|
+
end
|
129
|
+
|
130
|
+
asserts("no getter for no_acc") { !topic.respond_to?(:no_acc) }
|
131
|
+
asserts("no setter for no_acc") { !topic.respond_to?(:no_acc=) }
|
132
|
+
asserts("getter for rdr") { topic.respond_to?(:rdr) }
|
133
|
+
asserts("no setter for rdr") { !topic.respond_to?(:rdr=) }
|
134
|
+
asserts("no getter for wrt") { !topic.respond_to?(:wrt) }
|
135
|
+
asserts("setter for wrt") { topic.respond_to?(:wrt=) }
|
136
|
+
asserts("getter for acc") { topic.respond_to?(:acc) }
|
137
|
+
asserts("setter for acc") { topic.respond_to?(:acc=) }
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end # with converters
|
142
|
+
|
143
|
+
# TODO test structr
|
144
|
+
# TODO integration tests
|
145
|
+
|
146
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: structr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Suschlik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-07 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: riot
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.10.4
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: riot_notifier
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.0.5
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: peter-structr@suschlik.de
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README.rdoc
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- .watchr
|
46
|
+
- README.rdoc
|
47
|
+
- Rakefile
|
48
|
+
- VERSION
|
49
|
+
- examples/invoice.rb
|
50
|
+
- examples/top.rb
|
51
|
+
- lib/structr.rb
|
52
|
+
- structr.gemspec
|
53
|
+
- test/helper.rb
|
54
|
+
- test/test_field_descriptor.rb
|
55
|
+
- test/test_structr.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/splattael/structr
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.5
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Parse plain text to Ruby classes.
|
84
|
+
test_files:
|
85
|
+
- test/test_field_descriptor.rb
|
86
|
+
- test/test_structr.rb
|