rails_view_adapters 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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +181 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.md +27 -0
- data/README.md +88 -0
- data/Rakefile +6 -0
- data/lib/rails_view_adapters/adapter.rb +34 -0
- data/lib/rails_view_adapters/adapter_base.rb +101 -0
- data/lib/rails_view_adapters/definition_proxy.rb +155 -0
- data/lib/rails_view_adapters/map.rb +46 -0
- data/lib/rails_view_adapters/version.rb +4 -0
- data/lib/rails_view_adapters.rb +13 -0
- data/rails_view_adapters.gemspec +35 -0
- data/spec/active_record_helper.rb +16 -0
- data/spec/active_record_support/db/migrate/20161031222934_create_users.rb +14 -0
- data/spec/active_record_support/db/migrate/20161031223219_create_posts.rb +11 -0
- data/spec/active_record_support/db/migrate/20161031223253_create_teams.rb +10 -0
- data/spec/active_record_support/fabricators/post_fabricator.rb +7 -0
- data/spec/active_record_support/fabricators/team_fabricator.rb +6 -0
- data/spec/active_record_support/fabricators/user_fabricator.rb +10 -0
- data/spec/active_record_support/models/post.rb +4 -0
- data/spec/active_record_support/models/team.rb +4 -0
- data/spec/active_record_support/models/user.rb +5 -0
- data/spec/integration/an_adapter_spec.rb +58 -0
- data/spec/lib/adapter_base_spec.rb +133 -0
- data/spec/lib/adapter_spec.rb +45 -0
- data/spec/lib/definition_proxy_spec.rb +242 -0
- data/spec/lib/map_spec.rb +99 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/an_adapter.rb +72 -0
- data/spec/support/fuzzy_nested_match.rb +96 -0
- metadata +206 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "active_support/core_ext/time"
|
3
|
+
Time.zone = "UTC"
|
4
|
+
|
5
|
+
require "rails_view_adapters/version"
|
6
|
+
require "rails_view_adapters/adapter_base"
|
7
|
+
require "rails_view_adapters/map"
|
8
|
+
require "rails_view_adapters/definition_proxy"
|
9
|
+
require "rails_view_adapters/adapter"
|
10
|
+
|
11
|
+
# Namespace for rails_view_adapters
|
12
|
+
module RailsViewAdapters
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rails_view_adapters/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rails_view_adapters"
|
8
|
+
spec.version = RailsViewAdapters::VERSION
|
9
|
+
spec.authors = ["Bryan Hockey"]
|
10
|
+
spec.email = ["bhock@umich.edu"]
|
11
|
+
|
12
|
+
spec.summary = "Bidirectional mappings between models and external views for Rails."
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = "https://github.com/mlibrary/rails_view_adapters"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
spec.test_files = Dir["spec/**/*"]
|
23
|
+
|
24
|
+
spec.required_ruby_version = ">= 2.2.2"
|
25
|
+
|
26
|
+
spec.add_dependency "activerecord", "~>4.2.7.1"
|
27
|
+
spec.add_dependency "activesupport", "~>4.2.7.1"
|
28
|
+
|
29
|
+
spec.add_development_dependency "sqlite3"
|
30
|
+
spec.add_development_dependency "rspec-rails"
|
31
|
+
spec.add_development_dependency "faker"
|
32
|
+
spec.add_development_dependency "fabrication"
|
33
|
+
spec.add_development_dependency "pry"
|
34
|
+
spec.add_development_dependency "rubocop"
|
35
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "active_record"
|
3
|
+
require "fabrication"
|
4
|
+
|
5
|
+
require "active_record_support/models/user"
|
6
|
+
require "active_record_support/models/post"
|
7
|
+
require "active_record_support/models/team"
|
8
|
+
|
9
|
+
require "active_record_support/fabricators/user_fabricator"
|
10
|
+
require "active_record_support/fabricators/post_fabricator"
|
11
|
+
require "active_record_support/fabricators/team_fabricator"
|
12
|
+
|
13
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
14
|
+
ActiveSupport::Deprecation.silenced = true
|
15
|
+
ActiveRecord::Migration.verbose = false
|
16
|
+
ActiveRecord::Migrator.migrate File.join(File.dirname(__FILE__), "active_record_support/db/migrate")
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class CreateUsers < ActiveRecord::Migration
|
3
|
+
def change
|
4
|
+
create_table :users do |t|
|
5
|
+
t.string :name
|
6
|
+
t.time :join_date
|
7
|
+
t.string :secret
|
8
|
+
t.boolean :admin
|
9
|
+
t.references :team, foreign_key: true
|
10
|
+
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "active_record_helper"
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
module RailsViewAdapters
|
6
|
+
|
7
|
+
describe "an adapter", integration: true do
|
8
|
+
date_format = "%Y-%m-%dT%H:%M:%S%z"
|
9
|
+
secret_token = Faker::Internet.password
|
10
|
+
Adapter.define(:user_integration_test_adapter) do
|
11
|
+
map_simple :name, :author
|
12
|
+
map_date :join_date, :member_since, date_format
|
13
|
+
map_date :created_at, :created_at, date_format
|
14
|
+
map_date :updated_at, :updated_at, date_format
|
15
|
+
map_bool :admin, :super_user
|
16
|
+
hidden_field :secret
|
17
|
+
map_from_public :secret do |token|
|
18
|
+
{ secret: token }
|
19
|
+
end
|
20
|
+
map_belongs_to :team, :favorite_team, model_class: Team
|
21
|
+
map_has_many :posts, :all_posts, sub_method: :body
|
22
|
+
end
|
23
|
+
|
24
|
+
before(:each) do
|
25
|
+
@model = Fabricate(:user, secret: secret_token)
|
26
|
+
Fabricate.times(3, :post, user: @model)
|
27
|
+
|
28
|
+
@public_hash = {
|
29
|
+
author: @model.name,
|
30
|
+
member_since: @model.join_date.in_time_zone.strftime(date_format),
|
31
|
+
super_user: @model.admin,
|
32
|
+
favorite_team: @model.team.id,
|
33
|
+
all_posts: @model.posts.pluck(:body),
|
34
|
+
created_at: @model.created_at.in_time_zone.strftime(date_format),
|
35
|
+
updated_at: @model.updated_at.in_time_zone.strftime(date_format)
|
36
|
+
}
|
37
|
+
|
38
|
+
@model_hash = {
|
39
|
+
name: @model.name,
|
40
|
+
join_date: @model.join_date,
|
41
|
+
admin: @model.admin,
|
42
|
+
secret: @model.secret,
|
43
|
+
team_id: @model.team_id,
|
44
|
+
posts: @model.posts,
|
45
|
+
created_at: @model.created_at,
|
46
|
+
updated_at: @model.updated_at
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
it_behaves_like "an adapter", secret: secret_token do
|
51
|
+
let(:adapter_class) { UserIntegrationTestAdapter }
|
52
|
+
let(:model) { @model }
|
53
|
+
let(:public_hash) { @public_hash }
|
54
|
+
let(:model_hash) { @model_hash }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
require "active_record_helper"
|
4
|
+
|
5
|
+
module RailsViewAdapters
|
6
|
+
describe AdapterBase do
|
7
|
+
class TestAdapter < AdapterBase
|
8
|
+
def self.simple_maps
|
9
|
+
[[:body, :post_text]]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.to_maps
|
13
|
+
[[:user_id, proc {|v| { user_name: v + 10 } }]]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_maps
|
17
|
+
[[:user_name, proc {|v| { user_id: v + 100 } }]]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.model_fields
|
21
|
+
[:body, :user_id]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.public_fields
|
25
|
+
[:post_text, :user_name]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ARTestAdapter < TestAdapter
|
30
|
+
def self.to_maps
|
31
|
+
[[:user_id, proc {|v| { user_name: User.find(v).name } }]]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.from_maps
|
35
|
+
[[:user_name, proc {|v| { user_id: User.find_by_name(v).id } }]]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#to_model_hash" do
|
40
|
+
let(:internals) { { a: 1, b: 2 } }
|
41
|
+
it "returns the internals" do
|
42
|
+
expect(described_class.new(internals, {}).to_model_hash).to eql(internals)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#to_params_hash" do
|
47
|
+
let(:internals) { { a: 1, b: 2 } }
|
48
|
+
let(:disjoint_extras) { { c: 3 } }
|
49
|
+
let(:overlapping_extras) { { b: 27, c: 3 } }
|
50
|
+
it "merges internals and extras" do
|
51
|
+
expect(described_class.new(internals, disjoint_extras).to_params_hash)
|
52
|
+
.to eql(a: 1, b: 2, c: 3)
|
53
|
+
end
|
54
|
+
it "prefers internals over extras" do
|
55
|
+
expect(described_class.new(internals, overlapping_extras).to_params_hash)
|
56
|
+
.to eql(a: 1, b: 2, c: 3)
|
57
|
+
end
|
58
|
+
it "symbolizes keys" do
|
59
|
+
expect(described_class.new(internals, "c" => 3).to_params_hash)
|
60
|
+
.to eql(a: 1, b: 2, c: 3)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#to_public_hash" do
|
65
|
+
let(:internals) { { body: 2, user_id: 4 } }
|
66
|
+
let(:extras) { { extra_field: "asdf" } }
|
67
|
+
let(:adapter) { TestAdapter.new(internals, extras) }
|
68
|
+
it "returns the public hash w/o extras" do
|
69
|
+
expect(adapter.to_public_hash).to eql(
|
70
|
+
post_text: 2,
|
71
|
+
user_name: 14
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#to_json" do
|
77
|
+
let(:adapter) { described_class.new({}, {}) }
|
78
|
+
let(:public_hash) { double(:public_hash) }
|
79
|
+
let(:options) { { a: 11_313, b: 1231 } }
|
80
|
+
it "delegates to #to_json on the public hash" do
|
81
|
+
allow(adapter).to receive(:to_public_hash).and_return(public_hash)
|
82
|
+
expect(public_hash).to receive(:to_json).with(options)
|
83
|
+
adapter.to_json(options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "::from_model" do
|
88
|
+
let(:model) { Fabricate(:post) }
|
89
|
+
it "instantiates the adapter" do
|
90
|
+
expect(TestAdapter.from_model(model)).to be_an_instance_of(TestAdapter)
|
91
|
+
end
|
92
|
+
it "loads the model as its internals" do
|
93
|
+
expect(TestAdapter.from_model(model).to_model_hash).to eql(
|
94
|
+
body: model.body,
|
95
|
+
user_id: model.user_id
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "::from_public" do
|
101
|
+
let(:user) { Fabricate(:user) }
|
102
|
+
let(:input_hash) do
|
103
|
+
{
|
104
|
+
post_text: Faker::Lorem.paragraph,
|
105
|
+
user_name: user.name,
|
106
|
+
extra_field: 12_345
|
107
|
+
}
|
108
|
+
end
|
109
|
+
it "instantiates the adapter" do
|
110
|
+
expect(ARTestAdapter.from_public(input_hash)).to be_an_instance_of(ARTestAdapter)
|
111
|
+
end
|
112
|
+
it "loads the internals" do
|
113
|
+
expect(ARTestAdapter.from_public(input_hash).to_model_hash).to eql(
|
114
|
+
body: input_hash[:post_text],
|
115
|
+
user_id: user.id
|
116
|
+
)
|
117
|
+
end
|
118
|
+
it "loads the extras" do
|
119
|
+
expect(ARTestAdapter.from_public(input_hash).to_params_hash).to eql(
|
120
|
+
body: input_hash[:post_text],
|
121
|
+
user_id: user.id,
|
122
|
+
extra_field: 12_345
|
123
|
+
)
|
124
|
+
end
|
125
|
+
it "doesn't mutate the public representation" do
|
126
|
+
expect(ARTestAdapter.from_public(input_hash).to_public_hash).to eql(
|
127
|
+
post_text: input_hash[:post_text],
|
128
|
+
user_name: input_hash[:user_name]
|
129
|
+
)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
module RailsViewAdapters
|
5
|
+
describe Adapter do
|
6
|
+
describe "::define" do
|
7
|
+
it "defines a new class" do
|
8
|
+
Adapter.define(:new_test_adapter) {}
|
9
|
+
expect do
|
10
|
+
Object.const_get("NewTestAdapter")
|
11
|
+
end.to_not raise_error
|
12
|
+
end
|
13
|
+
|
14
|
+
it "sets the constant equal to the created adapter" do
|
15
|
+
spy = double(:spy)
|
16
|
+
allow(Adapter).to receive(:adapter_from_map).and_return(spy)
|
17
|
+
Adapter.define(:even_newer) {}
|
18
|
+
expect(EvenNewer).to eql(spy)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "::adapter_from_map" do
|
23
|
+
let(:map) do
|
24
|
+
double(:map,
|
25
|
+
model_fields: [:m1, :m2],
|
26
|
+
public_fields: [:p1, :p2],
|
27
|
+
simple_maps: [[:m1, :p1]],
|
28
|
+
to_maps: [[:m2, double(:proc1)]],
|
29
|
+
from_maps: [[:p2, double(:proc2)]])
|
30
|
+
end
|
31
|
+
let(:adapter) { Adapter.adapter_from_map(map) }
|
32
|
+
it "returns a new class" do
|
33
|
+
expect(adapter).to be_a(Class)
|
34
|
+
end
|
35
|
+
it "inherits from AdapterBase" do
|
36
|
+
expect(adapter).to be <= AdapterBase
|
37
|
+
end
|
38
|
+
[:model_fields, :public_fields, :simple_maps, :to_maps, :from_maps].each do |field|
|
39
|
+
it "adds the ::#{field} method" do
|
40
|
+
expect(adapter.public_send(field)).to eql(map.public_send(field))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
require "active_record_helper"
|
4
|
+
|
5
|
+
module RailsViewAdapters
|
6
|
+
|
7
|
+
class TestMap < Map
|
8
|
+
def to_hash
|
9
|
+
{
|
10
|
+
model_fields: model_fields,
|
11
|
+
public_fields: public_fields,
|
12
|
+
simple_maps: simple_maps,
|
13
|
+
to_maps: to_maps,
|
14
|
+
from_maps: from_maps
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe DefinitionProxy do
|
20
|
+
let(:proxy) { described_class.new(TestMap.new) }
|
21
|
+
let(:bare_hash) do
|
22
|
+
{
|
23
|
+
model_fields: [],
|
24
|
+
public_fields: [],
|
25
|
+
simple_maps: [],
|
26
|
+
to_maps: [],
|
27
|
+
from_maps: []
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#map_simple" do
|
32
|
+
let(:model_field) { :mod }
|
33
|
+
let(:public_field) { :pub }
|
34
|
+
it "creates the correct mapping" do
|
35
|
+
proxy.map_simple(model_field, public_field)
|
36
|
+
expect(proxy.map.to_hash).to eql(bare_hash.merge(
|
37
|
+
public_fields: [public_field],
|
38
|
+
model_fields: [model_field],
|
39
|
+
simple_maps: [[model_field, public_field]]
|
40
|
+
))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#map_to_public" do
|
45
|
+
let(:model_field) { :mod }
|
46
|
+
let(:extra_fields) { [:one, :two] }
|
47
|
+
let(:process) { proc {|v| { one: v + 1, two: v + 2 } } }
|
48
|
+
it "creates the correct mapping" do
|
49
|
+
proxy.map_to_public(model_field, extra_fields, &process)
|
50
|
+
expect(proxy.map.to_hash).to eql(bare_hash.merge(
|
51
|
+
to_maps: [[model_field, process]],
|
52
|
+
public_fields: extra_fields,
|
53
|
+
model_fields: [model_field]
|
54
|
+
))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#map_from_public" do
|
59
|
+
let(:public_field) { :pub }
|
60
|
+
let(:process) { proc {|v| { one: v + 1, two: v + 2 } } }
|
61
|
+
it "creates the correct mapping" do
|
62
|
+
proxy.map_from_public(public_field, &process)
|
63
|
+
expect(proxy.map.to_hash).to eql(bare_hash.merge(
|
64
|
+
from_maps: [[public_field, process]],
|
65
|
+
public_fields: [public_field]
|
66
|
+
))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#hidden_field" do
|
71
|
+
let(:hidden_field) { :hidden }
|
72
|
+
it "adds a model_field" do
|
73
|
+
proxy.hidden_field(hidden_field)
|
74
|
+
expect(proxy.map.to_hash).to eql(bare_hash.merge(
|
75
|
+
model_fields: [hidden_field]
|
76
|
+
))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#map_date" do
|
81
|
+
let(:model_field) { :mod }
|
82
|
+
let(:public_field) { :pub }
|
83
|
+
let(:date_format) { "%Y-%m-%dT%H:%M:%SZ" }
|
84
|
+
let(:time) { Time.new(2016, 10, 31, 12, 25, 33).utc }
|
85
|
+
let(:time_string) { time.strftime(date_format) }
|
86
|
+
it "creates the correct model_fields" do
|
87
|
+
proxy.map_date(model_field, public_field, date_format)
|
88
|
+
expect(proxy.map.model_fields).to eql([model_field])
|
89
|
+
end
|
90
|
+
it "creates the correct public_fields" do
|
91
|
+
proxy.map_date(model_field, public_field, date_format)
|
92
|
+
expect(proxy.map.public_fields).to eql([public_field])
|
93
|
+
end
|
94
|
+
it "creates no simple_maps" do
|
95
|
+
proxy.map_date(model_field, public_field, date_format)
|
96
|
+
expect(proxy.map.simple_maps).to eql([])
|
97
|
+
end
|
98
|
+
it "creates the correct to_maps" do
|
99
|
+
proxy.map_date(model_field, public_field, date_format)
|
100
|
+
expect(proxy.map.to_maps[0]).to contain_exactly(model_field, an_instance_of(Proc))
|
101
|
+
end
|
102
|
+
it "creates the correct from_maps" do
|
103
|
+
proxy.map_date(model_field, public_field, date_format)
|
104
|
+
expect(proxy.map.from_maps[0]).to contain_exactly(public_field, an_instance_of(Proc))
|
105
|
+
end
|
106
|
+
it "defines a to_map that converts the model's date to the public's string" do
|
107
|
+
proxy.map_date(model_field, public_field, date_format)
|
108
|
+
expect(proxy.map.to_maps[0][1].call(time)).to eql(public_field => time_string)
|
109
|
+
end
|
110
|
+
it "defines a from_map that converts the public's string to the model's Time" do
|
111
|
+
proxy.map_date(model_field, public_field, date_format)
|
112
|
+
expect(proxy.map.from_maps[0][1].call(time_string)).to eql(model_field => time)
|
113
|
+
end
|
114
|
+
it "raises ArgumentError if date_format is nil" do
|
115
|
+
expect do
|
116
|
+
proxy.map_date(model_field, public_field, nil)
|
117
|
+
end.to raise_error ArgumentError
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "#map_bool" do
|
122
|
+
let(:model_field) { :mod }
|
123
|
+
let(:public_field) { :pub }
|
124
|
+
it "creates the correct model_fields" do
|
125
|
+
proxy.map_bool(model_field, public_field)
|
126
|
+
expect(proxy.map.model_fields).to eql([model_field])
|
127
|
+
end
|
128
|
+
it "creates the correct public_fields" do
|
129
|
+
proxy.map_bool(model_field, public_field)
|
130
|
+
expect(proxy.map.public_fields).to eql([public_field])
|
131
|
+
end
|
132
|
+
it "creates the correct to_maps" do
|
133
|
+
proxy.map_bool(model_field, public_field)
|
134
|
+
expect(proxy.map.to_maps[0]).to contain_exactly(model_field, an_instance_of(Proc))
|
135
|
+
end
|
136
|
+
it "creates the correct from_maps" do
|
137
|
+
proxy.map_bool(model_field, public_field)
|
138
|
+
expect(proxy.map.from_maps[0]).to contain_exactly(public_field, an_instance_of(Proc))
|
139
|
+
end
|
140
|
+
[true, false, nil].each do |bool|
|
141
|
+
it "defines a to_map that converts models' #{bool} to public's #{bool}" do
|
142
|
+
proxy.map_bool(model_field, public_field)
|
143
|
+
expect(proxy.map.to_maps[0][1].call(bool)).to eql(public_field => bool)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
["true", "True", "t", "T", "yes", "Yes", "Y", "y", "1"].each do |truthy_string|
|
147
|
+
it "defines a from_map that converts public #{truthy_string} to model true" do
|
148
|
+
proxy.map_bool(model_field, public_field)
|
149
|
+
expect(proxy.map.from_maps[0][1].call(truthy_string)).to eql(model_field => true)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
["false", "False", "f", "F", "no", "No", "N", "n", "0"].each do |falsey_string|
|
153
|
+
it "defines a from_map that converts public #{falsey_string} to model false" do
|
154
|
+
proxy.map_bool(model_field, public_field)
|
155
|
+
expect(proxy.map.from_maps[0][1].call(falsey_string)).to eql(model_field => false)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
[nil, "nil", "null"].each do |null|
|
159
|
+
it "defines a from_map that converts public #{null} to model nil" do
|
160
|
+
proxy.map_bool(model_field, public_field)
|
161
|
+
expect(proxy.map.from_maps[0][1].call(null)).to eql(model_field => nil)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "#map_belongs_to" do
|
167
|
+
let(:model_field) { :user_id }
|
168
|
+
let(:public_field) { :user_name }
|
169
|
+
let(:options) { { model_class: User, sub_method: :name } }
|
170
|
+
let(:post) { Fabricate(:post, user: Fabricate(:user)) }
|
171
|
+
it "creates the correct model_fields" do
|
172
|
+
proxy.map_belongs_to(model_field, public_field, options)
|
173
|
+
expect(proxy.map.model_fields).to contain_exactly(model_field)
|
174
|
+
end
|
175
|
+
it "creates the correct public_fields" do
|
176
|
+
proxy.map_belongs_to(model_field, public_field, options)
|
177
|
+
expect(proxy.map.public_fields).to contain_exactly(public_field)
|
178
|
+
end
|
179
|
+
it "creates no simple_maps" do
|
180
|
+
proxy.map_belongs_to(model_field, public_field, options)
|
181
|
+
expect(proxy.map.simple_maps).to eql([])
|
182
|
+
end
|
183
|
+
it "creates the correct to_maps" do
|
184
|
+
proxy.map_belongs_to(model_field, public_field, options)
|
185
|
+
expect(proxy.map.to_maps[0]).to contain_exactly(model_field, an_instance_of(Proc))
|
186
|
+
end
|
187
|
+
it "creates the correct from_maps" do
|
188
|
+
proxy.map_belongs_to(model_field, public_field, options)
|
189
|
+
expect(proxy.map.from_maps[0]).to contain_exactly(public_field, an_instance_of(Proc))
|
190
|
+
end
|
191
|
+
it "defines a to_map that converts the model's parent to the public's field:value string" do
|
192
|
+
proxy.map_belongs_to(model_field, public_field, options)
|
193
|
+
expect(proxy.map.to_maps[0][1].call(post.user.id))
|
194
|
+
.to eql(public_field => post.user.name)
|
195
|
+
end
|
196
|
+
it "defines a from_map that converts the public's string to the model's owning model id" do
|
197
|
+
proxy.map_belongs_to(model_field, public_field, options)
|
198
|
+
expect(proxy.map.from_maps[0][1].call(post.user.name))
|
199
|
+
.to eql(model_field => post.user.id)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe "#map_has_many" do
|
204
|
+
let(:model_field) { :posts }
|
205
|
+
let(:public_field) { :post_dates }
|
206
|
+
let(:options) { { model_class: Post, sub_method: :created_at } }
|
207
|
+
let(:user) { Fabricate(:user) }
|
208
|
+
before(:each) { Fabricate.times(2, :post, user: user) }
|
209
|
+
it "creates the correct model_fields" do
|
210
|
+
proxy.map_has_many(model_field, public_field, options)
|
211
|
+
expect(proxy.map.model_fields).to contain_exactly(model_field)
|
212
|
+
end
|
213
|
+
it "creates the correct public_fields" do
|
214
|
+
proxy.map_has_many(model_field, public_field, options)
|
215
|
+
expect(proxy.map.public_fields).to contain_exactly(public_field)
|
216
|
+
end
|
217
|
+
it "creates no simple_maps" do
|
218
|
+
proxy.map_has_many(model_field, public_field, options)
|
219
|
+
expect(proxy.map.simple_maps).to eql([])
|
220
|
+
end
|
221
|
+
it "creates the correct to_maps" do
|
222
|
+
proxy.map_has_many(model_field, public_field, options)
|
223
|
+
expect(proxy.map.to_maps[0]).to contain_exactly(model_field, an_instance_of(Proc))
|
224
|
+
end
|
225
|
+
it "creates the correct from_maps" do
|
226
|
+
proxy.map_has_many(model_field, public_field, options)
|
227
|
+
expect(proxy.map.from_maps[0]).to contain_exactly(public_field, an_instance_of(Proc))
|
228
|
+
end
|
229
|
+
it "defines a to_map that converts the model's children to the public's Array<String>" do
|
230
|
+
proxy.map_has_many(model_field, public_field, options)
|
231
|
+
expect(proxy.map.to_maps[0][1].call(user.posts))
|
232
|
+
.to eql(public_field => user.posts.pluck(:created_at))
|
233
|
+
end
|
234
|
+
it "defines a from_map that converts the public's string to the model's owning models" do
|
235
|
+
proxy.map_has_many(model_field, public_field, options)
|
236
|
+
expect(proxy.map.from_maps[0][1].call(user.posts.pluck(:created_at).to_a))
|
237
|
+
.to eql(model_field => user.posts.to_a)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|