Skip to content
This repository was archived by the owner on May 1, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions hw1/fibonacci.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Provides iteration over fibonacci sequence within a given size of elements
class Fibonacci
include Enumerable

private

attr_reader :quantity

public

def initialize(quantity = 1)
@quantity = quantity.to_i
raise 'Pass at least one number to iterate over!' if @quantity < 1
end

def each
previous = 1
two_steps_before = 1
quantity.times do |index|
current = index < 2 ? 1 : (previous + two_steps_before)
two_steps_before = previous
previous = current
yield(current)
end
end
end
7 changes: 4 additions & 3 deletions hw2/Gemfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true
source "https://rubygems.org"
source 'https://rubygems.org'

gem "rack"
gem "rspec"
gem 'rack'
gem 'rspec'
gem 'pry-byebug'
12 changes: 12 additions & 0 deletions hw2/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
GEM
remote: https://rubygems.org/
specs:
byebug (9.0.6)
coderay (1.1.1)
diff-lcs (1.2.5)
method_source (0.8.2)
pry (0.10.4)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
pry-byebug (3.4.0)
byebug (~> 9.0)
pry (~> 0.10)
rack (2.0.1)
rspec (3.5.0)
rspec-core (~> 3.5.0)
Expand All @@ -16,11 +26,13 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
slop (3.6.0)

PLATFORMS
ruby

DEPENDENCIES
pry-byebug
rack
rspec

Expand Down
2 changes: 1 addition & 1 deletion hw2/app/app.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Application = Router.new do
Application = Router::Base.new do
get '/test', ->(env) { [200, {}, ['get test']] }
post '/test', ->(env) { [200, {}, ['post test']] }
end
25 changes: 0 additions & 25 deletions hw2/lib/router.rb

This file was deleted.

50 changes: 50 additions & 0 deletions hw2/lib/router/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# rubocop:disable Style/Documentation
module Router
class Base
def initialize(&block)
@routes = {}
instance_exec(&block)
end

def call(env)
current(env)[:rack_app].call(env).tap do |rack_app|
merge_current_params(env, rack_app)
end
end

private

%i(get post put patch update delete).each do |http_method|
define_method http_method do |path, rack_app|
match(http_method.to_s.upcase, path, rack_app)
end
end

def match(http_method, path, rack_app)
@routes[http_method] ||= {}
@routes[http_method][root_path path] = rack_app
end

def current(env)
@routes[env['REQUEST_METHOD']].each do |path, rack_app|
path = path.split('/')
current = root_path(env['REQUEST_PATH']).split('/')
next unless path[1] == current[1]
return { path: path, rack_app: rack_app }
end

{ rack_app: ->(_env) { [404, {}, ['Ooops! We have not found:(']] } }
end

def root_path(path)
path.start_with?('/') ? path : path.prepend('/')
end

def merge_current_params(env, rack_app)
param = env['REQUEST_PATH'].split('/')[2]
return unless param
name = current(env)[:path][1..2].join('_').delete(':').upcase
rack_app[1] = rack_app[1].merge(name => param)
end
end
end
2 changes: 1 addition & 1 deletion hw2/main.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
require './lib/router'
require './lib/router/base'
require './app/app'
91 changes: 73 additions & 18 deletions hw2/spec/lib/router_spec.rb
Original file line number Diff line number Diff line change
@@ -1,34 +1,89 @@
RSpec.describe Router do
# rubocop:disable Metrics/BlockLength
RSpec.describe Router::Base do
subject do
Router.new do
get '/test', ->(env) { [200, {}, ['get test']] }
post '/test', ->(env) { [200, {}, ['post test']] }

##
# TODO: router should match path by pattern like
# Pattern: /posts/:name
# Paths:
# /post/about_ruby
# /post/43
# Cover this with tests.
#
get '/post/:name', ->(env) { [200, {}, ['post show page']] }
Router::Base.new do
get '/test', ->(_env) { [200, {}, ['get test']] }
post '/test', ->(_env) { [200, {}, ['post test']] }
get '/posts/:name', ->(_env) { [200, {}, ['post show page']] }
# get '/posts/:name/comments/:content',
# ->(_env) { [200, {}, ['deep comment show page']] }
end
end

context 'when request is GET' do
let(:env) { { 'REQUEST_PATH' => '/test', 'REQUEST_METHOD' => 'GET'} }
context 'under GET' do
let(:env) { { 'REQUEST_PATH' => '/test', 'REQUEST_METHOD' => 'GET' } }

it 'matches request' do
expect(subject.call(env)).to eq [200, {}, ['get test']]
end
end

context 'when request is POST' do
let(:env) { { 'REQUEST_PATH' => '/test', 'REQUEST_METHOD' => 'POST'} }
context 'under POST' do
let(:env) { { 'REQUEST_PATH' => '/test', 'REQUEST_METHOD' => 'POST' } }

it 'matches request' do
expect(subject.call(env)).to eq [200, {}, ['post test']]
end
end

context 'under unspecified route' do
let(:envs) do
[
{ 'REQUEST_PATH' => '/missing', 'REQUEST_METHOD' => 'GET' },
{ 'REQUEST_PATH' => '/missing', 'REQUEST_METHOD' => 'POST' }
]
end

it 'renders 404' do
envs.each do |env|
expect(subject.call(env))
.to eq [404, {}, ['Ooops! We have not found:(']]
end
end
end

context 'under route with parameters' do
context 'with one parameter' do
let(:envs) do
[
{ 'REQUEST_PATH' => '/posts/about_ruby', 'REQUEST_METHOD' => 'GET' },
{ 'REQUEST_PATH' => '/posts/43', 'REQUEST_METHOD' => 'GET' },
{ 'REQUEST_PATH' => 'posts/43', 'REQUEST_METHOD' => 'GET' }
]
end

it 'will recognize it' do
envs.each do |env|
expect(subject.call(env)[0]).to eq 200
expect(subject.call(env)[2]).to eq ['post show page']
end
end

it 'will return passed parameter' do
envs.each do |env|
expect(%w(about_ruby 43))
.to include(subject.call(env)[1]['POSTS_NAME'])
end
end
end

# context 'with nested parameters' do
# let(:envs) do
# [
# { 'REQUEST_PATH' => '/posts/about_ruby', 'REQUEST_METHOD' => 'GET' },
# { 'REQUEST_PATH' => '/posts/43', 'REQUEST_METHOD' => 'GET' },
# { 'REQUEST_PATH' => 'posts/43', 'REQUEST_METHOD' => 'GET' }
# ]
# end
#
# it 'will recognize it' do
# envs.each do |env|
# expect(subject.call(env)[0]).to eq 200
# expect(subject.call(env)[2]).to eq ['post show page']
# end
# end
#
# it 'will return passed parameters for nested route'
# end
end
end
3 changes: 2 additions & 1 deletion hw2/spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require './lib/router'
# rubocop:disable all
require './main'

RSpec.configure do |config|
config.expect_with :rspec do |expectations|
Expand Down