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