bespoke 0.2.0 → 0.2.1
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/bespoke.gemspec +3 -2
- data/lib/bespoke.rb +14 -0
- data/lib/bespoke/dsl.rb +2 -3
- data/lib/bespoke/export.rb +7 -0
- data/lib/bespoke/export/filter.rb +154 -0
- data/lib/bespoke/export/filter/function_call.rb +61 -0
- data/lib/bespoke/export/filter/identifier.rb +66 -0
- data/lib/bespoke/export/filter/select_template.rb +109 -0
- data/lib/bespoke/export/filter/string_literal.rb +16 -0
- data/lib/bespoke/join.rb +15 -8
- data/lib/bespoke/mustache.rb +17 -0
- data/lib/bespoke/projection.rb +31 -17
- data/lib/bespoke/template.rb +2 -2
- data/lib/bespoke/typed_field.rb +30 -0
- data/lib/bespoke/version.rb +1 -1
- data/spec/fixtures/sif.student_personal.xslt +1 -1
- data/spec/fixtures/sif.xslt.mustache +1 -1
- data/spec/lib/bespoke/export/filter/function_call_spec.rb +72 -0
- data/spec/lib/bespoke/export/filter/identifier_spec.rb +62 -0
- data/spec/lib/bespoke/export/filter/select_template_spec.rb +102 -0
- data/spec/lib/bespoke/export/filter_spec.rb +102 -0
- data/spec/lib/bespoke/export_spec.rb +6 -0
- data/spec/lib/bespoke/join_spec.rb +59 -0
- data/spec/lib/bespoke/projection_spec.rb +94 -0
- data/spec/{template_spec.rb → lib/bespoke/template_spec.rb} +3 -3
- data/spec/lib/bespoke/typed_field_spec.rb +101 -0
- data/spec/{xsltproc_spec.rb → lib/bespoke/xsltproc_spec.rb} +1 -1
- data/spec/spec_helper.rb +16 -3
- data/spec/support/fixture_helpers.rb +24 -0
- metadata +52 -12
- data/spec/join_spec.rb +0 -44
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Bespoke
|
4
|
+
class Export
|
5
|
+
describe Filter do
|
6
|
+
let(:join) { basic_join }
|
7
|
+
let(:db) { join.database }
|
8
|
+
let(:table) { db[:two] }
|
9
|
+
let(:templates) { {} }
|
10
|
+
let(:filter) { Filter.new(table, templates) }
|
11
|
+
|
12
|
+
describe '#apply' do
|
13
|
+
before do
|
14
|
+
join.load_csv(:one, fixture('one.csv'))
|
15
|
+
join.load_csv(:two, fixture('two.csv'))
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'must not allow SQLi vulnerabilities into clients through the selects templates' do
|
19
|
+
templates[:selects] = { foo_id: '* FROM `two` -- ' }
|
20
|
+
dataset = filter.apply
|
21
|
+
expect(dataset.first).to eq({foo_id: '* FROM `two` -- '})
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'must not allow SQLi vulnerabilities into clients through the joins templates as strings' do
|
25
|
+
templates[:joins] = 'foos; SELECT * FROM `one`;'
|
26
|
+
dataset = filter.apply
|
27
|
+
expect { dataset.all }.to raise_error
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'must not allow SQLi vulnerabilities into clients through the joins templates as a hash' do
|
31
|
+
templates[:joins] = { one: ['one_id', 'id` WHERE 1=1; -- `'] }
|
32
|
+
dataset = filter.apply
|
33
|
+
expect { dataset.all }.to raise_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'must not allow SQLi vulnerabilities into clients through the where template' do
|
37
|
+
templates[:where] = '1=1); (DROP TABLE `one`'
|
38
|
+
dataset = filter.apply
|
39
|
+
expect(dataset.first).to eq({description: 'Cryptocurrency', id: 1, one_id: 1})
|
40
|
+
expect(db[:one].all).to_not be_empty
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#sql' do
|
45
|
+
it 'must default to selecting all fields from the table' do
|
46
|
+
expect(filter.sql).to start_with 'SELECT * FROM'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'must select from the specified table' do
|
50
|
+
expect(filter.sql).to end_with 'FROM `two`'
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when processing the selects key from the template hash' do
|
54
|
+
it 'must select the columns with the ailases specified' do
|
55
|
+
templates[:selects] = {course_id: :bar, user_id: :baz}
|
56
|
+
expect(filter.sql).to include "`bar` AS 'course_id'"
|
57
|
+
expect(filter.sql).to include "`baz` AS 'user_id'"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'processing the joins key of the template hash' do
|
62
|
+
it 'must not include any joins if the key is nil' do
|
63
|
+
templates[:joins] = nil
|
64
|
+
expect(filter.sql).to_not include 'JOIN'
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'must apply a left join for each element in an array' do
|
68
|
+
templates[:joins] = [:two, :three]
|
69
|
+
expect(filter.sql).to include 'LEFT JOIN `two`'
|
70
|
+
expect(filter.sql).to include 'LEFT JOIN `three`'
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'must apply a hash of joins using the columns supplied' do
|
74
|
+
templates[:joins] = {'one' => ['id', 'two_id']}
|
75
|
+
expect(filter.sql).to include 'LEFT JOIN `one` ON (`two`.`id` = `one`.`two_id`)'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'processing the where key of the template hash' do
|
80
|
+
it 'must not include a where clause when the key is nil' do
|
81
|
+
templates[:where] = nil
|
82
|
+
expect(filter.sql).to_not include 'WHERE'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'must directly apply a string SQL fragment' do
|
86
|
+
fragment = '`two`.`id` IS NOT NULL'
|
87
|
+
templates[:where] = fragment
|
88
|
+
expect(filter.sql).to include fragment
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'custom functions' do
|
94
|
+
it "uses :functions" do
|
95
|
+
templates[:selects] = { course_id: "<myfn()>" }
|
96
|
+
templates[:functions] = { myfn: ->(args) { "MYFN" } }
|
97
|
+
expect(filter.sql).to include "MYFN"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bespoke::Join do
|
4
|
+
let(:join) { basic_join }
|
5
|
+
|
6
|
+
context "table 'one'" do
|
7
|
+
before { join.load_csv('one', fixture('one.csv')) }
|
8
|
+
|
9
|
+
it "loads csv" do
|
10
|
+
join.database[:one].count.should == 2
|
11
|
+
end
|
12
|
+
|
13
|
+
context "and table 'two'" do
|
14
|
+
before { join.load_csv('two', fixture('two.csv')) }
|
15
|
+
|
16
|
+
it "loads csv" do
|
17
|
+
join.database[:two].count.should == 3
|
18
|
+
end
|
19
|
+
|
20
|
+
it "joins" do
|
21
|
+
sql = "SELECT name, description FROM one LEFT JOIN two ON one.id = two.one_id"
|
22
|
+
join.query(sql).map { |row| row }.
|
23
|
+
should == [
|
24
|
+
{:name=>"bitcoin", :description=>"Cryptocurrency"},
|
25
|
+
{:name=>"bitcoin", :description=>"Investment"},
|
26
|
+
{:name=>"nxt", :description=>"Alternate Cryptocurrency"}
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#database' do
|
33
|
+
let(:db) { join.database }
|
34
|
+
|
35
|
+
describe 'the concat_ws() function added to the database' do
|
36
|
+
it 'must join strings using the specified delemeter' do
|
37
|
+
result = db.get{ concat_ws('foo', 'bar', 'baz', '-') }
|
38
|
+
expect(result).to eq 'foo-bar-baz'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must eliminate nulls from the args before joining' do
|
42
|
+
result = db.get{ concat_ws('foo', nil, 'baz', '-') }
|
43
|
+
expect(result).to eq 'foo-baz'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#projection_named(table_name)' do
|
49
|
+
it 'must return the table with the specified name' do
|
50
|
+
table = join.projection_named 'one'
|
51
|
+
expect(table.opts[:from]).to eq [:one]
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'must return nil when the projection requested does not exist' do
|
55
|
+
table = join.projection_named 'foos'
|
56
|
+
expect(table).to be_nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Bespoke
|
4
|
+
describe Projection do
|
5
|
+
before do
|
6
|
+
@projection = Projection.new(:foo)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#initialize' do
|
10
|
+
it 'must evaluate the supplied block in the context of the new object' do
|
11
|
+
projection = Projection.new(:bar) do
|
12
|
+
field :foo, :integer
|
13
|
+
field :bar, :string
|
14
|
+
field :id, :integer, primary_key: true
|
15
|
+
end
|
16
|
+
|
17
|
+
foo_field = projection.fields.find{|f| f.name == :foo}
|
18
|
+
expect(foo_field).to_not be_nil
|
19
|
+
|
20
|
+
bar_field = projection.fields.find{|f| f.name == :bar}
|
21
|
+
expect(bar_field).to_not be_nil
|
22
|
+
|
23
|
+
id_field = projection.fields.find{|f| f.name == :id}
|
24
|
+
expect(id_field).to_not be_nil
|
25
|
+
expect(id_field).to be_primary_key
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'must yeild the projdction to the block if its arity is 1' do
|
29
|
+
projection = Projection.new(:bar) do |p|
|
30
|
+
p.field :foo, :integer
|
31
|
+
p.field :bar, :string
|
32
|
+
p.field :id, :integer, primary_key: true
|
33
|
+
end
|
34
|
+
|
35
|
+
foo_field = projection.fields.find{|f| f.name == :foo}
|
36
|
+
expect(foo_field).to_not be_nil
|
37
|
+
|
38
|
+
bar_field = projection.fields.find{|f| f.name == :bar}
|
39
|
+
expect(bar_field).to_not be_nil
|
40
|
+
|
41
|
+
id_field = projection.fields.find{|f| f.name == :id}
|
42
|
+
expect(id_field).to_not be_nil
|
43
|
+
expect(id_field).to be_primary_key
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#field' do
|
48
|
+
it 'must add a new field to the fields array with the supplied attributes' do
|
49
|
+
@projection.field(:foo, :integer)
|
50
|
+
field = @projection.fields.last
|
51
|
+
expect(field.name).to eq :foo
|
52
|
+
expect(field.type).to eq :integer
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#ensure_primary_key!' do
|
57
|
+
it 'must raise an exception if there are no fields present' do
|
58
|
+
expect { @projection.ensure_primary_key! }.to raise_error Projection::NoPrimaryKeyError
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when there is a ref_id column specified but isn't tagged as the PK" do
|
62
|
+
before do
|
63
|
+
@original_stderr = $stderr
|
64
|
+
$stderr = @new_stderr = StringIO.new
|
65
|
+
@projection.field :ref_id, :string
|
66
|
+
@projection.field :name, :string
|
67
|
+
@projection.field :birth_date, :date
|
68
|
+
end
|
69
|
+
|
70
|
+
after do
|
71
|
+
$stderr = @original_stderr
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'must add the primary key specification to the ref_id column' do
|
75
|
+
@projection.ensure_primary_key!
|
76
|
+
ref_field = @projection.fields.find{|f| f.name == :ref_id }
|
77
|
+
expect(ref_field).to be_primary_key
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'must issue a deprecation warning when setting the implied primary key' do
|
81
|
+
@projection.ensure_primary_key!
|
82
|
+
expect(@new_stderr.string).to_not be_empty
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'must not set the primary key specification if another is already supplied' do
|
86
|
+
@projection.field :id, :integer, primary_key: true
|
87
|
+
@projection.ensure_primary_key!
|
88
|
+
ref_field = @projection.fields.find{|f| f.name == :ref_id }
|
89
|
+
expect(ref_field).to_not be_primary_key
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bespoke::Template do
|
4
4
|
let(:projection) {
|
@@ -21,8 +21,8 @@ describe Bespoke::Template do
|
|
21
21
|
|
22
22
|
it "last element is the only element where 'last' is true" do
|
23
23
|
first = fields[0..-2].map{ |f| f[:last] }
|
24
|
-
first.
|
25
|
-
fields[-1][:last].
|
24
|
+
expect(first).to be_all {|item| item == false}
|
25
|
+
expect(fields[-1][:last]).to eq true
|
26
26
|
end
|
27
27
|
|
28
28
|
it "has optional function field" do
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Bespoke
|
4
|
+
describe TypedField do
|
5
|
+
describe '#initialize(name, type, options_or_xpath = )' do
|
6
|
+
context 'when passed an xpath string as the last argument' do
|
7
|
+
before do
|
8
|
+
@original_stderr = $stderr
|
9
|
+
$stderr = @new_stderr = StringIO.new
|
10
|
+
@field = TypedField.new(:foo, :integer, '/foo/bar*')
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
$stderr = @original_stderr
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'must set the xpath attribute' do
|
18
|
+
expect(@field.xpath).to eq '/foo/bar*'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'must issue a deprecation warning to stderr indicating this is a deprecated use' do
|
22
|
+
expect($stderr.string).to_not be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'must set the column_options to an empty hash' do
|
26
|
+
expect(@field.column_options).to eq Hash.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when passed an xpath array as the last argument' do
|
31
|
+
before do
|
32
|
+
@original_stderr = $stderr
|
33
|
+
$stderr = @new_stderr = StringIO.new
|
34
|
+
@field = TypedField.new(:foo, :integer, ["sif:EmailList/sif:Email[@Type='Primary']", 'split-get-first'])
|
35
|
+
end
|
36
|
+
|
37
|
+
after do
|
38
|
+
$stderr = @original_stderr
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must set the xpath attribute' do
|
42
|
+
expect(@field.xpath).to eq ["sif:EmailList/sif:Email[@Type='Primary']", 'split-get-first']
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'must issue a deprecation warning to stderr indicating this is a deprecated use' do
|
46
|
+
expect($stderr.string).to_not be_empty
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'must set the column_options to an empty hash' do
|
50
|
+
expect(@field.column_options).to eq Hash.new
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context ' when passed a hash as the last argument' do
|
55
|
+
it 'must extract the xpath from the supplied hash' do
|
56
|
+
field = TypedField.new(:foo, :string, xpath: '/foo/bar/baz')
|
57
|
+
expect(field.xpath).to eq '/foo/bar/baz'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'must keep the rest of the options for use by sequel in the column_options attribute' do
|
61
|
+
field = TypedField.new(:foo, :string, {
|
62
|
+
null: false,
|
63
|
+
unique: true,
|
64
|
+
xpath: '/bar/qux/flubble',
|
65
|
+
})
|
66
|
+
expect(field.column_options).to eq({null: false, unique: true})
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#make_primary_key!' do
|
72
|
+
before do
|
73
|
+
@field = TypedField.new(:foo, :string)
|
74
|
+
end
|
75
|
+
|
76
|
+
specify { expect(@field).to_not be_primary_key }
|
77
|
+
|
78
|
+
it 'must make the field indicate it is a primary key' do
|
79
|
+
@field.make_primary_key!
|
80
|
+
expect(@field).to be_primary_key
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#primary_key?' do
|
85
|
+
it 'must return false when not specified by the column options' do
|
86
|
+
field = TypedField.new(:foo, :string)
|
87
|
+
expect(field).to_not be_primary_key
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'must return false when specified as false in the column options' do
|
91
|
+
field = TypedField.new(:foo, :string, primary_key: false)
|
92
|
+
expect(field).to_not be_primary_key
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'must return true when specified as true in the column options' do
|
96
|
+
field = TypedField.new(:foo, :string, primary_key: true)
|
97
|
+
expect(field).to be_primary_key
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
-
|
1
|
+
require 'pry'
|
2
|
+
|
3
|
+
if ENV['CHECK_SPEC_COVERAGE']
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.start do
|
6
|
+
add_filter '/spec/'
|
7
|
+
end
|
8
|
+
end
|
2
9
|
|
3
10
|
require "bespoke"
|
4
11
|
require "bespoke/dsl"
|
5
12
|
|
6
|
-
|
7
|
-
|
13
|
+
Dir.glob(File.expand_path(File.join(*%w{.. support ** *.rb}), __FILE__)).each do |file|
|
14
|
+
require file
|
15
|
+
end
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.include FixtureHelpers
|
19
|
+
config.filter_run_including focus: true
|
20
|
+
config.run_all_when_everything_filtered = true
|
8
21
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module FixtureHelpers
|
2
|
+
def fixture(*fileparts)
|
3
|
+
File.join(File.dirname(__FILE__), '..', 'fixtures', *fileparts)
|
4
|
+
end
|
5
|
+
|
6
|
+
def basic_join
|
7
|
+
Bespoke::Join.new(basic_projections)
|
8
|
+
end
|
9
|
+
|
10
|
+
def basic_projections
|
11
|
+
[
|
12
|
+
Bespoke::Projection.new(:one) {
|
13
|
+
field :id, :integer, primary_key: true
|
14
|
+
field :name, :string
|
15
|
+
},
|
16
|
+
Bespoke::Projection.new(:two) {
|
17
|
+
field :id, :integer, primary_key: true
|
18
|
+
field :one_id, :integer
|
19
|
+
field :description, :string
|
20
|
+
}
|
21
|
+
]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bespoke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '2.6'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
name:
|
47
|
+
name: guard
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
@@ -60,14 +60,14 @@ dependencies:
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
name:
|
63
|
+
name: guard-rspec
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
67
|
- - ! '>='
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
|
-
type: :
|
70
|
+
type: :development
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
79
|
+
name: rake
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
81
81
|
none: false
|
82
82
|
requirements:
|
@@ -139,6 +139,22 @@ dependencies:
|
|
139
139
|
- - ! '>='
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: activesupport
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :runtime
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
142
158
|
description: Bespoke does in-memory object joins using mustache templates
|
143
159
|
email:
|
144
160
|
- duane@instructure.com
|
@@ -149,9 +165,17 @@ files:
|
|
149
165
|
- bespoke.gemspec
|
150
166
|
- readme.md
|
151
167
|
- lib/bespoke/dsl.rb
|
168
|
+
- lib/bespoke/export/filter/function_call.rb
|
169
|
+
- lib/bespoke/export/filter/identifier.rb
|
170
|
+
- lib/bespoke/export/filter/select_template.rb
|
171
|
+
- lib/bespoke/export/filter/string_literal.rb
|
172
|
+
- lib/bespoke/export/filter.rb
|
173
|
+
- lib/bespoke/export.rb
|
152
174
|
- lib/bespoke/join.rb
|
175
|
+
- lib/bespoke/mustache.rb
|
153
176
|
- lib/bespoke/projection.rb
|
154
177
|
- lib/bespoke/template.rb
|
178
|
+
- lib/bespoke/typed_field.rb
|
155
179
|
- lib/bespoke/version.rb
|
156
180
|
- lib/bespoke/xsltproc.rb
|
157
181
|
- lib/bespoke.rb
|
@@ -161,10 +185,18 @@ files:
|
|
161
185
|
- spec/fixtures/sif.student_personal.xslt
|
162
186
|
- spec/fixtures/sif.xslt.mustache
|
163
187
|
- spec/fixtures/two.csv
|
164
|
-
- spec/
|
188
|
+
- spec/lib/bespoke/export/filter/function_call_spec.rb
|
189
|
+
- spec/lib/bespoke/export/filter/identifier_spec.rb
|
190
|
+
- spec/lib/bespoke/export/filter/select_template_spec.rb
|
191
|
+
- spec/lib/bespoke/export/filter_spec.rb
|
192
|
+
- spec/lib/bespoke/export_spec.rb
|
193
|
+
- spec/lib/bespoke/join_spec.rb
|
194
|
+
- spec/lib/bespoke/projection_spec.rb
|
195
|
+
- spec/lib/bespoke/template_spec.rb
|
196
|
+
- spec/lib/bespoke/typed_field_spec.rb
|
197
|
+
- spec/lib/bespoke/xsltproc_spec.rb
|
165
198
|
- spec/spec_helper.rb
|
166
|
-
- spec/
|
167
|
-
- spec/xsltproc_spec.rb
|
199
|
+
- spec/support/fixture_helpers.rb
|
168
200
|
homepage:
|
169
201
|
licenses: []
|
170
202
|
post_install_message:
|
@@ -196,8 +228,16 @@ test_files:
|
|
196
228
|
- spec/fixtures/sif.student_personal.xslt
|
197
229
|
- spec/fixtures/sif.xslt.mustache
|
198
230
|
- spec/fixtures/two.csv
|
199
|
-
- spec/
|
231
|
+
- spec/lib/bespoke/export/filter/function_call_spec.rb
|
232
|
+
- spec/lib/bespoke/export/filter/identifier_spec.rb
|
233
|
+
- spec/lib/bespoke/export/filter/select_template_spec.rb
|
234
|
+
- spec/lib/bespoke/export/filter_spec.rb
|
235
|
+
- spec/lib/bespoke/export_spec.rb
|
236
|
+
- spec/lib/bespoke/join_spec.rb
|
237
|
+
- spec/lib/bespoke/projection_spec.rb
|
238
|
+
- spec/lib/bespoke/template_spec.rb
|
239
|
+
- spec/lib/bespoke/typed_field_spec.rb
|
240
|
+
- spec/lib/bespoke/xsltproc_spec.rb
|
200
241
|
- spec/spec_helper.rb
|
201
|
-
- spec/
|
202
|
-
- spec/xsltproc_spec.rb
|
242
|
+
- spec/support/fixture_helpers.rb
|
203
243
|
has_rdoc:
|