fabulator-exhibit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,79 @@
1
+ = fabulator-exhibit
2
+
3
+ * http://github.com/jgsmith/ruby-fabulator-exhibit
4
+
5
+ == DESCRIPTION:
6
+
7
+ Fabulator engine extension for creating Exhibit data sources.
8
+
9
+ Namespace: http://dh.tamu.edu/ns/fabulator/exhibit/1.0#
10
+
11
+ See http://www.simile-widgets.org/exhibit/ for more information
12
+ on Exhibit
13
+
14
+ == FEATURES/PROBLEMS:
15
+
16
+ == SYNOPSIS:
17
+
18
+ === In Ruby
19
+
20
+ require 'fabulator/exhibit'
21
+
22
+ === In Fabulator applications
23
+
24
+ <ex:database ex:database="data">
25
+ <ex:item ex:id="'id'" ex:label="'label'" ex:type="ItemType">
26
+ <ex:value ex:name="key" f:select="'value'" />
27
+ </ex:item>
28
+ </ex:database>
29
+
30
+ == REQUIREMENTS:
31
+
32
+ The uuid gem is required to autogenerate ids.
33
+
34
+ This Fabulator extension provides to an Exhibit-style database, but does
35
+ not provide actual storage. The embedding framework will need to define
36
+ several functions:
37
+
38
+ === Fabulator::Exhibit::Action::Lib.fetch_database(name)
39
+
40
+ This function should return the Exhibit database. It needs to look like
41
+ the following data structure:
42
+
43
+ {
44
+ :types => { },
45
+ :properties => { },
46
+ :items => { }
47
+ }
48
+
49
+ === Fabulator::Exhibit::Action::Lib.store_database(name, data)
50
+
51
+ This function should store the data for later retrieval. The data is provided
52
+ in the same format it is returned by the fetch_database function.
53
+
54
+ == INSTALL:
55
+
56
+ * sudo gem install fabulator-exhibit
57
+
58
+ == LICENSE:
59
+
60
+ Copyright (c) 2010 Texas A&M University
61
+
62
+ Permission is hereby granted, free of charge, to any person obtaining
63
+ a copy of this software and associated documentation files (the
64
+ 'Software'), to deal in the Software without restriction, including
65
+ without limitation the rights to use, copy, modify, merge, publish,
66
+ distribute, sublicense, and/or sell copies of the Software, and to
67
+ permit persons to whom the Software is furnished to do so, subject to
68
+ the following conditions:
69
+
70
+ The above copyright notice and this permission notice shall be
71
+ included in all copies or substantial portions of the Software.
72
+
73
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
74
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
75
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
76
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
77
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
78
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
79
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,25 @@
1
+ Feature: Simple database items
2
+
3
+ Scenario: simple database with one item
4
+ Given the statemachine
5
+ """
6
+ <f:application xmlns:f="http://dh.tamu.edu/ns/fabulator/1.0#"
7
+ xmlns:ex="http://dh.tamu.edu/ns/fabulator/exhibit/1.0#"
8
+ ex:database="test"
9
+ >
10
+ <ex:database>
11
+ <ex:item ex:id="'foo'" ex:type="fooType" ex:label="'fooLabel'">
12
+ <ex:value ex:name="bar" f:select="'baz'" />
13
+ </ex:item>
14
+ </ex:database>
15
+ <ex:database>
16
+ <f:value f:path="/f" f:select="ex:item('foo')" />
17
+ </ex:database>
18
+ </f:application>
19
+ """
20
+ And using the 'test' database
21
+ Then there should be 1 item
22
+ And the item 'foo' should have type 'fooType'
23
+ And the item 'foo' should have the label 'fooLabel'
24
+ And the item 'foo' should have the property 'bar' as 'baz'
25
+ And the expression (/f/bar) should equal ['baz']
@@ -0,0 +1,24 @@
1
+ Given /the '(.*)' database/ do |n|
2
+ @exhibit_db_nom = n
3
+ end
4
+
5
+ Then /there should be (\d+) items?/ do |n|
6
+ db = Fabulator::Exhibit::Actions::Lib.fetch_database(@exhibit_db_nom)
7
+ db[:items].size.should == n.to_i
8
+ end
9
+
10
+ Then /^the item '(.*)' should have type '(.+)'$/ do |id, type|
11
+ db = Fabulator::Exhibit::Actions::Lib.fetch_database(@exhibit_db_nom)
12
+ db[:items][id]['type'].should == type
13
+ end
14
+
15
+ Then /^the item '(.*)' should have the label '(.*)'$/ do |id, label|
16
+ db = Fabulator::Exhibit::Actions::Lib.fetch_database(@exhibit_db_nom)
17
+ db[:items][id]['label'].should == label
18
+ end
19
+
20
+ Then /^the item '(.*)' should have the property '(.*)' as '(.*)'$/ do |id, prop_name, prop_value|
21
+ db = Fabulator::Exhibit::Actions::Lib.fetch_database(@exhibit_db_nom)
22
+ db[:items][id][prop_name].should == prop_value
23
+ end
24
+
@@ -0,0 +1,104 @@
1
+ require 'yaml'
2
+
3
+ Transform /^(expression|context) \((.*)\)$/ do |n, arg|
4
+ @namespaces ||= { }
5
+ @parser ||= Fabulator::Expr::Parser.new
6
+ @parser.parse(arg, @context)
7
+ end
8
+
9
+ Transform /^\[(.*)\]$/ do |arg|
10
+ @parser ||= Fabulator::Expr::Parser.new
11
+ @parser.parse(arg, @context)
12
+ end
13
+
14
+ Transform /^(\d+)$/ do |arg|
15
+ arg.to_i
16
+ end
17
+
18
+ Given 'a context' do
19
+ @roots ||= { }
20
+ @data ||= Fabulator::Expr::Node.new('data', @roots, nil, [])
21
+ @roots['data'] ||= @data
22
+ @context ||= Fabulator::Expr::Context.new
23
+ @context.root = @data
24
+ @parser ||= Fabulator::Expr::Parser.new
25
+ end
26
+
27
+ Given /the prefix (\S+) as "([^"]+)"/ do |p,h|
28
+ @context ||= Fabulator::Expr::Context.new
29
+ @context.set_ns(p, h)
30
+ end
31
+
32
+ Given /that (\[.*\]) is set to (\[.*\])/ do |l,r|
33
+ @context.set_value(l, r)
34
+ end
35
+
36
+ When /I run the (expression \(.*\)) in the (context \(.*\))/ do |exp, cp|
37
+ @expr = exp
38
+ if cp.nil? || cp == ''
39
+ @result = []
40
+ @cp = @context.root
41
+ else
42
+ @cp = cp.run(@context).first || @context.root
43
+ @result = @expr.run(@context.with_root(@cp))
44
+ end
45
+ end
46
+
47
+ When /I run the (expression \(.*\))/ do |exp|
48
+ ## assume '/' as the context here
49
+ @expr = exp
50
+ @cp = @data
51
+ #puts YAML::dump(@expr)
52
+ @result = @expr.run(@context.with_root(@cp))
53
+ #puts YAML::dump(@result)
54
+ end
55
+
56
+ When /I unify the types? (.*)/ do |ts|
57
+ types = ts.split(/\s*,\s*/)
58
+ typea = types.collect { |t|
59
+ pn = t.split(/:/, 2)
60
+ [ @context.get_ns(pn[0]), pn[1] ]
61
+ }
62
+ @type_result = Fabulator::ActionLib.unify_types(
63
+ types.collect { |t|
64
+ pn = t.split(/:/, 2)
65
+ [ @context.get_ns(pn[0]), pn[1] ]
66
+ }
67
+ )
68
+ end
69
+
70
+ Then /I should get the type (.*)/ do |t|
71
+ pn = t.split(/:/, 2)
72
+ @type_result[0].should == @context.get_ns(pn[0])
73
+ @type_result[1].should == pn[1]
74
+ end
75
+
76
+ Then /I should get (\d+) items?/ do |count|
77
+ @result.length.should == count
78
+ end
79
+
80
+ Then /item (\d+) should be (\[.*\])/ do |i,t|
81
+ test = t.run(@context.with_root(@cp)).first
82
+ #puts "Result: #{@result[i.to_i].to_s.class.to_s}"
83
+ @result[i.to_i].to_s.should == test.to_s
84
+ end
85
+
86
+ Then /item (\d+) should be false/ do |i|
87
+ (!!@result[i.to_i].value).should == false
88
+ end
89
+
90
+ Then /item (\d+) should be true/ do |i|
91
+ (!!@result[i.to_i].value).should == true
92
+ end
93
+
94
+ Then /the (expression \(.*\)) should equal (\[.*\])/ do |x, y|
95
+ a = x.run(@context)
96
+ b = y.run(@context)
97
+ #puts YAML::dump(a)
98
+ #puts YAML::dump(b)
99
+ a.first.value.should == b.first.value
100
+ end
101
+
102
+ Then /the (expression \(.*\)) should be nil/ do |x|
103
+ x.run(@context).first.should == nil
104
+ end
@@ -0,0 +1,31 @@
1
+ Given /the statemachine/ do |doc_xml|
2
+ doc = LibXML::XML::Document.string doc_xml
3
+
4
+ @roots ||= { }
5
+ @namespaces ||= { }
6
+ @data ||= Fabulator::Expr::Node.new('data', @roots, nil, [])
7
+ @roots['data'] ||= @data
8
+ @context ||= Fabulator::Expr::Context.new
9
+ @context.root = @data
10
+
11
+ @parser ||= Fabulator::Expr::Parser.new
12
+ if @sm.nil?
13
+ @sm = Fabulator::Core::StateMachine.new.compile_xml(doc, @context)
14
+ else
15
+ @sm.compile_xml(doc, @context)
16
+ end
17
+ @sm.init_context(@context)
18
+ end
19
+
20
+ When /I run it with the following params:/ do |param_table|
21
+ params = { }
22
+ param_table.hashes.each do |hash|
23
+ params[hash['key']] = hash['value']
24
+ end
25
+ @sm.run(params)
26
+ #puts YAML::dump(@sm)
27
+ end
28
+
29
+ Then /it should be in the '(.*)' state/ do |s|
30
+ @sm.state.should == s
31
+ end
@@ -0,0 +1,21 @@
1
+ # This file makes it possible to install RubyCAS-Client as a Rails plugin.
2
+
3
+ $: << File.expand_path(File.dirname(__FILE__))+'/../../lib'
4
+ $: << File.expand_path(File.dirname(__FILE__))+'/../../../fabulator/lib'
5
+
6
+ require 'fabulator'
7
+ require 'fabulator/exhibit'
8
+ require 'spec/expectations'
9
+ require 'xml/libxml'
10
+
11
+ Fabulator::Exhibit::Actions::Lib.class_eval do
12
+ def self.fetch_database(nom)
13
+ @@dbs ||= { }
14
+ @@dbs[nom] ||= { :types => {}, :items => {}, :properties => {} }
15
+ @@dbs[nom]
16
+ end
17
+
18
+ def self.store_database(nom, data)
19
+ @@dbs[nom] = data
20
+ end
21
+ end
@@ -0,0 +1,2 @@
1
+ require 'fabulator/exhibit/actions'
2
+ require 'fabulator/exhibit/version'
@@ -0,0 +1,124 @@
1
+
2
+ module Fabulator
3
+ EXHIBIT_NS = "http://dh.tamu.edu/ns/fabulator/exhibit/1.0#"
4
+
5
+ require 'fabulator/exhibit/actions/item'
6
+ require 'fabulator/exhibit/actions/property'
7
+ require 'fabulator/exhibit/actions/type'
8
+ require 'fabulator/exhibit/actions/value'
9
+
10
+ module Exhibit
11
+ module Actions
12
+ class Lib
13
+ include Fabulator::ActionLib
14
+
15
+ @@databases = { }
16
+
17
+ register_namespace EXHIBIT_NS
18
+
19
+ action 'database', Database
20
+ action 'item', Item
21
+ action 'value', Value
22
+ action 'property', Property
23
+ action 'type', Type
24
+
25
+ ## should set up an empty database with :items, :types, and :properties
26
+ def self.fetch_database(nom)
27
+ raise "fetch_database is not implemented by the framework."
28
+ end
29
+
30
+ def self.store_database(nom, data)
31
+ raise "store_database is not imeplemented by the framework."
32
+ end
33
+
34
+ def self.get_database(nom)
35
+ @@databases[nom] ||= self.fetch_database(nom)
36
+ end
37
+
38
+ def self.set_database(nom, data)
39
+ @@databases[nom] = data
40
+ end
41
+
42
+ def self.store_databases
43
+ @@databases.keys.each do |k|
44
+ self.store_database(k, @@databases[k])
45
+ end
46
+ end
47
+
48
+ def self.accumulate_item_info(&block)
49
+ @@item ||=[]
50
+ @@item.unshift({})
51
+ yield
52
+ @@item.shift
53
+ end
54
+
55
+ def self.add_item_to_accumulator(k,v)
56
+ return if @@item.empty?
57
+ if v.is_a?(Array) && v.size == 1
58
+ v = v[0]
59
+ end
60
+ @@item[0][k] = v
61
+ end
62
+
63
+ def self.add_info(nom, t, item)
64
+ @@databases ||= {}
65
+ @@databases[nom] ||= self.fetch_database(nom)
66
+ @@databases[nom][t][item['id']] ||= { }
67
+ @@databases[nom][t][item['id']].merge!(item)
68
+ @@databases[nom][t][item['id']].each_pair do |k,v|
69
+ if v.nil? || (v.is_a?(Array) && v.empty?) ||
70
+ v.is_a?(String) && v == ""
71
+ @@databases[nom][t][item['id']].delete(k)
72
+ end
73
+ end
74
+ case t
75
+ when :types, :properties
76
+ @@databases[nom][t][item['id']].delete(:id)
77
+ end
78
+ end
79
+
80
+ def self.remove_info(nom, t, id)
81
+ @@databases[nom] ||= self.fetch_database(nom)
82
+ return if @@databases[nom][t].empty?
83
+ @@databases[nom][t].delete(id)
84
+ end
85
+
86
+ function 'item' do |ctx, args|
87
+ # need to get at the 'global' ex:database attribute
88
+ nom = ctx.attribute(EXHIBIT_NS, 'database', { :inherited => true, :static => true })
89
+ db = Fabulator::Exhibit::Actions::Lib.get_database(nom)
90
+ args.collect{ |a|
91
+ id = a.to_s
92
+ i = db[:items][id]
93
+ r = ctx.root.anon_node(id)
94
+ r.name = id
95
+ i.each_pair do |k,v|
96
+ next if k == "id"
97
+ v = [ v ] unless v.is_a?(Array)
98
+ v.each do |vv|
99
+ r.create_child(k,vv)
100
+ end
101
+ end
102
+ r
103
+ }
104
+ end
105
+
106
+ function 'items' do |ctx, args|
107
+ db = Fabulator::Exhibit::Actions::Lib.get_database(args.first.to_s)
108
+ db[:items].collect{ |item|
109
+ i = ctx.anon_node(item["id"])
110
+ i.name = item["id"]
111
+ item.each_pair do |k,v|
112
+ next if k == "id"
113
+ v = [ v ] unless v.is_a?(Array)
114
+ v.each do |vv|
115
+ i.create_child(k,vv)
116
+ end
117
+ end
118
+ i
119
+ }
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,81 @@
1
+ require 'uuid'
2
+
3
+ module Fabulator
4
+ module Exhibit
5
+ module Actions
6
+ class Item < Fabulator::Action
7
+ namespace Fabulator::EXHIBIT_NS
8
+ attribute :database, :inherited => true, :static => false
9
+ attribute :id, :eval => true, :static => false
10
+ attribute :type, :static => false, :inherited => true
11
+ attribute :label, :eval => true, :static => false
12
+
13
+ has_select
14
+ has_actions
15
+
16
+ def run(context, autovivify = false)
17
+ @context.with(context) do |ctx|
18
+ items = @select.run(ctx)
19
+
20
+ db = @database.run(ctx).first.to_s
21
+
22
+ items.each do |item|
23
+ info = Fabulator::Exhibit::Actions::Lib.accumulate_item_info do
24
+ @actions.run(ctx.with_root(item))
25
+ end
26
+ info['id'] = (@id.run(ctx.with_root(item)).first.to_s rescue nil)
27
+ if info['id'].nil?
28
+ @@uuid ||= UUID.new
29
+ info['id'] = @@uuid.generate(:compact)
30
+ end
31
+ info['type'] = @type.run(ctx.with_root(item)).first.to_s
32
+ info['label'] = @label.run(ctx.with_root(item)).first.to_s
33
+ Fabulator::Exhibit::Actions::Lib.add_info(db, :items, info)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ class Database < Fabulator::Action
40
+ namespace Fabulator::EXHIBIT_NS
41
+ attribute :database, :inherited => true, :static => false
42
+ attribute :mode, :default => 'merge', :static => false
43
+ attribute :type, :as => :scope_type, :static => false
44
+
45
+ has_actions
46
+
47
+ def run(context, autovivify = false)
48
+ ret = [ ]
49
+ @context.with(context) do |ctx|
50
+ nom = @database.run(ctx).first.to_s
51
+ mode = @mode.run(ctx).first.to_s
52
+ scope_type = (@scope_type.run(ctx).first.to_s rescue nil)
53
+ db = nil
54
+ if mode == 'merge' || !scope_type.nil?
55
+ db = Fabulator::Exhibit::Actions::Lib.fetch_database(nom)
56
+ if !db.nil? && mode == 'overwrite' # !scope_type.nil? is a consequence
57
+ # remove any items of scope_type
58
+ db[:items].delete_if{ |k,v| v['type'] == scope_type }
59
+ end
60
+ end
61
+ if db.nil?
62
+ db = { :items => {}, :types => {}, :properties => {} }
63
+ end
64
+ Fabulator::Exhibit::Actions::Lib.set_database(nom, db)
65
+
66
+ begin
67
+ ret = @actions.run(ctx)
68
+ ensure
69
+ Fabulator::Exhibit::Actions::Lib.store_database(
70
+ nom,
71
+ Fabulator::Exhibit::Actions::Lib.get_database(nom)
72
+ )
73
+ end
74
+ end
75
+ return ret
76
+ end
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,24 @@
1
+ module Fabulator
2
+ module Exhibit
3
+ module Actions
4
+ class Property < Fabulator::Action
5
+ namespace Fabulator::EXHIBIT_NS
6
+ attribute :database, :inherited => true, :static => false
7
+ attribute :name, :static => false
8
+ attribute :valueType, :static => false
9
+
10
+ def run(context, autovivify = false)
11
+ @context.with(context) do |ctx|
12
+ Fabulator::Exhibit::Actions::Lib.add_info(
13
+ @database.run(ctx).first.to_s,
14
+ :properties, {
15
+ 'id' => @name.run(ctx).first.to_s,
16
+ 'valueType' => @valueType.run(ctx).first.to_s
17
+ }
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ module Fabulator
2
+ module Exhibit
3
+ module Actions
4
+ class Type < Fabulator::Action
5
+
6
+ namespace Fabulator::EXHIBIT_NS
7
+ attribute :database, :inherited => true, :static => false
8
+ attribute :name, :static => false
9
+ attribute :pluralLabel, :static => false
10
+
11
+ def run(context, autovivify = false)
12
+ @context.with(context) do |ctx|
13
+ info = { :id => @name.run(ctx).first.to_s }
14
+ if !@pluralLabel.nil?
15
+ info['pluralLabel'] = @pluralLabel.run(ctx).first.to_s
16
+ end
17
+ Fabulator::Exhibit::Actions::Lib.add_info(
18
+ @database.run(ctx).first.to_s, :types, info
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ module Fabulator
2
+ module Exhibit
3
+ module Actions
4
+ class Value < Fabulator::Action
5
+
6
+ namespace Fabulator::EXHIBIT_NS
7
+ attribute :name, :static => false
8
+
9
+ has_select
10
+
11
+ def run(context, autovivify = false)
12
+ @context.with(context) do |ctx|
13
+ Fabulator::Exhibit::Actions::Lib.add_item_to_accumulator(
14
+ @name.run(ctx).first.to_s,
15
+ @select.run(ctx).collect{ |s| s.value }
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module Fabulator
2
+ module Exhibit
3
+ module VERSION
4
+ unless defined? MAJOR
5
+ MAJOR = 0
6
+ MINOR = 0
7
+ TINY = 1
8
+ PRE = nil
9
+
10
+ STRING = [MAJOR,MINOR,TINY].compact.join('.') + (PRE.nil? ? '' : PRE)
11
+
12
+ SUMMARY = "fabulator-exhibit #{STRING}"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestFabulatorXml < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/fabulator-xml'
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fabulator-exhibit
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - James Smith
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-08 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: fabulator
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 29
30
+ segments:
31
+ - 0
32
+ - 0
33
+ - 1
34
+ version: 0.0.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: Provides language extensions to manage Exhibit-style NoSQL databases.
38
+ email: jgsmith@tamu.edu
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - README.rdoc
45
+ files:
46
+ - README.rdoc
47
+ - VERSION
48
+ - features/simple-database.feature
49
+ - features/step_definitions/exhibit_steps.rb
50
+ - features/step_definitions/expression_steps.rb
51
+ - features/step_definitions/xml_steps.rb
52
+ - features/support/env.rb
53
+ - lib/fabulator/exhibit.rb
54
+ - lib/fabulator/exhibit/actions.rb
55
+ - lib/fabulator/exhibit/actions/item.rb
56
+ - lib/fabulator/exhibit/actions/property.rb
57
+ - lib/fabulator/exhibit/actions/type.rb
58
+ - lib/fabulator/exhibit/actions/value.rb
59
+ - lib/fabulator/exhibit/version.rb
60
+ - test/test_helper.rb
61
+ - test/test_fabulator-xml.rb
62
+ has_rdoc: true
63
+ homepage: http://github.com/jgsmith/fabulator-exhibit
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ requirements: []
90
+
91
+ rubyforge_project:
92
+ rubygems_version: 1.3.7
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: Fabulator Extension providing Exhibit-style NoSQL databases.
96
+ test_files:
97
+ - test/test_helper.rb
98
+ - test/test_fabulator-xml.rb