spec/unit/yaks/runner_spec.rb in yaks-0.9.0 vs spec/unit/yaks/runner_spec.rb in yaks-0.10.0
- old
+ new
@@ -6,24 +6,30 @@
let(:object) { Object.new }
let(:config) { Yaks.new }
let(:options) { {} }
shared_examples 'high-level runner test' do
- let(:options) { {env: {foo: "from_env"}} }
+ let(:object) { 7 }
+
+ let(:options) {
+ {
+ env: {foo: "from_env"},
+ hooks: [[:after, :step2, :upcase, ->(x, _env) { x.upcase }]]
+ }
+ }
+
let(:runner) {
Class.new(described_class) do
def steps
[ [:step1, proc { |x| x + 35 }],
[:step2, proc { |x, env| "#{env[:foo]}[#{x} #{x}]" }] ]
end
end.new(object: object, config: config, options: options)
}
- let(:object) { 7 }
-
it 'should go through all the steps' do
- expect(runner.call).to eql "from_env[42 42]"
+ expect(runner.call).to eql "FROM_ENV[42 42]"
end
end
describe '#call' do
include_examples 'high-level runner test'
@@ -31,17 +37,88 @@
describe '#process' do
include_examples 'high-level runner test'
end
+ describe '#format' do
+ let(:object) {
+ Yaks::Resource.new(attributes: {ronny: :jonny})
+ }
+
+ let(:options) {
+ {
+ env: {
+ 'api.key_prefix' => 'pre_'
+ },
+ hooks: [
+ [:before,
+ :format,
+ :add_kristel,
+ ->(resource, _env) {
+ resource.merge_attributes(kristel: :christa)
+ },
+ ],
+ [:after,
+ :primitivize,
+ :add_prefix,
+ ->(hsh, env) {
+ hsh.each_with_object({}) do |(k, v), h|
+ h[env['api.key_prefix'] + k] = v
+ end
+ }
+ ]
+ ]
+ }
+ }
+
+ it 'should run the formatter and primitivizer plus hooks' do
+ expect(runner.format).to eql("pre_kristel" => "christa", "pre_ronny" => "jonny")
+ end
+ end
+
+ describe '#read' do
+ let(:object) {
+ '{"pre_ronny": "jonny"}'
+ }
+
+ let(:options) {
+ {
+ env: {
+ 'api.key_prefix' => 'pre_'
+ },
+ hooks: [
+ [:after,
+ :read,
+ :add_kristel,
+ ->(resource, _env) {
+ resource.merge_attributes(kristel: 'christa')
+ },
+ ],
+ [:before,
+ :parse,
+ :strip_prefix,
+ ->(json, env) {
+ json.gsub(env['api.key_prefix'], '')
+ }
+ ]
+ ]
+ }
+ }
+
+ it 'should run the parser and reader plus hooks' do
+ expect(runner.read)
+ .to eql Yaks::Resource.new(attributes: {ronny: "jonny", kristel: "christa"})
+ end
+ end
+
describe '#context' do
it 'should contain the policy, env, and an empty mapper_stack' do
expect(runner.context).to eql(policy: config.policy, env: {}, mapper_stack: [])
end
context 'with an item mapper' do
- let(:options) { { item_mapper: :foo } }
+ let(:options) { {item_mapper: :foo} }
it 'should contain the item_mapper' do
expect(runner.context).to eql(policy: config.policy, env: {}, mapper_stack: [], item_mapper: :foo)
end
end
@@ -53,39 +130,39 @@
default_format :collection_json
end
end
let(:rack_env) {
- { 'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json' }
+ {'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json'}
}
it 'should fall back to the default when no HTTP_ACCEPT key is present' do
- runner = described_class.new(object: nil, config: config, options: { env: {} })
+ runner = described_class.new(object: nil, config: config, options: {env: {}})
expect(runner.format_class).to equal Yaks::Format::CollectionJson
end
it 'should detect format based on accept header' do
- rack_env = { 'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json' }
- runner = described_class.new(object: nil, config: config, options: { env: rack_env })
+ rack_env = {'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json'}
+ runner = described_class.new(object: nil, config: config, options: {env: rack_env})
expect(runner.format_class).to equal Yaks::Format::JsonAPI
end
it 'should know to pick the best match' do
- rack_env = { 'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json;q=0.7' }
- runner = described_class.new(object: nil, config: config, options: { env: rack_env })
+ rack_env = {'HTTP_ACCEPT' => 'application/hal+json;q=0.8, application/vnd.api+json;q=0.7'}
+ runner = described_class.new(object: nil, config: config, options: {env: rack_env})
expect(runner.format_class).to equal Yaks::Format::Hal
end
it 'should pick the one given in the options if no header matches' do
- rack_env = { 'HTTP_ACCEPT' => 'text/xml, application/json' }
- runner = described_class.new(object: nil, config: config, options: { format: :hal, env: rack_env })
+ rack_env = {'HTTP_ACCEPT' => 'text/xml, application/json'}
+ runner = described_class.new(object: nil, config: config, options: {format: :hal, env: rack_env})
expect(runner.format_class).to equal Yaks::Format::Hal
end
it 'should fall back to the default when no mime type is recognized' do
- rack_env = { 'HTTP_ACCEPT' => 'text/xml, application/json' }
- runner = described_class.new(object: nil, config: config, options: { env: rack_env })
+ rack_env = {'HTTP_ACCEPT' => 'text/xml, application/json'}
+ runner = described_class.new(object: nil, config: config, options: {env: rack_env})
expect(runner.format_class).to equal Yaks::Format::CollectionJson
end
end
describe '#format_name' do
@@ -97,11 +174,11 @@
context 'with a default format specified' do
let(:config) { Yaks.new { default_format :collection_json } }
context 'with a format in the options' do
- let(:options) { { format: :json_api } }
+ let(:options) { {format: :json_api} }
it 'should give preference to that one' do
expect(runner.format_name).to eql :json_api
end
end
@@ -115,11 +192,11 @@
describe '#formatter' do
let(:config) {
Yaks.new do
default_format :json_api
- format_options :json_api, {format_option: [:foo]}
+ format_options :json_api, format_option: [:foo]
end
}
let(:formatter) { runner.formatter }
@@ -133,11 +210,11 @@
end
end
describe '#env' do
describe 'when env is set in the options' do
- let(:options) { { env: 123 } }
+ let(:options) { {env: 123} }
it 'returns the env passed in' do
expect(runner.env).to be 123
end
end
@@ -150,11 +227,11 @@
end
describe '#mapper' do
context 'with an explicit mapper in the options' do
let(:mapper_class) { Class.new(Yaks::Mapper) }
- let(:options) { { mapper: mapper_class } }
+ let(:options) { {mapper: mapper_class} }
it 'should take the mapper from options' do
expect(runner.mapper).to be_a mapper_class
end
end
@@ -186,16 +263,16 @@
expect(runner.serializer.call('42', {})).to eql 'serialized 42'
end
end
it 'should fall back to the policy' do
- expect(runner.serializer.call([1,2,3], {})).to eql "[\n 1,\n 2,\n 3\n]"
+ expect(runner.serializer.call([1, 2, 3], {})).to eql "[\n 1,\n 2,\n 3\n]"
end
end
describe '#steps' do
- let(:options) {{ mapper: Yaks::Mapper }}
+ let(:options) {{mapper: Yaks::Mapper}}
it 'should have all four steps' do
expect(runner.steps).to eql [
[ :map, runner.mapper ],
[ :format, runner.formatter ],
@@ -233,11 +310,11 @@
it 'should contain the hooks from the config' do
expect(runner.hooks).to eql [[:after, :map, :this_happens_after_map, nil]]
end
context 'with extra blocks in the options' do
- let(:options) { { hooks: [[:foo]] } }
+ let(:options) { {hooks: [[:foo]]} }
it 'should combine the hooks' do
expect(runner.hooks).to eql [[:after, :map, :this_happens_after_map, nil], [:foo]]
end
end
@@ -245,32 +322,39 @@
describe '#map' do
let(:mapper_class) do
Struct.new(:options) do
include Yaks::FP::Callable
- def call(obj, env) "mapped[#{obj}]" end
+ def call(obj, _env)
+ "mapped[#{obj}]"
+ end
end
end
- let(:options) { { mapper: mapper_class } }
+ let(:options) {
+ {
+ mapper: mapper_class,
+ env: {'api.prefix' => 'pre_'}
+ }
+ }
+
let(:object) { "foo" }
it 'should only run the mapper' do
expect(runner.map).to eql "mapped[foo]"
end
context 'with a hook on the :map step' do
let(:config) do
Yaks.new do
around(:map) do |res, env, &block|
- "around[#{block.call(res, env)}]"
+ "#{env['api.prefix']}around[#{block.call(res, env)}]"
end
end
end
- it 'should invoke the hook as well' do
- expect(runner.map).to eql "around[mapped[foo]]"
+ it 'should invoke the hook and pass in the env' do
+ expect(runner.map).to eql "pre_around[mapped[foo]]"
end
end
end
-
end