almanack 1.0.5 → 1.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/almanack.gemspec +1 -0
- data/example.ru +4 -4
- data/lib/almanack/base.rb +22 -0
- data/lib/almanack/calendar.rb +9 -27
- data/lib/almanack/configuration.rb +15 -4
- data/lib/almanack/event.rb +56 -5
- data/lib/almanack/event_source/ical_feed.rb +6 -2
- data/lib/almanack/event_source/meetup_group.rb +26 -5
- data/lib/almanack/event_source/static.rb +5 -1
- data/lib/almanack/representation/ical_feed.rb +59 -0
- data/lib/almanack/representation/json_feed.rb +55 -0
- data/lib/almanack/serialized_transformation.rb +53 -0
- data/lib/almanack/server/environment.rb +38 -0
- data/lib/almanack/server/helpers.rb +32 -28
- data/lib/almanack/server.rb +23 -37
- data/lib/almanack/themes/legacy/views/events.erb +2 -2
- data/lib/almanack/themes/starter/views/events.erb +2 -2
- data/lib/almanack/version.rb +1 -1
- data/lib/almanack.rb +4 -18
- data/spec/calendar_spec.rb +10 -3
- data/spec/configuration_spec.rb +10 -0
- data/spec/event_source/ical_feed_spec.rb +15 -2
- data/spec/event_source/meetup_group_spec.rb +23 -2
- data/spec/event_source/static_spec.rb +25 -7
- data/spec/event_spec.rb +80 -11
- data/spec/features/api_feature_spec.rb +24 -0
- data/spec/features/calendar_feature_spec.rb +3 -3
- data/spec/features/subscription_feature_spec.rb +5 -5
- data/spec/representation/json_feed_spec.rb +44 -0
- data/spec/serialized_transformation_spec.rb +45 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/event_matchers.rb +1 -1
- data/templates/new/config.ru.tt +1 -1
- metadata +29 -4
data/lib/almanack/server.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "rack/contrib"
|
1
2
|
require "sinatra"
|
2
3
|
require "sinatra/reloader"
|
3
4
|
require "sass"
|
@@ -6,67 +7,52 @@ require "almanack"
|
|
6
7
|
module Almanack
|
7
8
|
class Server < Sinatra::Base
|
8
9
|
require "almanack/server/helpers"
|
10
|
+
require "almanack/server/environment"
|
9
11
|
|
10
|
-
|
11
|
-
register Sinatra::Reloader
|
12
|
-
end
|
12
|
+
include Almanack::ServerContext::Environment
|
13
13
|
|
14
14
|
set :root, -> { Almanack.config.theme_root }
|
15
15
|
set :protection, except: :frame_options
|
16
|
-
set :feed_path, "feed
|
17
|
-
|
18
|
-
not_found do
|
19
|
-
status 404
|
20
|
-
erb :error
|
21
|
-
end
|
22
|
-
|
23
|
-
error do
|
24
|
-
status 500
|
25
|
-
erb :error
|
26
|
-
end
|
16
|
+
set :feed_path, "feed"
|
27
17
|
|
28
|
-
|
29
|
-
Pathname(file).split.last.to_s.split(".", 2).first
|
30
|
-
end
|
18
|
+
use Rack::JSONP
|
31
19
|
|
32
|
-
|
33
|
-
|
34
|
-
path = settings.root.join(within)
|
35
|
-
available = Pathname.glob(path.join("*"))
|
36
|
-
asset = available.find { |path| basename(path) == name }
|
37
|
-
raise "Could not find stylesheet #{name} inside #{available}" if asset.nil?
|
38
|
-
asset
|
20
|
+
configure :development do
|
21
|
+
register Sinatra::Reloader
|
39
22
|
end
|
40
23
|
|
41
|
-
|
42
|
-
|
43
|
-
content = asset.read
|
44
|
-
respond_to?(renderer) ? send(renderer, content) : content
|
24
|
+
helpers do
|
25
|
+
include Almanack::ServerContext::Helpers
|
45
26
|
end
|
46
27
|
|
47
|
-
|
48
|
-
|
28
|
+
before do
|
29
|
+
register_sass_loadpaths!
|
49
30
|
end
|
50
31
|
|
51
|
-
|
52
|
-
|
32
|
+
not_found do
|
33
|
+
status 404
|
34
|
+
erb :error
|
53
35
|
end
|
54
36
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
37
|
+
error do
|
38
|
+
status 500
|
39
|
+
erb :error
|
59
40
|
end
|
60
41
|
|
61
42
|
get "/" do
|
62
43
|
erb :events
|
63
44
|
end
|
64
45
|
|
65
|
-
get "/#{settings.feed_path}" do
|
46
|
+
get "/#{settings.feed_path}.ics" do
|
66
47
|
content_type "text/calendar"
|
67
48
|
Almanack.calendar.ical_feed
|
68
49
|
end
|
69
50
|
|
51
|
+
get "/#{settings.feed_path}.json" do
|
52
|
+
content_type :json
|
53
|
+
Almanack.calendar.json_feed
|
54
|
+
end
|
55
|
+
|
70
56
|
get "/stylesheets/:name" do
|
71
57
|
content_type :css
|
72
58
|
auto_render_asset params[:name], within: "stylesheets"
|
@@ -4,8 +4,8 @@
|
|
4
4
|
<% calendar.events.each do |event| %>
|
5
5
|
<div class="event">
|
6
6
|
<div class="date">
|
7
|
-
<div class="month"><%= event.
|
8
|
-
<div class="day"><%= event.
|
7
|
+
<div class="month"><%= event.start_time.strftime('%a') %></div>
|
8
|
+
<div class="day"><%= event.start_time.strftime('%d') %></div>
|
9
9
|
</div>
|
10
10
|
<div class="details">
|
11
11
|
<h3 class="title"><%= event.title %></h3>
|
@@ -4,8 +4,8 @@
|
|
4
4
|
<% calendar.events.each do |event| %>
|
5
5
|
<div class="event">
|
6
6
|
<div class="date">
|
7
|
-
<div class="month"><%= event.
|
8
|
-
<div class="day"><%= event.
|
7
|
+
<div class="month"><%= event.start_time.strftime('%a') %></div>
|
8
|
+
<div class="day"><%= event.start_time.strftime('%d') %></div>
|
9
9
|
</div>
|
10
10
|
<div class="details">
|
11
11
|
<h3 class="title"><%= event.title %></h3>
|
data/lib/almanack/version.rb
CHANGED
data/lib/almanack.rb
CHANGED
@@ -4,28 +4,14 @@ require "ri_cal"
|
|
4
4
|
require "addressable/uri"
|
5
5
|
require "faraday"
|
6
6
|
|
7
|
+
require "almanack/base"
|
7
8
|
require "almanack/version"
|
8
9
|
require "almanack/configuration"
|
9
10
|
require "almanack/calendar"
|
11
|
+
require "almanack/serialized_transformation"
|
12
|
+
require "almanack/representation/ical_feed"
|
13
|
+
require "almanack/representation/json_feed"
|
10
14
|
require "almanack/event"
|
11
15
|
require "almanack/event_source/static"
|
12
16
|
require "almanack/event_source/meetup_group"
|
13
17
|
require "almanack/event_source/ical_feed"
|
14
|
-
|
15
|
-
module Almanack
|
16
|
-
class << self
|
17
|
-
def config(&block)
|
18
|
-
@config ||= Configuration.new
|
19
|
-
yield @config if block_given?
|
20
|
-
@config
|
21
|
-
end
|
22
|
-
|
23
|
-
def calendar
|
24
|
-
@calendar ||= Calendar.new(config)
|
25
|
-
end
|
26
|
-
|
27
|
-
def reset!
|
28
|
-
config.reset!
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/spec/calendar_spec.rb
CHANGED
@@ -42,9 +42,9 @@ module Almanack
|
|
42
42
|
|
43
43
|
config = Configuration.new
|
44
44
|
config.add_events [
|
45
|
-
{ title: 'Today',
|
46
|
-
{ title: 'Yesterday',
|
47
|
-
{ title: 'Tomorrow',
|
45
|
+
{ title: 'Today', start_time: today },
|
46
|
+
{ title: 'Yesterday', start_time: yesterday },
|
47
|
+
{ title: 'Tomorrow', start_time: tomorrow },
|
48
48
|
]
|
49
49
|
|
50
50
|
calendar = Calendar.new(config)
|
@@ -60,5 +60,12 @@ module Almanack
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
describe "#feed_lookahead" do
|
64
|
+
it "delegates to the configuration's feed_lookahead" do
|
65
|
+
config = double(feed_lookahead: :delegated)
|
66
|
+
expect(Calendar.new(config).feed_lookahead).to eq(:delegated)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
63
70
|
end
|
64
71
|
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -37,6 +37,16 @@ module Almanack
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
describe "#feed_lookahead" do
|
41
|
+
specify { expect(Configuration.new.feed_lookahead).to eq(365) }
|
42
|
+
|
43
|
+
specify "it can be set" do
|
44
|
+
config = Configuration.new
|
45
|
+
config.feed_lookahead = 30
|
46
|
+
expect(config.feed_lookahead).to eq(30)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
40
50
|
describe "#add_events" do
|
41
51
|
it "adds a simple event collection event source" do
|
42
52
|
config = Configuration.new
|
@@ -16,10 +16,23 @@ module Almanack::EventSource
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
start_times = events.map(&:start_time)
|
20
20
|
|
21
21
|
expect(events.length).to eq(15)
|
22
|
-
expect(events).to all_have_properties(:title, :
|
22
|
+
expect(events).to all_have_properties(:title, :start_time, :end_time, :description, :location)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#serialized_between" do
|
27
|
+
it "returns a hash containing attributes" do
|
28
|
+
source = IcalFeed.new 'url'
|
29
|
+
|
30
|
+
events = [double(serialized: :serialized_event)]
|
31
|
+
expect(source).to receive(:events_between).with(:date_range) { events }
|
32
|
+
|
33
|
+
expect(source.serialized_between(:date_range)).to eq({
|
34
|
+
events: [:serialized_event]
|
35
|
+
})
|
23
36
|
end
|
24
37
|
end
|
25
38
|
|
@@ -17,10 +17,10 @@ module Almanack::EventSource
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
start_times = events.map(&:start_time)
|
21
21
|
|
22
22
|
expect(events.length).to eq(5)
|
23
|
-
expect(events).to all_have_properties(:title, :
|
23
|
+
expect(events).to all_have_properties(:title, :start_time, :end_time, :description, :location)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "handles a missing location" do
|
@@ -38,5 +38,26 @@ module Almanack::EventSource
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
describe "#serialized_between" do
|
42
|
+
it "returns a hash containing attributes" do
|
43
|
+
feed = MeetupGroup.new(group_urlname: 'The-Foundation-Christchurch',
|
44
|
+
key: 'secrettoken',
|
45
|
+
connection: Faraday.new)
|
46
|
+
serialized = nil
|
47
|
+
|
48
|
+
Timecop.freeze(2014, 5, 24) do
|
49
|
+
VCR.use_cassette('meetup') do
|
50
|
+
from = Time.now
|
51
|
+
to = from + 30 * 24 * 60 * 60
|
52
|
+
serialized = feed.serialized_between(from..to)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
expect(serialized[:events].length).to eq 5
|
57
|
+
expect(serialized[:name]).to eq("The Foundation")
|
58
|
+
expect(serialized[:url]).to eq("http://www.meetup.com/The-Foundation-Christchurch")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
41
62
|
end
|
42
63
|
end
|
@@ -2,16 +2,20 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Almanack::EventSource
|
4
4
|
describe Static do
|
5
|
+
let(:yesterday) { now - 1 }
|
6
|
+
let(:now) { Time.now }
|
7
|
+
let(:tomorrow) { now + 1 }
|
8
|
+
|
9
|
+
around do |test|
|
10
|
+
Timecop.freeze(now, &test)
|
11
|
+
end
|
12
|
+
|
5
13
|
describe "#events_between" do
|
6
14
|
it "returns events between two dates" do
|
7
|
-
now = Time.now
|
8
|
-
yesterday = now - 1
|
9
|
-
tomorrow = now + 1
|
10
|
-
|
11
15
|
source = Static.new [
|
12
|
-
{ title: 'Yesterday',
|
13
|
-
{ title: 'Today',
|
14
|
-
{ title: 'Tomorrow',
|
16
|
+
{ title: 'Yesterday', start_time: yesterday },
|
17
|
+
{ title: 'Today', start_time: now },
|
18
|
+
{ title: 'Tomorrow', start_time: tomorrow }
|
15
19
|
]
|
16
20
|
|
17
21
|
expect(source.events_between(yesterday..tomorrow).map(&:title)).to eq(%w( Yesterday Today Tomorrow ))
|
@@ -19,5 +23,19 @@ module Almanack::EventSource
|
|
19
23
|
expect(source.events_between(yesterday..now).map(&:title)).to eq(%w( Yesterday Today ))
|
20
24
|
end
|
21
25
|
end
|
26
|
+
|
27
|
+
describe "#serialized_between" do
|
28
|
+
it "returns a hash containing attributes" do
|
29
|
+
source = Static.new []
|
30
|
+
date_range = yesterday..tomorrow
|
31
|
+
|
32
|
+
events = [double(serialized: :serialized_event)]
|
33
|
+
expect(source).to receive(:events_between).with(date_range) { events }
|
34
|
+
|
35
|
+
expect(source.serialized_between(date_range)).to eq({
|
36
|
+
events: [:serialized_event]
|
37
|
+
})
|
38
|
+
end
|
39
|
+
end
|
22
40
|
end
|
23
41
|
end
|
data/spec/event_spec.rb
CHANGED
@@ -8,14 +8,14 @@ module Almanack
|
|
8
8
|
expect(event.title).to eq("Music with rocks in")
|
9
9
|
end
|
10
10
|
|
11
|
-
it "has a start
|
12
|
-
event = Event.new(
|
13
|
-
expect(event.
|
11
|
+
it "has a start time" do
|
12
|
+
event = Event.new(start_time: Time.new(2014, 01, 01))
|
13
|
+
expect(event.start_time).to eq_time(Time.new(2014, 01, 01))
|
14
14
|
end
|
15
15
|
|
16
|
-
it "has a end
|
17
|
-
event = Event.new(
|
18
|
-
expect(event.
|
16
|
+
it "has a end time" do
|
17
|
+
event = Event.new(end_time: Time.new(2014, 01, 02))
|
18
|
+
expect(event.end_time).to eq_time(Time.new(2014, 01, 02))
|
19
19
|
end
|
20
20
|
|
21
21
|
it "has a location" do
|
@@ -30,23 +30,92 @@ module Almanack
|
|
30
30
|
|
31
31
|
describe "#formatted_date" do
|
32
32
|
it "handles events without an end date" do
|
33
|
-
event = Event.new(
|
33
|
+
event = Event.new(start_time: Time.parse("2014-07-06 06:24:00 UTC"))
|
34
34
|
expect(event.formatted_date).to eq("July 6 2014 at 6:24am")
|
35
35
|
end
|
36
36
|
|
37
37
|
it "handles events with an end date on the same day" do
|
38
|
-
event = Event.new(
|
39
|
-
|
38
|
+
event = Event.new(start_time: Time.parse("2014-07-06 06:24:00 UTC"),
|
39
|
+
end_time: Time.parse("2014-07-06 13:20:00 UTC"))
|
40
40
|
expect(event.formatted_date).to eq("July 6 2014 at 6:24am to 1:20pm")
|
41
41
|
end
|
42
42
|
|
43
43
|
it "handles events with an end date on a different day" do
|
44
|
-
event = Event.new(
|
45
|
-
|
44
|
+
event = Event.new(start_time: Time.parse("2014-07-06 06:00:00 UTC"),
|
45
|
+
end_time: Time.parse("2014-08-07 10:00:00 UTC"))
|
46
46
|
expect(event.formatted_date).to eq("July 6 2014 at 6:00am to August 7 2014 at 10:00am")
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
describe "#start_date" do
|
51
|
+
it "returns start_time for legacy reasons" do
|
52
|
+
event = Event.new(start_time: Time.new(2014, 01, 01))
|
53
|
+
result = nil
|
54
|
+
expect { result = event.start_date }.to output(/deprecated/i).to_stderr
|
55
|
+
expect(result).to eq_time(Time.new(2014, 01, 01))
|
56
|
+
end
|
57
|
+
|
58
|
+
it "can be set via start_date for legacy reasons" do
|
59
|
+
event = Event.new(start_date: Time.new(2014, 01, 01))
|
60
|
+
result = nil
|
61
|
+
expect { result = event.start_time }.to output(/deprecated/i).to_stderr
|
62
|
+
expect(result).to eq_time(Time.new(2014, 01, 01))
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises an error when both start_date and start_time are given" do
|
66
|
+
event = Event.new(start_date: Time.new(2014, 01, 01),
|
67
|
+
start_time: Time.new(2014, 01, 02))
|
68
|
+
expect { event.start_date }.to raise_error
|
69
|
+
expect { event.start_time }.to raise_error
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#end_date" do
|
74
|
+
it "returns end_time for legacy reasons" do
|
75
|
+
event = Event.new(end_time: Time.new(2014, 01, 01))
|
76
|
+
result = nil
|
77
|
+
expect { result = event.end_date }.to output(/deprecated/i).to_stderr
|
78
|
+
expect(result).to eq_time(Time.new(2014, 01, 01))
|
79
|
+
end
|
80
|
+
|
81
|
+
it "can be set via end_date for legacy reasons" do
|
82
|
+
event = Event.new(end_date: Time.new(2014, 01, 01))
|
83
|
+
result = nil
|
84
|
+
expect { result = event.end_time }.to output(/deprecated/i).to_stderr
|
85
|
+
expect(result).to eq_time(Time.new(2014, 01, 01))
|
86
|
+
end
|
87
|
+
|
88
|
+
it "raises an error when both end_date and end_time are given" do
|
89
|
+
event = Event.new(end_date: Time.new(2014, 01, 01),
|
90
|
+
end_time: Time.new(2014, 01, 02))
|
91
|
+
expect { event.end_date }.to raise_error
|
92
|
+
expect { event.end_time }.to raise_error
|
93
|
+
end
|
94
|
+
|
95
|
+
it "does not output a deprecation warning when using end_time if neither end_date or end_time is set" do
|
96
|
+
event = Event.new
|
97
|
+
expect { event.end_time }.not_to output.to_stderr
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#serialized" do
|
102
|
+
it "returns attributes as a hash" do
|
103
|
+
wed = Time.new(2014, 01, 01)
|
104
|
+
thu = Time.new(2014, 01, 02)
|
105
|
+
|
106
|
+
event = Event.new(title: "Hogswatch",
|
107
|
+
start_time: wed,
|
108
|
+
end_time: thu,
|
109
|
+
arbitrary: true)
|
110
|
+
|
111
|
+
expect(event.serialized).to eq({
|
112
|
+
title: "Hogswatch",
|
113
|
+
start_time: wed.iso8601,
|
114
|
+
end_time: thu.iso8601,
|
115
|
+
arbitrary: true
|
116
|
+
})
|
117
|
+
end
|
118
|
+
end
|
50
119
|
|
51
120
|
end
|
52
121
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "API", :feature do
|
4
|
+
before { Almanack.reset! }
|
5
|
+
|
6
|
+
describe "/feed.json" do
|
7
|
+
it "has a JSON content-type" do
|
8
|
+
get '/feed.json'
|
9
|
+
expect(last_response['Content-Type']).to eq 'application/json'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns the JSON feed" do
|
13
|
+
allow(Almanack.calendar).to receive(:json_feed) { "feed" }
|
14
|
+
get '/feed.json'
|
15
|
+
expect(last_response.body).to eq("feed")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "supports JSONP" do
|
19
|
+
allow(Almanack.calendar).to receive(:json_feed) { "feed" }
|
20
|
+
get '/feed.json?callback=custom'
|
21
|
+
expect(last_response.body).to include("custom(feed)")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -7,9 +7,9 @@ describe "Viewing a calendar", :feature do
|
|
7
7
|
now = Time.now
|
8
8
|
|
9
9
|
Almanack.config.add_events [
|
10
|
-
{ title: "Hogswatch",
|
11
|
-
{ title: "Soul Cake Tuesday",
|
12
|
-
{ title: "Eve of Small Gods",
|
10
|
+
{ title: "Hogswatch", start_time: now },
|
11
|
+
{ title: "Soul Cake Tuesday", start_time: now + 10 * 24 * 60 * 60 },
|
12
|
+
{ title: "Eve of Small Gods", start_time: now + 30 * 24 * 60 * 60 },
|
13
13
|
]
|
14
14
|
|
15
15
|
Timecop.freeze(now) do
|
@@ -12,13 +12,13 @@ describe "Consolidated iCal feed", :feature do
|
|
12
12
|
Almanack.reset!
|
13
13
|
|
14
14
|
Almanack.config.add_events [
|
15
|
-
{ title: "Basic",
|
16
|
-
{ title: "Almost a year away",
|
17
|
-
{ title: "Over a year away",
|
15
|
+
{ title: "Basic", start_time: now },
|
16
|
+
{ title: "Almost a year away", start_time: now + 364 * 24 * 60 * 60 },
|
17
|
+
{ title: "Over a year away", start_time: now + 366 * 24 * 60 * 60 },
|
18
18
|
{
|
19
19
|
title: "Complex",
|
20
|
-
|
21
|
-
|
20
|
+
start_time: now,
|
21
|
+
end_time: now + 30 * 24 * 60 * 60,
|
22
22
|
description: "Body",
|
23
23
|
location: "CA"
|
24
24
|
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Almanack::Representation
|
4
|
+
describe JSONFeed do
|
5
|
+
|
6
|
+
let(:calendar) { Almanack.calendar }
|
7
|
+
let(:parsed_json) { JSON.parse JSONFeed.from(calendar).to_s }
|
8
|
+
|
9
|
+
before do
|
10
|
+
Almanack.reset!
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".from" do
|
14
|
+
around do |test|
|
15
|
+
Timecop.freeze(Time.now, &test)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns empty event sources by default" do
|
19
|
+
expect(parsed_json).to eq({ "eventSources" => [] })
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns event sources" do
|
23
|
+
Almanack.config.add_events [
|
24
|
+
{ title: "Basic event", start_time: Time.now, custom_data: 'present' }
|
25
|
+
]
|
26
|
+
|
27
|
+
expect(parsed_json).to eq({
|
28
|
+
"eventSources" => [
|
29
|
+
{
|
30
|
+
"events" => [
|
31
|
+
{
|
32
|
+
"title" => "Basic event",
|
33
|
+
"startTime" => Time.now.iso8601,
|
34
|
+
"customData" => 'present'
|
35
|
+
}
|
36
|
+
]
|
37
|
+
}
|
38
|
+
]
|
39
|
+
})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Almanack
|
4
|
+
describe SerializedTransformation do
|
5
|
+
let(:fact_book) do
|
6
|
+
{
|
7
|
+
title: "Facts of the World",
|
8
|
+
countries: [
|
9
|
+
{ name: "New Zealand", population: "4 mil" },
|
10
|
+
{ name: "America", population: "320 mil" }
|
11
|
+
]
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:transformation) { described_class.new(fact_book) }
|
16
|
+
|
17
|
+
describe "#apply" do
|
18
|
+
it "returns an unmodified structure by default" do
|
19
|
+
expect(transformation.apply).to eq fact_book
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can apply changes to keys" do
|
23
|
+
transformation.key { |key| key.to_s }
|
24
|
+
expect(transformation.apply).to eq({
|
25
|
+
"title" => "Facts of the World",
|
26
|
+
"countries" => [
|
27
|
+
{ "name" => "New Zealand", "population" => "4 mil" },
|
28
|
+
{ "name" => "America", "population" => "320 mil" }
|
29
|
+
]
|
30
|
+
})
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can apply changes to values" do
|
34
|
+
transformation.value { |value| value.upcase }
|
35
|
+
expect(transformation.apply).to eq({
|
36
|
+
title: "FACTS OF THE WORLD",
|
37
|
+
countries: [
|
38
|
+
{ name: "NEW ZEALAND", population: "4 MIL" },
|
39
|
+
{ name: "AMERICA", population: "320 MIL" }
|
40
|
+
]
|
41
|
+
})
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
CHANGED