mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-03-25 01:14:43 +00:00
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
.git
|
||||
frontend/node_modules
|
||||
log
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@
|
||||
/tmp
|
||||
.rvmrc
|
||||
/deploy/prod.env
|
||||
frontend/node_modules
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -56,7 +56,9 @@ gem 'spring', :group => :development
|
||||
gem 'delayed_job_active_record'
|
||||
gem 'puma'
|
||||
gem 'brakeman'
|
||||
gem 'rails-lineman'
|
||||
group :development do
|
||||
|
||||
#gem 'bullet'
|
||||
end
|
||||
|
||||
|
||||
@@ -131,6 +131,8 @@ GEM
|
||||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
rails-html-sanitizer (1.0.2)
|
||||
loofah (~> 2.0)
|
||||
rails-lineman (0.3.0)
|
||||
rake
|
||||
rails_12factor (0.0.3)
|
||||
rails_serve_static_assets
|
||||
rails_stdout_logging
|
||||
@@ -207,6 +209,7 @@ DEPENDENCIES
|
||||
passenger
|
||||
puma
|
||||
rails (= 4.2.5)
|
||||
rails-lineman
|
||||
rails_12factor
|
||||
rb-readline
|
||||
round_robin_tournament
|
||||
@@ -217,5 +220,8 @@ DEPENDENCIES
|
||||
turbolinks
|
||||
uglifier (>= 1.3.0)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.3.0p0
|
||||
|
||||
BUNDLED WITH
|
||||
1.11.2
|
||||
1.13.5
|
||||
|
||||
3
app/assets/javascripts/api.js.coffee
Normal file
3
app/assets/javascripts/api.js.coffee
Normal file
@@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
||||
4
app/assets/stylesheets/api.css
Normal file
4
app/assets/stylesheets/api.css
Normal file
@@ -0,0 +1,4 @@
|
||||
/*
|
||||
Place all the styles related to the matching controller here.
|
||||
They will automatically be included in application.css.
|
||||
*/
|
||||
28
app/controllers/api_controller.rb
Normal file
28
app/controllers/api_controller.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
class ApiController < ApplicationController
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
def index
|
||||
|
||||
end
|
||||
|
||||
def tournaments
|
||||
if params[:search]
|
||||
@tournaments = Tournament.search(params[:search]).order("created_at DESC")
|
||||
else
|
||||
@tournaments = Tournament.all.sort_by{|t| t.daysUntil}.first(20)
|
||||
end
|
||||
end
|
||||
|
||||
def tournament
|
||||
@tournament = Tournament.where(:id => params[:tournament]).includes(:schools,:weights,:mats,:matches,:user,:wrestlers).first
|
||||
end
|
||||
|
||||
def newTournament
|
||||
@tournament = Tournament.new(JSON.parse(params[:tournament]))
|
||||
@tournament.save
|
||||
end
|
||||
|
||||
def currentUserTournaments
|
||||
@tournaments = current_user.tournaments
|
||||
end
|
||||
end
|
||||
@@ -3,8 +3,21 @@ class ApplicationController < ActionController::Base
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
after_filter :set_csrf_cookie_for_ng
|
||||
|
||||
def set_csrf_cookie_for_ng
|
||||
cookies['XSRF-TOKEN'] = form_authenticity_token if protect_against_forgery?
|
||||
end
|
||||
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
# flash[:error] = "Access denied!"
|
||||
redirect_to '/static_pages/not_allowed'
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# In Rails 4.2 and above
|
||||
def verified_request?
|
||||
super || valid_authenticity_token?(session, request.headers['X-XSRF-TOKEN'])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -163,7 +163,7 @@ class TournamentsController < ApplicationController
|
||||
end
|
||||
|
||||
def generate_matches
|
||||
@tournament.generateMatchups
|
||||
GenerateTournamentMatches.new(@tournament).generate
|
||||
end
|
||||
|
||||
def brackets
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class WeightsController < ApplicationController
|
||||
before_action :set_weight, only: [:show, :edit, :update, :destroy]
|
||||
before_filter :check_access, only: [:new,:create,:update,:destroy,:edit]
|
||||
before_action :set_weight, only: [:show, :edit, :update, :destroy,:re_gen]
|
||||
before_filter :check_access, only: [:new,:create,:update,:destroy,:edit, :re_gen]
|
||||
|
||||
|
||||
# GET /weights/1
|
||||
@@ -69,6 +69,11 @@ class WeightsController < ApplicationController
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
def re_gen
|
||||
@tournament = @weight.tournament
|
||||
GenerateTournamentMatches.new(@tournament).generateWeight(@weight)
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
|
||||
@@ -31,6 +31,7 @@ class WrestlersController < ApplicationController
|
||||
def edit
|
||||
@weight = @wrestler.weight
|
||||
@weights = @school.tournament.weights.sort_by{|w| w.max}
|
||||
@school = @wrestler.school
|
||||
end
|
||||
|
||||
# POST /wrestlers
|
||||
|
||||
2
app/helpers/api_helper.rb
Normal file
2
app/helpers/api_helper.rb
Normal file
@@ -0,0 +1,2 @@
|
||||
module ApiHelper
|
||||
end
|
||||
@@ -1,62 +0,0 @@
|
||||
module GeneratesTournamentMatches
|
||||
|
||||
def generateMatchups
|
||||
self.curently_generating_matches = 1
|
||||
self.save
|
||||
resetSchoolScores
|
||||
setSeedsAndRandomSeedingWrestlersWithoutSeeds
|
||||
poolToBracket() if tournament_type == "Pool to bracket"
|
||||
self.curently_generating_matches = nil
|
||||
self.save
|
||||
matches
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :generateMatchups
|
||||
end
|
||||
|
||||
def poolToBracket
|
||||
destroyAllMatches
|
||||
buildTournamentWeights
|
||||
generateMatches
|
||||
# This is not working for pool order and I cannot get tests working
|
||||
movePoolSeedsToFinalPoolRound
|
||||
end
|
||||
|
||||
def buildTournamentWeights
|
||||
weights.order(:max).each do |weight|
|
||||
Pool.new(weight).generatePools()
|
||||
last_match = matches.where(weight: weight).order(round: :desc).limit(1).first
|
||||
highest_round = last_match.round
|
||||
PoolBracket.new(weight, highest_round).generateBracketMatches()
|
||||
end
|
||||
end
|
||||
|
||||
def generateMatches
|
||||
moveFinalsMatchesToLastRound
|
||||
assignBouts
|
||||
assignLoserNames
|
||||
assignFirstMatchesToMats
|
||||
end
|
||||
|
||||
def moveFinalsMatchesToLastRound
|
||||
finalsRound = self.totalRounds
|
||||
finalsMatches = self.matches.select{|m| m.bracket_position == "1/2" || m.bracket_position == "3/4" || m.bracket_position == "5/6" || m.bracket_position == "7/8"}
|
||||
finalsMatches. each do |m|
|
||||
m.round = finalsRound
|
||||
m.save
|
||||
end
|
||||
end
|
||||
|
||||
def setSeedsAndRandomSeedingWrestlersWithoutSeeds
|
||||
weights.each do |w|
|
||||
w.setSeeds
|
||||
end
|
||||
end
|
||||
|
||||
def movePoolSeedsToFinalPoolRound
|
||||
self.weights.each do |w|
|
||||
w.setOriginalSeedsToWrestleLastPoolRound
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -7,6 +7,10 @@ class Match < ActiveRecord::Base
|
||||
|
||||
|
||||
after_update do
|
||||
after_update_actions
|
||||
end
|
||||
|
||||
def after_update_actions
|
||||
if self.finished == 1 && self.winner_id != nil
|
||||
if self.w1 && self.w2
|
||||
wrestler1.touch
|
||||
@@ -28,9 +32,7 @@ class Match < ActiveRecord::Base
|
||||
wrestler2.school.calcScore
|
||||
end
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :calcSchoolPoints
|
||||
end
|
||||
|
||||
|
||||
def mat_assigned
|
||||
if self.mat
|
||||
@@ -53,15 +55,11 @@ class Match < ActiveRecord::Base
|
||||
|
||||
def advance_wrestlers
|
||||
if self.w1 && self.w2
|
||||
@w1 = wrestler1
|
||||
@w2 = wrestler2
|
||||
@w1.advanceInBracket(self)
|
||||
@w2.advanceInBracket(self)
|
||||
AdvanceWrestler.new(wrestler1).advance
|
||||
AdvanceWrestler.new(wrestler2).advance
|
||||
end
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :advance_wrestlers
|
||||
end
|
||||
|
||||
|
||||
def bracketScore
|
||||
if self.finished != 1
|
||||
|
||||
@@ -24,6 +24,9 @@ class School < ActiveRecord::Base
|
||||
self.score = newScore
|
||||
self.save
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :calcScore
|
||||
end
|
||||
|
||||
def totalWrestlerPoints
|
||||
points = 0
|
||||
|
||||
@@ -14,15 +14,11 @@ class Teampointadjust < ActiveRecord::Base
|
||||
#Team score needs calculated
|
||||
if self.wrestler_id != nil
|
||||
#In case this affects pool order
|
||||
if self.wrestler.lastFinishedMatch
|
||||
self.wrestler.lastFinishedMatch.advance_wrestlers
|
||||
end
|
||||
AdvanceWrestler.new(self.wrestler).advance
|
||||
self.wrestler.school.calcScore
|
||||
elsif self.school_id != nil
|
||||
self.school.calcScore
|
||||
end
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :advance_wrestlers_and_calc_team_score
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
class Tournament < ActiveRecord::Base
|
||||
|
||||
include GeneratesLoserNames
|
||||
include GeneratesTournamentMatches
|
||||
belongs_to :user
|
||||
has_many :schools, dependent: :destroy
|
||||
has_many :weights, dependent: :destroy
|
||||
@@ -24,10 +22,6 @@ class Tournament < ActiveRecord::Base
|
||||
time
|
||||
end
|
||||
|
||||
def resetSchoolScores
|
||||
schools.update_all("score = 0.0")
|
||||
end
|
||||
|
||||
def tournament_types
|
||||
["Pool to bracket"]
|
||||
end
|
||||
@@ -50,19 +44,6 @@ class Tournament < ActiveRecord::Base
|
||||
def matchesByRound(round)
|
||||
matches.joins(:weight).where(round: round).order("weights.max")
|
||||
end
|
||||
|
||||
def assignBouts
|
||||
bout_counts = Hash.new(0)
|
||||
matches.each do |m|
|
||||
m.bout_number = m.round * 1000 + bout_counts[m.round]
|
||||
bout_counts[m.round] += 1
|
||||
m.save!
|
||||
end
|
||||
end
|
||||
|
||||
def assignFirstMatchesToMats
|
||||
assignMats(mats)
|
||||
end
|
||||
|
||||
def totalRounds
|
||||
self.matches.sort_by{|m| m.round}.last.round
|
||||
|
||||
@@ -14,7 +14,7 @@ class Weight < ActiveRecord::Base
|
||||
end
|
||||
|
||||
before_save do
|
||||
self.tournament.destroyAllMatches
|
||||
# self.tournament.destroyAllMatches
|
||||
end
|
||||
|
||||
def wrestlersForPool(pool)
|
||||
@@ -46,22 +46,6 @@ class Weight < ActiveRecord::Base
|
||||
wrestlersForPool(pool).sort_by{|w| [w.original_seed ? 0 : 1, w.original_seed || 0]}
|
||||
end
|
||||
|
||||
def setOriginalSeedsToWrestleLastPoolRound
|
||||
pool = 1
|
||||
until pool > self.pools
|
||||
wrestler1 = poolSeedOrder(pool).first
|
||||
wrestler2 = poolSeedOrder(pool).second
|
||||
match = wrestler1.poolMatches.sort_by{|m| m.round}.last
|
||||
if match.w1 != wrestler2.id or match.w2 != wrestler2.id
|
||||
if match.w1 == wrestler1.id
|
||||
swapWrestlers(match.w2,wrestler2.id)
|
||||
elsif match.w2 == wrestler1.id
|
||||
swapWrestlers(match.w1,wrestler2.id)
|
||||
end
|
||||
end
|
||||
pool += 1
|
||||
end
|
||||
end
|
||||
|
||||
def swapWrestlers(wrestler1_id,wrestler2_id)
|
||||
SwapWrestlers.new.swapWrestlers(wrestler1_id,wrestler2_id)
|
||||
@@ -180,38 +164,5 @@ class Weight < ActiveRecord::Base
|
||||
def poolOrder(pool)
|
||||
PoolOrder.new(wrestlersForPool(pool)).getPoolOrder
|
||||
end
|
||||
|
||||
def randomSeeding
|
||||
wrestlerWithSeeds = self.wrestlers.select{|w| w.original_seed != nil }.sort_by{|w| w.original_seed}
|
||||
if wrestlerWithSeeds.size > 0
|
||||
highestSeed = wrestlerWithSeeds.last.seed
|
||||
seed = highestSeed + 1
|
||||
else
|
||||
seed = 1
|
||||
end
|
||||
wrestlersWithoutSeed = self.wrestlers.select{|w| w.original_seed == nil }
|
||||
wrestlersWithoutSeed.shuffle.each do |w|
|
||||
w.seed = seed
|
||||
w.save
|
||||
seed += 1
|
||||
end
|
||||
end
|
||||
|
||||
def setSeeds
|
||||
resetAllSeeds
|
||||
wrestlerWithSeeds = self.wrestlers.select{|w| w.original_seed != nil }
|
||||
wrestlerWithSeeds.each do |w|
|
||||
w.seed = w.original_seed
|
||||
w.save
|
||||
end
|
||||
randomSeeding
|
||||
end
|
||||
|
||||
def resetAllSeeds
|
||||
self.wrestlers.each do |w|
|
||||
w.seed = nil
|
||||
w.save
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -22,28 +22,19 @@ class Wrestler < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def totalTeamPoints
|
||||
if self.extra
|
||||
return 0
|
||||
else
|
||||
teamPointsEarned - totalDeductedPoints
|
||||
end
|
||||
CalculateWrestlerTeamScore.new(self).totalScore
|
||||
end
|
||||
|
||||
def teamPointsEarned
|
||||
points = 0.0
|
||||
points = points + (poolWins.size * 2) + (championshipAdvancementWins.size * 2) + (consoAdvancementWins.size * 1) + (pinWins.size * 2) + (techWins.size * 1.5) + (majorWins.size * 1) + placementPoints
|
||||
CalculateWrestlerTeamScore.new(self).earnedPoints
|
||||
end
|
||||
|
||||
def placementPoints
|
||||
PoolBracketPlacementPoints.new(self).calcPoints
|
||||
CalculateWrestlerTeamScore.new(self).placementPoints
|
||||
end
|
||||
|
||||
def totalDeductedPoints
|
||||
points = 0
|
||||
self.deductedPoints.each do |d|
|
||||
points = points + d.points
|
||||
end
|
||||
points
|
||||
CalculateWrestlerTeamScore.new(self).deductedPoints
|
||||
end
|
||||
|
||||
def nextMatch
|
||||
@@ -88,15 +79,15 @@ class Wrestler < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def resultByBout(bout)
|
||||
@match = allMatches.select{|m| m.bout_number == bout and m.finished == 1}
|
||||
if @match.size == 0
|
||||
bout_match = allMatches.select{|m| m.bout_number == bout and m.finished == 1}
|
||||
if bout_match.size == 0
|
||||
return ""
|
||||
end
|
||||
if @match.first.winner_id == self.id
|
||||
return "W #{@match.first.bracketScore}"
|
||||
if bout_match.first.winner_id == self.id
|
||||
return "W #{bout_match.first.bracketScore}"
|
||||
end
|
||||
if @match.first.winner_id != self.id
|
||||
return "L #{@match.first.bracketScore}"
|
||||
if bout_match.first.winner_id != self.id
|
||||
return "L #{bout_match.first.bracketScore}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -113,26 +104,25 @@ class Wrestler < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def generatePoolNumber
|
||||
@pool = self.weight.returnPoolNumber(self)
|
||||
self.weight.returnPoolNumber(self)
|
||||
end
|
||||
|
||||
def boutByRound(round)
|
||||
@match = allMatches.select{|m| m.round == round}.first
|
||||
if @match.blank?
|
||||
round_match = allMatches.select{|m| m.round == round}.first
|
||||
if round_match.blank?
|
||||
return "BYE"
|
||||
else
|
||||
return @match.bout_number
|
||||
return round_match.bout_number
|
||||
end
|
||||
end
|
||||
|
||||
def allMatches
|
||||
@matches = matches.select{|m| m.w1 == self.id or m.w2 == self.id}
|
||||
return @matches
|
||||
return matches.select{|m| m.w1 == self.id or m.w2 == self.id}
|
||||
end
|
||||
|
||||
def poolMatches
|
||||
@poolMatches = allMatches.select{|m| m.bracket_position == "Pool"}
|
||||
@poolMatches.select{|m| m.poolNumber == self.generatePoolNumber}
|
||||
pool_matches = allMatches.select{|m| m.bracket_position == "Pool"}
|
||||
pool_matches.select{|m| m.poolNumber == self.generatePoolNumber}
|
||||
end
|
||||
|
||||
def championshipAdvancementWins
|
||||
@@ -213,7 +203,4 @@ class Wrestler < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def advanceInBracket(match)
|
||||
PoolAdvance.new(self,match).advanceWrestler
|
||||
end
|
||||
end
|
||||
|
||||
14
app/services/bracket_advancement/advance_wrestler.rb
Normal file
14
app/services/bracket_advancement/advance_wrestler.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class AdvanceWrestler
|
||||
def initialize( wrestler )
|
||||
@wrestler = wrestler
|
||||
@tournament = @wrestler.tournament
|
||||
end
|
||||
|
||||
def advance
|
||||
PoolAdvance.new(@wrestler,@wrestler.lastMatch).advanceWrestler if @tournament.tournament_type == "Pool to bracket"
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :advance
|
||||
end
|
||||
|
||||
end
|
||||
@@ -109,21 +109,26 @@ class PoolOrder
|
||||
end
|
||||
|
||||
def fastestPin
|
||||
timeArray = []
|
||||
wrestlersWithSamePoints.each do |w|
|
||||
timeArray << w.fastestPin
|
||||
wrestlersWithSamePointsWithPins = []
|
||||
wrestlersWithSamePoints.each do |wr|
|
||||
if wr.pinWins.size > 0
|
||||
wrestlersWithSamePointsWithPins << wr
|
||||
end
|
||||
end
|
||||
fastest = timeArray.max
|
||||
wrestlersWithFastestPin = wrestlersWithSamePoints.select{|w| w.fastestPin == fastest}
|
||||
addPointsToWrestlersAhead(wrestlersWithFastestPin.first)
|
||||
wrestlersWithFastestPin.each do |wr|
|
||||
addPoints(wr)
|
||||
end
|
||||
secondFastest = timeArray.sort[-2]
|
||||
wrestlersWithSecondFastestPin = wrestlersWithSamePoints.select{|w| w.fastestPin == secondFastest}
|
||||
addPointsToWrestlersAhead(wrestlersWithSecondFastestPin.first)
|
||||
wrestlersWithSecondFastestPin.each do |wr|
|
||||
addPoints(wr)
|
||||
if wrestlersWithSamePointsWithPins.size > 0
|
||||
fastest = wrestlersWithSamePointsWithPins.sort_by{|w| w.fastestPin.pinTime}.first.fastestPin
|
||||
secondFastest = wrestlersWithSamePointsWithPins.sort_by{|w| w.fastestPin.pinTime}.second.fastestPin
|
||||
wrestlersWithFastestPin = wrestlersWithSamePointsWithPins.select{|w| w.fastestPin.pinTime == fastest.pinTime}
|
||||
addPointsToWrestlersAhead(wrestlersWithFastestPin.first)
|
||||
wrestlersWithFastestPin.each do |wr|
|
||||
addPoints(wr)
|
||||
end
|
||||
|
||||
wrestlersWithSecondFastestPin = wrestlersWithSamePointsWithPins.select{|w| w.fastestPin.pinTime == secondFastest.pinTime}
|
||||
addPointsToWrestlersAhead(wrestlersWithSecondFastestPin.first)
|
||||
wrestlersWithSecondFastestPin.each do |wr|
|
||||
addPoints(wr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
class GenerateTournamentMatches
|
||||
def initialize( tournament )
|
||||
@tournament = tournament
|
||||
end
|
||||
|
||||
def generateWeight(weight)
|
||||
WipeTournamentMatches.new(@tournament).wipeWeightMatches(weight)
|
||||
@tournament.curently_generating_matches = 1
|
||||
@tournament.save
|
||||
unAssignBouts
|
||||
PoolToBracketMatchGeneration.new(@tournament).generatePoolToBracketMatchesWeight(weight) if @tournament.tournament_type == "Pool to bracket"
|
||||
postMatchCreationActions
|
||||
PoolToBracketGenerateLoserNames.new(@tournament).assignLoserNamesWeight(weight) if @tournament.tournament_type == "Pool to bracket"
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :generateWeight
|
||||
end
|
||||
|
||||
def generate
|
||||
standardStartingActions
|
||||
PoolToBracketMatchGeneration.new(@tournament).generatePoolToBracketMatches if @tournament.tournament_type == "Pool to bracket"
|
||||
postMatchCreationActions
|
||||
PoolToBracketMatchGeneration.new(@tournament).assignLoserNames if @tournament.tournament_type == "Pool to bracket"
|
||||
end
|
||||
if Rails.env.production?
|
||||
handle_asynchronously :generate
|
||||
end
|
||||
|
||||
def standardStartingActions
|
||||
@tournament.curently_generating_matches = 1
|
||||
@tournament.save
|
||||
WipeTournamentMatches.new(@tournament).setUpMatchGeneration
|
||||
TournamentSeeding.new(@tournament).setSeeds
|
||||
end
|
||||
|
||||
def postMatchCreationActions
|
||||
moveFinalsMatchesToLastRound
|
||||
assignBouts
|
||||
assignFirstMatchesToMats
|
||||
@tournament.curently_generating_matches = nil
|
||||
@tournament.save
|
||||
end
|
||||
|
||||
def assignBouts
|
||||
bout_counts = Hash.new(0)
|
||||
@tournament.matches.each do |m|
|
||||
m.bout_number = m.round * 1000 + bout_counts[m.round]
|
||||
bout_counts[m.round] += 1
|
||||
m.save!
|
||||
end
|
||||
end
|
||||
|
||||
def moveFinalsMatchesToLastRound
|
||||
finalsRound = @tournament.totalRounds
|
||||
finalsMatches = @tournament.matches.select{|m| m.bracket_position == "1/2" || m.bracket_position == "3/4" || m.bracket_position == "5/6" || m.bracket_position == "7/8"}
|
||||
finalsMatches. each do |m|
|
||||
m.round = finalsRound
|
||||
m.save
|
||||
end
|
||||
end
|
||||
|
||||
def assignFirstMatchesToMats
|
||||
matsToAssign = @tournament.mats
|
||||
if matsToAssign.count > 0
|
||||
until matsToAssign.sort_by{|m| m.id}.last.matches.count == 4
|
||||
matsToAssign.sort_by{|m| m.id}.each do |m|
|
||||
m.assignNextMatch
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def unAssignBouts
|
||||
bout_counts = Hash.new(0)
|
||||
@tournament.matches.each do |m|
|
||||
m.bout_number = nil
|
||||
m.save!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
@@ -1,4 +1,4 @@
|
||||
class PoolBracket
|
||||
class PoolBracketGeneration
|
||||
|
||||
def initialize(weight, highest_round)
|
||||
@weight = weight
|
||||
@@ -1,4 +1,4 @@
|
||||
class Pool
|
||||
class PoolGeneration
|
||||
def initialize(weight)
|
||||
@weight = weight
|
||||
@tournament = @weight.tournament
|
||||
@@ -6,17 +6,14 @@ class Pool
|
||||
end
|
||||
|
||||
def generatePools
|
||||
matches = []
|
||||
pools = @weight.pools
|
||||
while @pool <= pools
|
||||
matches += roundRobin()
|
||||
roundRobin
|
||||
@pool += 1
|
||||
end
|
||||
return matches
|
||||
end
|
||||
|
||||
def roundRobin
|
||||
matches = []
|
||||
wrestlers = @weight.wrestlersForPool(@pool)
|
||||
poolMatches = RoundRobinTournament.schedule(wrestlers).reverse
|
||||
poolMatches.each_with_index do |b, index|
|
||||
@@ -24,16 +21,14 @@ class Pool
|
||||
bouts = b.map
|
||||
bouts.each do |bout|
|
||||
if bout[0] != nil and bout[1] != nil
|
||||
match = @tournament.matches.create(
|
||||
@tournament.matches.create(
|
||||
w1: bout[0].id,
|
||||
w2: bout[1].id,
|
||||
weight_id: @weight.id,
|
||||
bracket_position: "Pool",
|
||||
round: round)
|
||||
matches << match
|
||||
end
|
||||
end
|
||||
end
|
||||
matches
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,24 @@
|
||||
module GeneratesLoserNames
|
||||
def assignLoserNames
|
||||
class PoolToBracketGenerateLoserNames
|
||||
def initialize( tournament )
|
||||
@tournament = tournament
|
||||
end
|
||||
|
||||
def assignLoserNamesWeight(weight)
|
||||
matches_by_weight = @tournament.matches.where(weight_id: weight.id)
|
||||
if weight.pool_bracket_type == "twoPoolsToSemi"
|
||||
twoPoolsToSemiLoser(matches_by_weight)
|
||||
elsif weight.pool_bracket_type == "fourPoolsToQuarter"
|
||||
fourPoolsToQuarterLoser(matches_by_weight)
|
||||
elsif weight.pool_bracket_type == "fourPoolsToSemi"
|
||||
fourPoolsToSemiLoser(matches_by_weight)
|
||||
end
|
||||
saveMatches(matches_by_weight)
|
||||
end
|
||||
|
||||
def assignLoserNames
|
||||
matches_by_weight = nil
|
||||
weights.each do |w|
|
||||
matches_by_weight = matches.where(weight_id: w.id)
|
||||
@tournament.weights.each do |w|
|
||||
matches_by_weight = @tournament.matches.where(weight_id: w.id)
|
||||
if w.pool_bracket_type == "twoPoolsToSemi"
|
||||
twoPoolsToSemiLoser(matches_by_weight)
|
||||
elsif w.pool_bracket_type == "fourPoolsToQuarter"
|
||||
@@ -12,7 +28,7 @@ module GeneratesLoserNames
|
||||
end
|
||||
saveMatches(matches_by_weight)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def twoPoolsToSemiLoser(matches_by_weight)
|
||||
match1 = matches_by_weight.select{|m| m.loser1_name == "Winner Pool 1"}.first
|
||||
@@ -59,5 +75,6 @@ module GeneratesLoserNames
|
||||
matches.each do |m|
|
||||
m.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
class PoolToBracketMatchGeneration
|
||||
def initialize( tournament )
|
||||
@tournament = tournament
|
||||
end
|
||||
|
||||
def generatePoolToBracketMatchesWeight(weight)
|
||||
PoolGeneration.new(weight).generatePools()
|
||||
last_match = @tournament.matches.where(weight: weight).order(round: :desc).limit(1).first
|
||||
highest_round = last_match.round
|
||||
PoolBracketGeneration.new(weight, highest_round).generateBracketMatches()
|
||||
setOriginalSeedsToWrestleLastPoolRound(weight)
|
||||
end
|
||||
|
||||
def generatePoolToBracketMatches
|
||||
@tournament.weights.order(:max).each do |weight|
|
||||
PoolGeneration.new(weight).generatePools()
|
||||
last_match = @tournament.matches.where(weight: weight).order(round: :desc).limit(1).first
|
||||
highest_round = last_match.round
|
||||
PoolBracketGeneration.new(weight, highest_round).generateBracketMatches()
|
||||
end
|
||||
movePoolSeedsToFinalPoolRound
|
||||
end
|
||||
|
||||
def movePoolSeedsToFinalPoolRound
|
||||
@tournament.weights.each do |w|
|
||||
setOriginalSeedsToWrestleLastPoolRound(w)
|
||||
end
|
||||
end
|
||||
|
||||
def setOriginalSeedsToWrestleLastPoolRound(weight)
|
||||
pool = 1
|
||||
until pool > weight.pools
|
||||
wrestler1 = weight.poolSeedOrder(pool).first
|
||||
wrestler2 = weight.poolSeedOrder(pool).second
|
||||
match = wrestler1.poolMatches.sort_by{|m| m.round}.last
|
||||
if match.w1 != wrestler2.id or match.w2 != wrestler2.id
|
||||
if match.w1 == wrestler1.id
|
||||
SwapWrestlers.new.swapWrestlers(match.w2,wrestler2.id)
|
||||
elsif match.w2 == wrestler1.id
|
||||
SwapWrestlers.new.swapWrestlers(match.w1,wrestler2.id)
|
||||
end
|
||||
end
|
||||
pool += 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def assignLoserNames
|
||||
PoolToBracketGenerateLoserNames.new(@tournament).assignLoserNames
|
||||
end
|
||||
|
||||
end
|
||||
44
app/services/tournament_services/tournament_seeding.rb
Normal file
44
app/services/tournament_services/tournament_seeding.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
class TournamentSeeding
|
||||
def initialize( tournament )
|
||||
@tournament = tournament
|
||||
end
|
||||
|
||||
def setSeeds
|
||||
@tournament.weights.each do |w|
|
||||
resetAllSeeds(w)
|
||||
setOriginalSeeds(w)
|
||||
randomSeeding(w)
|
||||
end
|
||||
end
|
||||
|
||||
def randomSeeding(weight)
|
||||
wrestlerWithSeeds = weight.wrestlers.select{|w| w.original_seed != nil }.sort_by{|w| w.original_seed}
|
||||
if wrestlerWithSeeds.size > 0
|
||||
highestSeed = wrestlerWithSeeds.last.seed
|
||||
seed = highestSeed + 1
|
||||
else
|
||||
seed = 1
|
||||
end
|
||||
wrestlersWithoutSeed = weight.wrestlers.select{|w| w.original_seed == nil }
|
||||
wrestlersWithoutSeed.shuffle.each do |w|
|
||||
w.seed = seed
|
||||
w.save
|
||||
seed += 1
|
||||
end
|
||||
end
|
||||
|
||||
def setOriginalSeeds(weight)
|
||||
wrestlerWithSeeds = weight.wrestlers.select{|w| w.original_seed != nil }
|
||||
wrestlerWithSeeds.each do |w|
|
||||
w.seed = w.original_seed
|
||||
w.save
|
||||
end
|
||||
end
|
||||
|
||||
def resetAllSeeds(weight)
|
||||
weight.wrestlers.each do |w|
|
||||
w.seed = nil
|
||||
w.save
|
||||
end
|
||||
end
|
||||
end
|
||||
23
app/services/tournament_services/wipe_tournament_matches.rb
Normal file
23
app/services/tournament_services/wipe_tournament_matches.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
class WipeTournamentMatches
|
||||
|
||||
def initialize( tournament )
|
||||
@tournament = tournament
|
||||
end
|
||||
|
||||
def setUpMatchGeneration
|
||||
wipeMatches
|
||||
resetSchoolScores
|
||||
end
|
||||
|
||||
def wipeWeightMatches(weight)
|
||||
weight.matches.destroy_all
|
||||
end
|
||||
|
||||
def wipeMatches
|
||||
@tournament.matches.destroy_all
|
||||
end
|
||||
|
||||
def resetSchoolScores
|
||||
@tournament.schools.update_all("score = 0.0")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
class CalculateWrestlerTeamScore
|
||||
def initialize( wrestler )
|
||||
@wrestler = wrestler
|
||||
@tournament = @wrestler.tournament
|
||||
end
|
||||
|
||||
def totalScore
|
||||
if @wrestler.extra
|
||||
return 0
|
||||
else
|
||||
earnedPoints - deductedPoints
|
||||
end
|
||||
end
|
||||
|
||||
def earnedPoints
|
||||
return poolPoints + bracketPoints + placementPoints + bonusWinPoints
|
||||
end
|
||||
|
||||
def deductedPoints
|
||||
points = 0
|
||||
@wrestler.deductedPoints.each do |d|
|
||||
points = points + d.points
|
||||
end
|
||||
points
|
||||
end
|
||||
|
||||
def placementPoints
|
||||
PoolBracketPlacementPoints.new(@wrestler).calcPoints if @tournament.tournament_type == "Pool to bracket"
|
||||
end
|
||||
|
||||
def bracketPoints
|
||||
(@wrestler.championshipAdvancementWins.size * 2) + (@wrestler.consoAdvancementWins.size * 1)
|
||||
end
|
||||
|
||||
def poolPoints
|
||||
if @tournament.tournament_type == "Pool to bracket"
|
||||
(@wrestler.poolWins.size * 2)
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def bonusWinPoints
|
||||
(@wrestler.pinWins.size * 2) + (@wrestler.techWins.size * 1.5) + (@wrestler.majorWins.size * 1)
|
||||
end
|
||||
|
||||
end
|
||||
3
app/views/api/currentUserTournaments.jbuilder
Normal file
3
app/views/api/currentUserTournaments.jbuilder
Normal file
@@ -0,0 +1,3 @@
|
||||
json.array!(@tournaments) do |tournament|
|
||||
json.extract! tournament, :id, :name, :address, :director, :director_email, :date
|
||||
end
|
||||
2
app/views/api/index.html.erb
Normal file
2
app/views/api/index.html.erb
Normal file
@@ -0,0 +1,2 @@
|
||||
<%= stylesheet_link_tag "lineman/app" %>
|
||||
<%= javascript_include_tag "lineman/app" %>
|
||||
55
app/views/api/tournament.jbuilder
Normal file
55
app/views/api/tournament.jbuilder
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
json.cache! ["api_tournament", @tournament] do
|
||||
json.content(@tournament)
|
||||
json.(@tournament, :id, :name, :address, :director, :director_email, :tournament_type, :created_at, :updated_at, :user_id)
|
||||
|
||||
json.schools @tournament.schools do |school|
|
||||
json.id school.id
|
||||
json.name school.name
|
||||
json.score school.score
|
||||
end
|
||||
|
||||
json.weights @tournament.weights do |weight|
|
||||
json.id weight.id
|
||||
json.max weight.max
|
||||
json.bracket_size weight.bracket_size
|
||||
json.wrestlers weight.wrestlers do |wrestler|
|
||||
json.id wrestler.id
|
||||
json.name wrestler.name
|
||||
json.school wrestler.school.name
|
||||
json.original_seed wrestler.original_seed
|
||||
json.criteria wrestler.criteria
|
||||
json.extra wrestler.extra
|
||||
json.seasonWinPercentage wrestler.seasonWinPercentage
|
||||
json.season_win wrestler.season_win
|
||||
json.season_loss wrestler.season_loss
|
||||
end
|
||||
end
|
||||
|
||||
json.mats @tournament.mats do |mat|
|
||||
json.name mat.name
|
||||
json.unfinishedMatches mat.unfinishedMatches do |match|
|
||||
json.bout_number match.bout_number
|
||||
json.w1_name match.w1_name
|
||||
json.w2_name match.w2_name
|
||||
end
|
||||
end
|
||||
|
||||
json.unassignedMatches @tournament.matches.select{|m| m.mat_id == nil}.sort_by{|m| m.bout_number}[0...9] do |match|
|
||||
json.bout_number match.bout_number
|
||||
json.w1_name match.w1_name
|
||||
json.w2_name match.w2_name
|
||||
json.weightClass match.weight.max
|
||||
json.round match.round
|
||||
end
|
||||
|
||||
json.matches @tournament.matches do |match|
|
||||
json.bout_number match.bout_number
|
||||
json.w1_name match.w1_name
|
||||
json.w2_name match.w2_name
|
||||
json.weightClass match.weight.max
|
||||
json.round match.round
|
||||
json.w1 match.w1
|
||||
json.w2 match.w2
|
||||
end
|
||||
end
|
||||
3
app/views/api/tournaments.jbuilder
Normal file
3
app/views/api/tournaments.jbuilder
Normal file
@@ -0,0 +1,3 @@
|
||||
json.array!(@tournaments) do |tournament|
|
||||
json.extract! tournament, :id, :name, :address, :director, :director_email, :date
|
||||
end
|
||||
@@ -9,7 +9,7 @@
|
||||
<script src="https://cdn.datatables.net/1.10.6/js/jquery.dataTables.min.js"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.map"></script>
|
||||
|
||||
|
||||
<!--Mobile and tablet detection-->
|
||||
<script type='text/javascript' src="//wurfl.io/wurfl.js"></script>
|
||||
|
||||
3
app/views/weights/re_gen.html.erb
Normal file
3
app/views/weights/re_gen.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<%= link_to "Back to #{@weight.tournament.name}", "/tournaments/#{@weight.tournament.id}", :class=>"btn btn-default" %>
|
||||
<br><br>
|
||||
<%= @weight.max %> lbs Matches are being generated. This can take anywhere from 1-5 minutes to finish. It is recommended to delete all delegated school permissions to prevent lineup changes after the tournament has started.
|
||||
@@ -4,6 +4,9 @@
|
||||
<%= link_to "Back to #{@tournament.name}", "/tournaments/#{@tournament.id}", :class=>"btn btn-default" %>
|
||||
<% if can? :manage, @tournament %>
|
||||
| <%= link_to "Edit #{@weight.max} Weight Class", edit_weight_path(@weight), :class=>"btn btn-primary" %>
|
||||
| <%= form_for(@weight, url: regen_weight_path(@weight.id), :method => "post") do |f| %>
|
||||
<%= submit_tag "Regenerate Weight Class Matches", :class=>"btn"%>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<br>
|
||||
|
||||
@@ -17,14 +17,12 @@
|
||||
<%= f.text_field :name %>
|
||||
</div>
|
||||
<% if can? :manage, @wrestler.tournament %>
|
||||
<% if @tournament %>
|
||||
<%= f.hidden_field :school_id, :value => @school.id %>
|
||||
<% else %>
|
||||
<div class="field">
|
||||
<%= f.label 'School' %><br>
|
||||
<%= f.collection_select :school_id, @school.tournament.schools, :id, :name %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= f.hidden_field :school_id, :value => @school.id %>
|
||||
<% end %>
|
||||
<div class="field">
|
||||
<%= f.label 'Weight Class' %><br>
|
||||
|
||||
@@ -29,7 +29,15 @@ module Wrestling
|
||||
|
||||
config.active_job.queue_adapter = :delayed_job
|
||||
|
||||
config.rails_lineman.lineman_project_location = "frontend"
|
||||
|
||||
config.to_prepare do
|
||||
DeviseController.respond_to :html, :json
|
||||
end
|
||||
|
||||
config.autoload_paths += %W(#{config.root}/app/services/tournament_services)
|
||||
config.autoload_paths += %W(#{config.root}/app/services/wrestler_services)
|
||||
config.autoload_paths += %W(#{config.root}/app/services/bracket_advancement)
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -110,4 +110,7 @@ Wrestling::Application.configure do
|
||||
config.action_mailer.perform_deliveries = true
|
||||
#Devise needs origin of email
|
||||
Rails.application.routes.default_url_options[:host] = 'https://wrestlingdev.com'
|
||||
|
||||
#For lineman creating assets
|
||||
config.serve_static_files = true
|
||||
end
|
||||
|
||||
@@ -51,6 +51,15 @@ Wrestling::Application.routes.draw do
|
||||
get 'tournaments/:id/error' => 'tournaments#error'
|
||||
post "/tournaments/:id/swap" => "tournaments#swap", :as => :swap_wrestlers
|
||||
|
||||
post 'weights/:id/re_gen' => 'weights#re_gen', :as => :regen_weight
|
||||
|
||||
#API
|
||||
get "/api/tournaments" => "api#tournaments"
|
||||
get "/api/tournaments/user" => "api#currentUserTournaments"
|
||||
get "/api/tournaments/:tournament" => "api#tournament"
|
||||
get "/api/index" => "api#index"
|
||||
post "/api/tournaments/new" => "newTournament"
|
||||
|
||||
# Example of regular route:
|
||||
# get 'products/:id' => 'catalog#view'
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
cd ..
|
||||
bash rails-prod.sh wrestlingdev
|
||||
docker build -t wrestlingdev -f rails-prod-Dockerfile .
|
||||
cd deploy
|
||||
docker-compose -f docker-compose-test.yml kill
|
||||
docker-compose -f docker-compose-test.yml up -d
|
||||
echo Make sure your local mysql database has a wrestlingtourney db
|
||||
|
||||
@@ -23,3 +23,10 @@ worker:
|
||||
restart: always
|
||||
env_file:
|
||||
- ./prod.env
|
||||
command: bundle exec rake jobs:work RAILS_ENV=production
|
||||
|
||||
memcached:
|
||||
extends:
|
||||
file: docker-compose-common.yml
|
||||
service: memcached
|
||||
restart: always
|
||||
|
||||
@@ -10,10 +10,14 @@ app:
|
||||
- WRESTLINGDEV_DB_PORT=3306
|
||||
- WRESTLINGDEV_DEVISE_SECRET_KEY=2f29d49db6704377ba263f7cb9db085b386bcb301c0cd501126a674686ab1a109754071165b08cd72af03cec4642a4dd04361c994462254dd5d85e9594e8b9aa
|
||||
- WRESTLINGDEV_SECRET_KEY_BASE=077cdbef5c2ccf22543fb17a67339f234306b7fa2e1e4463d851c444c10a5611829a2290b253da78339427f131571fac9a42c83d960b2d25ecc10a4a0a7ce1a2
|
||||
|
||||
- MEMCACHIER_SERVERS=memcached:11211
|
||||
- MEMCACHIER_USERNAME=
|
||||
- MEMCACHIER_PASSWORD=
|
||||
links:
|
||||
- db
|
||||
- memcached
|
||||
restart: always
|
||||
|
||||
db:
|
||||
extends:
|
||||
file: docker-compose-common.yml
|
||||
@@ -21,6 +25,7 @@ db:
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=password
|
||||
restart: always
|
||||
|
||||
worker:
|
||||
extends:
|
||||
file: docker-compose-common.yml
|
||||
@@ -33,7 +38,18 @@ worker:
|
||||
- WRESTLINGDEV_DB_PORT=3306
|
||||
- WRESTLINGDEV_DEVISE_SECRET_KEY=2f29d49db6704377ba263f7cb9db085b386bcb301c0cd501126a674686ab1a109754071165b08cd72af03cec4642a4dd04361c994462254dd5d85e9594e8b9aa
|
||||
- WRESTLINGDEV_SECRET_KEY_BASE=077cdbef5c2ccf22543fb17a67339f234306b7fa2e1e4463d851c444c10a5611829a2290b253da78339427f131571fac9a42c83d960b2d25ecc10a4a0a7ce1a2
|
||||
|
||||
- MEMCACHIER_SERVERS=memcached:11211
|
||||
- MEMCACHIER_USERNAME=
|
||||
- MEMCACHIER_PASSWORD=
|
||||
links:
|
||||
- db
|
||||
- memcached
|
||||
restart: always
|
||||
command: bundle exec rake jobs:work RAILS_ENV=production
|
||||
|
||||
memcached:
|
||||
extends:
|
||||
file: docker-compose-common.yml
|
||||
service: memcached
|
||||
restart: always
|
||||
|
||||
|
||||
9
frontend/.gitignore
vendored
Normal file
9
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
.DS_Store
|
||||
|
||||
#ignore node_modules, as the node project is not "deployed" per se: http://www.mikealrogers.com/posts/nodemodules-in-git.html
|
||||
/node_modules
|
||||
|
||||
/dist
|
||||
/generated
|
||||
|
||||
.sass-cache
|
||||
9
frontend/.npmignore
Normal file
9
frontend/.npmignore
Normal file
@@ -0,0 +1,9 @@
|
||||
.DS_Store
|
||||
|
||||
#ignore node_modules, as the node project is not "deployed" per se: http://www.mikealrogers.com/posts/nodemodules-in-git.html
|
||||
/node_modules
|
||||
|
||||
/dist
|
||||
/generated
|
||||
|
||||
.sass-cache
|
||||
4
frontend/.travis.yml
Normal file
4
frontend/.travis.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.10
|
||||
script: "lineman spec-ci"
|
||||
4
frontend/Gruntfile.js
Normal file
4
frontend/Gruntfile.js
Normal file
@@ -0,0 +1,4 @@
|
||||
/*global module:false*/
|
||||
module.exports = function(grunt) {
|
||||
require('./config/lineman').config.grunt.run(grunt);
|
||||
};
|
||||
1
frontend/Procfile
Normal file
1
frontend/Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: npm run production
|
||||
1
frontend/README.md
Normal file
1
frontend/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# My Lineman Application
|
||||
4
frontend/app/css/style.css
Normal file
4
frontend/app/css/style.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.hello {
|
||||
background-color: #efefef;
|
||||
border: 1px solid #dedede;
|
||||
}
|
||||
0
frontend/app/img/.keep
Normal file
0
frontend/app/img/.keep
Normal file
0
frontend/app/js/.keep
Normal file
0
frontend/app/js/.keep
Normal file
11
frontend/app/js/app.js
Normal file
11
frontend/app/js/app.js
Normal file
@@ -0,0 +1,11 @@
|
||||
var app = angular.module("wrestlingdev", ["ngRoute","Devise"]).run(function($rootScope) {
|
||||
// adds some basic utilities to the $rootScope for debugging purposes
|
||||
$rootScope.log = function(thing) {
|
||||
console.log(thing);
|
||||
};
|
||||
|
||||
$rootScope.alert = function(thing) {
|
||||
alert(thing);
|
||||
};
|
||||
});
|
||||
|
||||
51
frontend/app/js/controllers/login-controller.js
Normal file
51
frontend/app/js/controllers/login-controller.js
Normal file
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
app.controller("loginController", function($scope, $routeParams, Auth, $rootScope) {
|
||||
$scope.credentials = {
|
||||
email: '',
|
||||
password: ''
|
||||
};
|
||||
|
||||
var config = {
|
||||
headers: {
|
||||
'X-HTTP-Method-Override': 'POST'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.login = function(){
|
||||
Auth.login($scope.credentials, config).then(function(user) {
|
||||
console.log(user); // => {id: 1, ect: '...'}
|
||||
$rootScope.user = user;
|
||||
$rootScope.alertClass = "alert alert-success";
|
||||
$rootScope.alertMessage = "Logged in successfully";
|
||||
}, function(error) {
|
||||
console.log(error);
|
||||
$rootScope.alertClass = "alert alert-danger";
|
||||
$rootScope.alertMessage = "Username and/or password is incorrect";
|
||||
});
|
||||
};
|
||||
|
||||
$scope.logout = function(){
|
||||
Auth.logout(config).then(function(oldUser) {
|
||||
// alert(oldUser.name + "you're signed out now.");
|
||||
$rootScope.user = null;
|
||||
$rootScope.alertClass = "alert alert-success";
|
||||
$rootScope.alertMessage = "Logged out successfully";
|
||||
}, function(error) {
|
||||
// An error occurred logging out.
|
||||
$rootScope.alertClass = "alert alert-danger";
|
||||
$rootScope.alertMessage = "There was an error logging out";
|
||||
});
|
||||
};
|
||||
|
||||
Auth.currentUser().then(function(user) {
|
||||
// User was logged in, or Devise returned
|
||||
// previously authenticated session.
|
||||
$rootScope.user = user;
|
||||
}, function(error) {
|
||||
// unauthenticated error
|
||||
$rootScope.user = null;
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
11
frontend/app/js/controllers/my-tournaments.js
Normal file
11
frontend/app/js/controllers/my-tournaments.js
Normal file
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
app.controller("myTournamentsController", function($scope, tournamentsService, $rootScope) {
|
||||
|
||||
tournamentsService.getMyTournaments().then(function(data) {
|
||||
//this will execute when the
|
||||
//AJAX call completes.
|
||||
$scope.allTournaments = data;
|
||||
});
|
||||
|
||||
});
|
||||
86
frontend/app/js/controllers/tournament-controller.js
Normal file
86
frontend/app/js/controllers/tournament-controller.js
Normal file
@@ -0,0 +1,86 @@
|
||||
'use strict';
|
||||
app.controller("tournamentController", function($scope, tournamentsService, $routeParams, Wrestler, Auth, $rootScope) {
|
||||
$scope.message = "Test message in scope.";
|
||||
|
||||
|
||||
// $scope.tournamentData = "test";
|
||||
tournamentsService.tournamentDetails($routeParams.id).then(function(data) {
|
||||
//this will execute when the
|
||||
//AJAX call completes.
|
||||
$scope.tournament = data;
|
||||
});
|
||||
|
||||
$scope.refreshTournamentData = function(){
|
||||
tournamentsService.tournamentDetails($routeParams.id).then(function(data) {
|
||||
//this will execute when the
|
||||
//AJAX call completes.
|
||||
$scope.tournament = data;
|
||||
});
|
||||
};
|
||||
|
||||
// refresh tournament data every 10 seconds
|
||||
// setInterval(function(){
|
||||
// tournamentsService.tournamentDetails($routeParams.id).then(function(data) {
|
||||
// //this will execute when the
|
||||
// //AJAX call completes.
|
||||
// $scope.tournament = data;
|
||||
// });
|
||||
// }, 10000);
|
||||
|
||||
$scope.wrestler = Wrestler;
|
||||
|
||||
$scope.showSchools = false;
|
||||
|
||||
$scope.toggleSchools = function(){
|
||||
$scope.showSchools = !$scope.showSchools;
|
||||
};
|
||||
|
||||
$scope.showWeightSeeds = false;
|
||||
|
||||
$scope.toggleWeightSeeds = function(){
|
||||
$scope.showWeightSeeds = !$scope.showWeightSeeds;
|
||||
};
|
||||
|
||||
|
||||
$scope.showBoutBoard = false;
|
||||
|
||||
$scope.toggleBoutBoard = function(){
|
||||
$scope.showBoutBoard = !$scope.showBoutBoard;
|
||||
};
|
||||
|
||||
|
||||
$scope.isTournamentOwner = function(tournamentId,userId){
|
||||
if(userId == tournamentId){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$scope.newSchool = null;
|
||||
|
||||
$scope.saveNewSchool = function(){
|
||||
$scope.newSchool.tournament_id = $scope.tournament.id;
|
||||
tournamentsService.saveNewSchool($scope.newSchool).then(function(data) {
|
||||
$scope.tournament.schools.push(data);
|
||||
});
|
||||
$scope.newSchool = null;
|
||||
$('#NewSchool').modal('hide');
|
||||
};
|
||||
|
||||
$scope.deleteSchool = function(school){
|
||||
if (confirm('Are you sure you want to delete ' + school.name + '?')) {
|
||||
tournamentsService.deleteSchool(school).then(function(data) {
|
||||
$scope.tournament.schools.splice( $scope.tournament.schools.indexOf(school), 1 );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.updateSchool = function(school){
|
||||
tournamentsService.updateSchool(school);
|
||||
$('#EditSchool' + school.id).modal('hide');
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
19
frontend/app/js/controllers/tournaments-controller.js
Normal file
19
frontend/app/js/controllers/tournaments-controller.js
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
app.controller("tournamentsController", function($scope, tournamentsService) {
|
||||
|
||||
tournamentsService.getAllTournaments().then(function(data) {
|
||||
//this will execute when the
|
||||
//AJAX call completes.
|
||||
$scope.allTournaments = data;
|
||||
});
|
||||
|
||||
$scope.searchTournaments = function (){
|
||||
tournamentsService.searchTournaments($scope.searchTerms).then(function(data) {
|
||||
//this will execute when the
|
||||
//AJAX call completes.
|
||||
$scope.allTournaments = data;
|
||||
});
|
||||
};
|
||||
|
||||
});
|
||||
24
frontend/app/js/directives/loading.js
Normal file
24
frontend/app/js/directives/loading.js
Normal file
@@ -0,0 +1,24 @@
|
||||
(function(){
|
||||
app.directive('usSpinner', ['$http', '$rootScope' ,function ($http, $rootScope){
|
||||
return {
|
||||
link: function (scope, elm, attrs)
|
||||
{
|
||||
$rootScope.spinnerActive = false;
|
||||
scope.isLoading = function () {
|
||||
return $http.pendingRequests.length > 0;
|
||||
};
|
||||
|
||||
scope.$watch(scope.isLoading, function (loading)
|
||||
{
|
||||
$rootScope.spinnerActive = loading;
|
||||
if(loading){
|
||||
elm.removeClass('ng-hide');
|
||||
}else{
|
||||
elm.addClass('ng-hide');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
}]);
|
||||
}).call(this);
|
||||
18
frontend/app/js/models/wrestler.js
Normal file
18
frontend/app/js/models/wrestler.js
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
app.factory('Wrestler', function Wrestler(){
|
||||
var vm = this;
|
||||
|
||||
|
||||
vm.matches = function(wrestler,matches){
|
||||
|
||||
console.log(matches);
|
||||
return _.filter(matches, function(match){
|
||||
return match.w1 == wrestler.id || match.w2 == wrestler.id;
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
return vm;
|
||||
});
|
||||
49
frontend/app/js/routes.js
Normal file
49
frontend/app/js/routes.js
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
|
||||
// $routeProvider.when('/list-of-books', {
|
||||
// templateUrl: 'angular/books.html',
|
||||
// controller: 'BooksController'
|
||||
// // uncomment if you want to see an example of a route that resolves a request prior to rendering
|
||||
// // resolve: {
|
||||
// // books : function(BookService) {
|
||||
// // return BookService.get();
|
||||
// // }
|
||||
// // }
|
||||
// });
|
||||
|
||||
|
||||
|
||||
app.config(['$routeProvider', '$locationProvider', function($routeProvider,$locationProvider) {
|
||||
|
||||
$routeProvider.when('/', {
|
||||
templateUrl: 'home.html',
|
||||
});
|
||||
|
||||
$routeProvider.when('/tournaments', {
|
||||
templateUrl: 'tournaments-search.html',
|
||||
controller: 'tournamentsController'
|
||||
});
|
||||
|
||||
$routeProvider.when('/tournaments/user', {
|
||||
templateUrl: 'my-tournaments.html',
|
||||
controller: 'myTournamentsController'
|
||||
});
|
||||
|
||||
$routeProvider.when('/tournaments/:id', {
|
||||
templateUrl: 'tournaments-show.html',
|
||||
controller: 'tournamentController'
|
||||
});
|
||||
|
||||
$routeProvider.when('/about', {
|
||||
templateUrl: 'about.html',
|
||||
});
|
||||
|
||||
$routeProvider.when('/tutorials', {
|
||||
templateUrl: 'tutorials.html',
|
||||
});
|
||||
|
||||
$routeProvider.otherwise({redirectTo: '/'});
|
||||
|
||||
//this give me normal routes instead of /#/
|
||||
// $locationProvider.html5Mode(true);
|
||||
}]);
|
||||
101
frontend/app/js/services/tournaments-service.js
Normal file
101
frontend/app/js/services/tournaments-service.js
Normal file
@@ -0,0 +1,101 @@
|
||||
|
||||
app.factory('tournamentsService', tournamentsService);
|
||||
|
||||
function tournamentsService($http,$rootScope){
|
||||
var service = {};
|
||||
|
||||
service.getMyTournaments = function(user){
|
||||
return $http({
|
||||
url: '/api/tournaments/user/',
|
||||
method: "GET"
|
||||
}).then(successResponse, errorCallback);
|
||||
};
|
||||
|
||||
service.getAllTournaments = function(){
|
||||
return $http({
|
||||
url: '/api/tournaments/',
|
||||
method: "GET"
|
||||
}).then(successResponse, errorCallback);
|
||||
};
|
||||
|
||||
service.searchTournaments = function(search){
|
||||
return $http({
|
||||
method: 'GET',
|
||||
url: '/api/tournaments/',
|
||||
params: {
|
||||
search: search
|
||||
}
|
||||
}).then(successResponse, errorCallback);
|
||||
};
|
||||
|
||||
service.tournamentDetails = function(tournamentId){
|
||||
return $http({
|
||||
url: '/api/tournaments/' + tournamentId,
|
||||
method: "GET"
|
||||
}).then(successResponse, errorCallback);
|
||||
};
|
||||
|
||||
service.saveNewSchool = function(newSchool){
|
||||
return $http({
|
||||
url: '/schools.json',
|
||||
method: "POST",
|
||||
|
||||
data: {
|
||||
school: {
|
||||
'name': newSchool.name,
|
||||
'tournament_id': newSchool.tournament_id
|
||||
}
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}).then(successResponse, errorCallback);
|
||||
};
|
||||
|
||||
service.deleteSchool = function(school){
|
||||
return $http({
|
||||
url: '/schools/' + school.id + '/',
|
||||
method: "DELETE"
|
||||
}).then(successResponse, errorCallback);
|
||||
};
|
||||
|
||||
service.updateSchool = function(schoolToEdit){
|
||||
return $http({
|
||||
url: '/schools/' + schoolToEdit.id,
|
||||
method: "PATCH",
|
||||
data: {
|
||||
school: {
|
||||
'name': schoolToEdit.name,
|
||||
'tournament_id': schoolToEdit.tournament_id
|
||||
}
|
||||
},
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}).then(successResponse, errorCallback);
|
||||
};
|
||||
|
||||
function successResponse(response){
|
||||
// console.log("success log below");
|
||||
// console.log(response);
|
||||
if(response.config.method == "POST" || response.config.method == "DELETE" || response.config.method == "PATCH"){
|
||||
$rootScope.alertClass = "alert alert-success";
|
||||
$rootScope.alertMessage = response.statusText;
|
||||
}
|
||||
return response.data;
|
||||
}
|
||||
|
||||
function errorCallback(err){
|
||||
// console.log("error log below");
|
||||
// console.log(err);
|
||||
if(err.status > 0){
|
||||
$rootScope.alertClass = "alert alert-danger";
|
||||
$rootScope.alertMessage = err.statusText;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
98
frontend/app/pages/index.us
Normal file
98
frontend/app/pages/index.us
Normal file
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html ng-app="wrestlingdev">
|
||||
<head>
|
||||
<base href="/#/">
|
||||
<title>WrestlingDev</title>
|
||||
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<!-- Optional theme -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
|
||||
</head>
|
||||
<body style="padding-top: 70px;">
|
||||
<div class="container">
|
||||
<div class="navbar-roof"></div>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/#/">WrestlingDev</a>
|
||||
</div>
|
||||
<div id="navbar" class="collapse navbar-collapse">
|
||||
<ul class="nav navbar-nav navbar-right navbar-custom-link">
|
||||
<li><a href="/#/tournaments">Browse Tournaments</a></li>
|
||||
<li><a href="/#/about">About</a></li>
|
||||
<li><a href="/#/tutorials">Tutorials</a></li>
|
||||
<li class="dropdown" ng-controller="loginController">
|
||||
<a ng-if="user == null" class="dropdown-toggle" data-toggle="dropdown">Login<span class="caret"></a>
|
||||
<div ng-if="user == null" class="dropdown-menu" style="padding:17px;">
|
||||
<form class="form" id="formLogin">
|
||||
<div class="form-group">
|
||||
<input name="username" class="form-control" id="username" type="text" placeholder="Email" ng-model="credentials.email">
|
||||
<input name="password" class="form-control" id="password" type="password" placeholder="Password" ng-model="credentials.password"><br>
|
||||
<button type="button" id="btnLogin" class="btn btn-primary" ng-click="login()">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<a ng-if="user != null" class="dropdown-toggle" data-toggle="dropdown">{{user.email}}<span class="caret"></a>
|
||||
<ul ng-if="user != null" class="dropdown-menu" style="list-style-type: none;">
|
||||
<li><a href="/#/tournaments/user">My Tournaments and schools</a></li>
|
||||
<li><a ng-click="logout()">Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="page-content">
|
||||
<div class="row no-margin">
|
||||
<div ng-if="alertMessage != null" ng-class="alertClass">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{{alertMessage}}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<!--left sidebar-->
|
||||
</div>
|
||||
<div class="col-md-8" style="padding-left: 2%;">
|
||||
<div id="view" ng-view></div>
|
||||
</div>
|
||||
<div class="col-md-2" >
|
||||
<!--right sidebar-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--footer-->
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.js"></script>
|
||||
<script type="text/javascript" src="/js/app.js"></script>
|
||||
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
|
||||
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
|
||||
|
||||
<script src="https://cdn.datatables.net/1.10.6/js/jquery.dataTables.min.js"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
|
||||
|
||||
<!--Mobile and tablet detection-->
|
||||
<script type='text/javascript' src="//wurfl.io/wurfl.js"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
46
frontend/app/pages/static_pages/about.html
Normal file
46
frontend/app/pages/static_pages/about.html
Normal file
@@ -0,0 +1,46 @@
|
||||
<h3>About WrestlingDev</h3>
|
||||
<br>
|
||||
<p>WrestlingDev was created to help bring wrestling into the 21st century for <strong>free</strong>. This site is <a href="https://github.com/jcwimer/wrestlingApp">open source</a> and is supported by the ads on the sidebar.</p>
|
||||
<br>
|
||||
<h4>Features</h4>
|
||||
<br>
|
||||
<p>At this moment in time, WrestlingDev supports a pool to bracket type tournament for up to 16 teams. The bracket format follows OHSAA's 5 match per day rule. WrestlingDev will automatically generate brackets, generate bout numbers, generate and update a bout board, track team points, and update brackets.</p>
|
||||
<p>For pool to bracket tournaments, pool tie breakers are the following:</p>
|
||||
<ul>
|
||||
<li>Least team points deducted</li>
|
||||
<li>Head to head</li>
|
||||
<li>Most team points scored</li>
|
||||
<li>Most wins by fall, default, dq</li>
|
||||
<li>Most wins by tech fall</li>
|
||||
<li>Most wins by major</li>
|
||||
<li>Most points scored in decisions</li>
|
||||
<li>Quickest pin</li>
|
||||
<li>Coin flip</li>
|
||||
</ul>
|
||||
<p>If three wrestlers are tied, they will be put through this sequence until two wrestlers are left. Once two wrestlers are left, the pool runner up will be decided by head to head.</p>
|
||||
<p>For pool to bracket tournaments, team points will be calculated as follows:</p>
|
||||
<ul>
|
||||
<li>Pool win: 2pt</li>
|
||||
<li>Win in championship bracket: 2pt</li>
|
||||
<li>Win in consolation bracket: 1pt</li>
|
||||
<li>Win by major: 1pt extra</li>
|
||||
<li>Win by tech fall: 1.5pt extra</li>
|
||||
<li>Win by fall, default, dq: 2pt extra</li>
|
||||
<li>1st place: 16pt</li>
|
||||
<li>2nd place: 12pt</li>
|
||||
<li>3rd place: 10pt</li>
|
||||
<li>4th place: 9pt</li>
|
||||
<li>5th place: 7pt</li>
|
||||
<li>6th place: 6pt</li>
|
||||
<li>7th place: 4pt</li>
|
||||
<li>8th place: 3pt</li>
|
||||
</ul>
|
||||
<p>Finals matches will only recieve extra placement points for placing higher and bonus points for pin, tech, major, etc. Please note, only brackets with four pools place up to 8. Brackets with 1 or 2 pools only place top 4.</p>
|
||||
<br>
|
||||
<h4>Future Plans</h4>
|
||||
<br>
|
||||
<p>Future development plans to support normal double elimination brackets are underway and are planned to be finished in time for the 2016-2017 wrestling season.</p>
|
||||
<br>
|
||||
<h4>Contact</h4>
|
||||
<br>
|
||||
<p>Suggestions, criticism, and kind words are welcomed. Please contact us.</p>
|
||||
10
frontend/app/pages/static_pages/home.html
Normal file
10
frontend/app/pages/static_pages/home.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<div class="center hero-unit" >
|
||||
<h1>Welcome to WrestlingDev</h1>
|
||||
<br>
|
||||
<p>This website was created to help wrestling coaches run their tournaments. It is 2015, why are we still running bout sheets to tables and why are we still using resources to push cards on a bout board? This website was created as a <strong>free</strong> way for coaches to run a tournament smoothly with as few workers as possible.</p>
|
||||
<br>
|
||||
<p>If you would like to run a tournament, please click log in and then click sign up.</p>
|
||||
<br>
|
||||
<a href='/#/tournaments' class="btn btn-large btn-primary">Browse Tournaments</a>
|
||||
<p></p>
|
||||
</div>
|
||||
17
frontend/app/pages/static_pages/tutorials.html
Normal file
17
frontend/app/pages/static_pages/tutorials.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<h3>Tutorials</h3>
|
||||
<br>
|
||||
<p>Unfortunately, I do not have tutorials available at this moment in time. If you would like to learn how to use this software, please email me at jacob.wimer@gmail.com and I will gladly provide an overview of how to use this software. I've done my best to make the software intuitive and easy to use.</p>
|
||||
<br>
|
||||
<h4>Planning on using this software?</h4>
|
||||
<br>
|
||||
<p>Here is a list of features available:</p>
|
||||
<br>
|
||||
<ul>
|
||||
<li>Pool to bracket type bracket generation for up to 16 man brackets</li>
|
||||
<li>Delegate control to coaches for lineup entry</li>
|
||||
<li>Automatically updated bout board</li>
|
||||
<li>Automatically updated brackets</li>
|
||||
<li>Automatically updated team scores</li>
|
||||
<li>Delegate director privileges to multiple people for tournament administration</li>
|
||||
<li>Matches can be scored at the tables and submitted via computer or bout sheets can be brought to the head table and entered there</li>
|
||||
</ul>
|
||||
17
frontend/app/pages/tournaments/my-tournaments.html
Normal file
17
frontend/app/pages/tournaments/my-tournaments.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<h2>My Tournaments</h2>
|
||||
<br>
|
||||
|
||||
<table class="table">
|
||||
<thead class="font-spot-color">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="tournament in allTournaments">
|
||||
<td><a ng-href="/#/tournaments/{{tournament.id}}">{{ tournament.name }}</a></td>
|
||||
<td>{{ tournament.date }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
25
frontend/app/pages/tournaments/tournaments-search.html
Normal file
25
frontend/app/pages/tournaments/tournaments-search.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<h2>Upcoming Tournaments</h2>
|
||||
<br>
|
||||
<form ng-submit="searchTournaments()">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search by name or date YYYY-MM-DD" ng-model="searchTerms">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="submit" id="submit">Search</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
<br>
|
||||
<table class="table">
|
||||
<thead class="font-spot-color">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="tournament in allTournaments">
|
||||
<td><a ng-href="/#/tournaments/{{tournament.id}}">{{ tournament.name }}</a></td>
|
||||
<td>{{ tournament.date }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
222
frontend/app/pages/tournaments/tournaments-show.html
Normal file
222
frontend/app/pages/tournaments/tournaments-show.html
Normal file
@@ -0,0 +1,222 @@
|
||||
|
||||
<a href="/#/tournaments" class="btn btn-default">Back to browse tournaments</a>
|
||||
<h1>
|
||||
{{ tournament.name }}
|
||||
</h1>
|
||||
<p>
|
||||
<strong>Address:</strong>
|
||||
{{ tournament.address }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Director:</strong>
|
||||
{{ tournament.director }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Director email:</strong>
|
||||
{{ tournament.director_email }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Tournament Type:</strong>
|
||||
{{ tournament.tournament_type }}
|
||||
</p>
|
||||
<br>
|
||||
<div class="panel panel-default">
|
||||
<a class="panel-heading" ng-click="toggleSchools()" style="display: block;">
|
||||
<h3 class="panel-title">School Lineups and Team Scores<span class="pull-left clickable"><i ng-if="showSchools == false" class="glyphicon glyphicon-chevron-down"></i>
|
||||
<i ng-if="showSchools == true" class="glyphicon glyphicon-chevron-up"></i></span></h3>
|
||||
</a>
|
||||
<div id="Schools" ng-if="showSchools == true">
|
||||
<div class="panel-body">
|
||||
<button ng-if="isTournamentOwner(user.id,tournament.user_id)" class="btn btn-success btn-sm" data-toggle="modal" data-target="#NewSchool">Create New School</button>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Score</th>
|
||||
<th ng-if="isTournamentOwner(user.id,tournament.user_id)">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
||||
<tbody>
|
||||
<tr ng-repeat="school in tournament.schools | orderBy : 'score'">
|
||||
<td>{{ school.name }}</td>
|
||||
<td>{{ school.score }}</td>
|
||||
<td ng-if="isTournamentOwner(user.id,tournament.user_id)">
|
||||
<button class="btn btn-sm" data-toggle="modal" data-target="#EditSchool{{school.id}}">Edit</button>
|
||||
<button ng-click="deleteSchool(school)"class="btn btn-danger btn-sm">Destroy</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<a class="panel-heading" ng-click="toggleWeightSeeds()" style="display: block;">
|
||||
<h3 class="panel-title">Weights and Seeds<span class="pull-left clickable"><i ng-if="showWeightSeeds == false" class="glyphicon glyphicon-chevron-down"></i>
|
||||
<i ng-if="showWeightSeeds == true" class="glyphicon glyphicon-chevron-up"></i></span></h3>
|
||||
</a>
|
||||
<div id="Weights" ng-if="showWeightSeeds == true">
|
||||
<div class="panel-body">
|
||||
<p>Click weight class for seeds</p>
|
||||
<br>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Weight Class</th>
|
||||
<th>Bracket Size</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr ng-repeat="weight in tournament.weights | orderBy : 'max' : reverse">
|
||||
<td><a data-toggle="modal" data-target="#Weight{{weight.id}}">{{ weight.max }}</a></td>
|
||||
<td>{{ weight.bracket_size }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<a class="panel-heading" ng-click="toggleBoutBoard()" style="display: block;" >
|
||||
<h3 class="panel-title">Mats and Bout Board<span class="pull-left clickable"><i ng-if="showBoutBoard == false" class="glyphicon glyphicon-chevron-down"></i>
|
||||
<i ng-if="showBoutBoard == true" class="glyphicon glyphicon-chevron-up"></i></span></h3>
|
||||
</a>
|
||||
<div id="Mats" ng-if="showBoutBoard == true">
|
||||
<div class="panel-body">
|
||||
<p ng-if="tournament.matches.length == 0">Matches have not been generated</p>
|
||||
<table ng-if="tournament.matches.length > 0" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>On Mat</th>
|
||||
<th>On Deck</th>
|
||||
<th>In The Hole</th>
|
||||
<th>Warm Up</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr ng-repeat="mat in tournament.mats">
|
||||
<td>{{ mat.name }}</td>
|
||||
<td>{{ mat.unfinishedMatches[0].bout_number }} {{ mat.unfinishedMatches[0].w1_name }} vs. {{ mat.unfinishedMatches[0].w2_name }}</td>
|
||||
<td>{{ mat.unfinishedMatches[1].bout_number }} {{ mat.unfinishedMatches[0].w1_name }} vs. {{ mat.unfinishedMatches[0].w2_name }}</td>
|
||||
<td>{{ mat.unfinishedMatches[2].bout_number }} {{ mat.unfinishedMatches[0].w1_name }} vs. {{ mat.unfinishedMatches[0].w2_name }}</td>
|
||||
<td>{{ mat.unfinishedMatches[3].bout_number }} {{ mat.unfinishedMatches[0].w1_name }} vs. {{ mat.unfinishedMatches[0].w2_name }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<h3 ng-if="tournament.matches.length > 0" >Matches not assigned</h3>
|
||||
<br>
|
||||
<table ng-if="tournament.matches.length > 0" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Round</th>
|
||||
<th>Bout Number</th>
|
||||
<th>Weight Class</th>
|
||||
<th>Matchup</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr ng-repeat="match in tournament.unassignedMatches">
|
||||
<td>Round {{ match.round }}</td>
|
||||
<td>{{ match.bout_number }}</td>
|
||||
<td>{{ match.weightClass }}</td>
|
||||
<td>{{ match.w1_name }} vs. {{ match.w2_name }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Hidden modals for weight seeds-->
|
||||
<div ng-repeat="weight in tournament.weights">
|
||||
<div class="modal fade bs-example-modal-lg" id="Weight{{weight.id}}" tabindex="-1" role="dialog" aria-labelledby="Weight{{weight.id}}">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h3 class="modal-title" id="gridSystemModalLabel">{{weight.max}}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>School</th>
|
||||
<th>Seed</th>
|
||||
<th>Record</th>
|
||||
<th>Criteria</th>
|
||||
<th>Extra?</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="wrestler in weight.wrestlers | orderBy : 'original_seed' : reverse">
|
||||
<td>{{wrestler.name}}</td>
|
||||
<td>{{wrestler.school}}</td>
|
||||
<td>{{wrestler.original_seed}}</td>
|
||||
<td>{{wrestler.season_win}}-{{wrestler.season_loss}}</td>
|
||||
<td>{{wrestler.criteria}} Win %{{wrestler.seasonWinPercentage}}</td>
|
||||
<td>{{wrestler.extra}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Hidden model for new school-->
|
||||
<div class="modal fade bs-example-modal-lg" id="NewSchool" tabindex="-1" role="dialog" aria-labelledby="NewSchool">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h3 class="modal-title" id="gridSystemModalLabel">New School for {{tournament.name}}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form" id="formNewSchool" name="form" ng-submit="saveNewSchool()">
|
||||
<div class="form-group">
|
||||
<input name="school[name]" class="form-control" id="name" type="text" placeholder="School Name" ng-model="newSchool.name"><br>
|
||||
<input type="submit" id="btnSaveNewSchool" class="btn btn-success" value="Save School">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Hidden modals for school edit forms-->
|
||||
<div ng-repeat="school in tournament.schools">
|
||||
<div class="modal fade bs-example-modal-lg" id="EditSchool{{school.id}}" tabindex="-1" role="dialog" aria-labelledby="EditSchool{{school.id}}">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h3 class="modal-title" id="gridSystemModalLabel">Edit {{school.name}}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form" id="formEditSchool{{school.id}}" name="form" ng-submit="updateSchool(school)">
|
||||
<div class="form-group">
|
||||
<input name="school[name]" class="form-control" id="name" type="text" placeholder="School Name" ng-model="school.name"><br>
|
||||
<input type="submit" id="btnSaveNewSchool" class="btn btn-success" value="Save School">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
frontend/app/static/favicon.ico
Normal file
BIN
frontend/app/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
3
frontend/app/templates/hello.us
Normal file
3
frontend/app/templates/hello.us
Normal file
@@ -0,0 +1,3 @@
|
||||
<div class="hello">
|
||||
<%= text %>
|
||||
</div>
|
||||
66
frontend/config/application.js
Normal file
66
frontend/config/application.js
Normal file
@@ -0,0 +1,66 @@
|
||||
/* Exports a function which returns an object that overrides the default &
|
||||
* plugin grunt configuration object.
|
||||
*
|
||||
* You can familiarize yourself with Lineman's defaults by looking at:
|
||||
*
|
||||
* - https://github.com/linemanjs/lineman/blob/master/config/application.coffee
|
||||
* - https://github.com/linemanjs/lineman/blob/master/config/plugins
|
||||
*
|
||||
* You can also ask about Lineman's config from the command line:
|
||||
*
|
||||
* $ lineman config #=> to print the entire config
|
||||
* $ lineman config concat_sourcemap.js #=> to see the JS config for the concat task.
|
||||
*/
|
||||
module.exports = function(lineman) {
|
||||
//Override application configuration here. Common examples follow in the comments.
|
||||
return {
|
||||
|
||||
// API Proxying
|
||||
//
|
||||
// During development, you'll likely want to make XHR (AJAX) requests to an API on the same
|
||||
// port as your lineman development server. By enabling the API proxy and setting the port, all
|
||||
// requests for paths that don't match a static asset in ./generated will be forwarded to
|
||||
// whatever service might be running on the specified port.
|
||||
//
|
||||
server: {
|
||||
apiProxy: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
port: 8080
|
||||
},
|
||||
web: {
|
||||
port: 8081
|
||||
}
|
||||
},
|
||||
|
||||
removeTasks: {
|
||||
common: ["jshint"]
|
||||
},
|
||||
|
||||
// Sass
|
||||
//
|
||||
// Lineman supports Sass via grunt-contrib-sass, which requires you first
|
||||
// have Ruby installed as well as the `sass` gem. To enable it, uncomment the
|
||||
// following line:
|
||||
//
|
||||
// enableSass: true,
|
||||
|
||||
// Asset Fingerprints
|
||||
//
|
||||
// Lineman can fingerprint your static assets by appending a hash to the filename
|
||||
// and logging a manifest of logical-to-hashed filenames in dist/assets.json
|
||||
// via grunt-asset-fingerprint
|
||||
//
|
||||
// enableAssetFingerprint: true,
|
||||
|
||||
// LiveReload
|
||||
//
|
||||
// Lineman can LiveReload browsers whenever a file is changed that results in
|
||||
// assets to be processed, preventing the need to hit F5/Cmd-R every time you
|
||||
// make a change in each browser you're working against. To enable LiveReload,
|
||||
// comment out the following line:
|
||||
//
|
||||
// livereload: true
|
||||
|
||||
};
|
||||
};
|
||||
26
frontend/config/files.js
Normal file
26
frontend/config/files.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Exports a function which returns an object that overrides the default &
|
||||
* plugin file patterns (used widely through the app configuration)
|
||||
*
|
||||
* To see the default definitions for Lineman's file paths and globs, see:
|
||||
*
|
||||
* - https://github.com/linemanjs/lineman/blob/master/config/files.coffee
|
||||
*/
|
||||
module.exports = function(lineman) {
|
||||
//Override file patterns here
|
||||
return {
|
||||
|
||||
// As an example, to override the file patterns for
|
||||
// the order in which to load third party JS libs:
|
||||
//
|
||||
// js: {
|
||||
// vendor: [
|
||||
// "vendor/js/underscore.js",
|
||||
// "vendor/js/**/*.js"
|
||||
// ]
|
||||
// }
|
||||
|
||||
//Override file patterns here
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
1
frontend/config/lineman.js
Normal file
1
frontend/config/lineman.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require(process.env['LINEMAN_MAIN']);
|
||||
21
frontend/config/server.js
Normal file
21
frontend/config/server.js
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Define custom server-side HTTP routes for lineman's development server
|
||||
* These might be as simple as stubbing a little JSON to
|
||||
* facilitate development of code that interacts with an HTTP service
|
||||
* (presumably, mirroring one that will be reachable in a live environment).
|
||||
*
|
||||
* It's important to remember that any custom endpoints defined here
|
||||
* will only be available in development, as lineman only builds
|
||||
* static assets, it can't run server-side code.
|
||||
*
|
||||
* This file can be very useful for rapid prototyping or even organically
|
||||
* defining a spec based on the needs of the client code that emerge.
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
drawRoutes: function(app) {
|
||||
// app.get('/api/greeting/:message', function(req, res){
|
||||
// res.json({ message: "OK, "+req.params.message });
|
||||
// });
|
||||
}
|
||||
};
|
||||
9
frontend/config/spec.json
Normal file
9
frontend/config/spec.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"framework" : "jasmine",
|
||||
"launch_in_dev" : ["Chrome"],
|
||||
"launch_in_ci" : ["PhantomJS"],
|
||||
"src_files" : [
|
||||
"generated/js/app.js",
|
||||
"generated/js/spec.js"
|
||||
]
|
||||
}
|
||||
15
frontend/package.json
Normal file
15
frontend/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"description": "Frontend for wrestlingdev",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"author": "Jacob Cody Wimer",
|
||||
"devDependencies": {
|
||||
"lineman": "~0.36.6"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "lineman run",
|
||||
"test": "lineman spec-ci",
|
||||
"production": "lineman clean build && npm i express@3 && node -e \"var e = require('express'), a = e(); a.use(e.static('dist/')); a.listen(process.env.PORT)\""
|
||||
}
|
||||
}
|
||||
4
frontend/spec/hello-spec.js
Normal file
4
frontend/spec/hello-spec.js
Normal file
@@ -0,0 +1,4 @@
|
||||
describe(".helloText", function(){
|
||||
When(function(){ this.result = helloText(); });
|
||||
Then(function(){ expect(this.result).toEqual("Hello, World!"); });
|
||||
});
|
||||
2
frontend/spec/helpers/helper.js
Normal file
2
frontend/spec/helpers/helper.js
Normal file
@@ -0,0 +1,2 @@
|
||||
window.context = window.describe;
|
||||
window.xcontext = window.xdescribe;
|
||||
433
frontend/spec/helpers/jasmine-fixture.js
Normal file
433
frontend/spec/helpers/jasmine-fixture.js
Normal file
@@ -0,0 +1,433 @@
|
||||
/* jasmine-fixture - 1.3.2
|
||||
* Makes injecting HTML snippets into the DOM easy & clean!
|
||||
* https://github.com/searls/jasmine-fixture
|
||||
*/
|
||||
(function() {
|
||||
var createHTMLBlock,
|
||||
__slice = [].slice;
|
||||
|
||||
(function($) {
|
||||
var ewwSideEffects, jasmineFixture, originalAffix, originalJasmineDotFixture, originalJasmineFixture, root, _, _ref;
|
||||
root = (1, eval)('this');
|
||||
originalJasmineFixture = root.jasmineFixture;
|
||||
originalJasmineDotFixture = (_ref = root.jasmine) != null ? _ref.fixture : void 0;
|
||||
originalAffix = root.affix;
|
||||
_ = function(list) {
|
||||
return {
|
||||
inject: function(iterator, memo) {
|
||||
var item, _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = list.length; _i < _len; _i++) {
|
||||
item = list[_i];
|
||||
_results.push(memo = iterator(memo, item));
|
||||
}
|
||||
return _results;
|
||||
}
|
||||
};
|
||||
};
|
||||
root.jasmineFixture = function($) {
|
||||
var $whatsTheRootOf, affix, create, jasmineFixture, noConflict;
|
||||
affix = function(selectorOptions) {
|
||||
return create.call(this, selectorOptions, true);
|
||||
};
|
||||
create = function(selectorOptions, attach) {
|
||||
var $top;
|
||||
$top = null;
|
||||
_(selectorOptions.split(/[ ](?![^\{]*\})(?=[^\]]*?(?:\[|$))/)).inject(function($parent, elementSelector) {
|
||||
var $el;
|
||||
if (elementSelector === ">") {
|
||||
return $parent;
|
||||
}
|
||||
$el = createHTMLBlock($, elementSelector);
|
||||
if (attach || $top) {
|
||||
$el.appendTo($parent);
|
||||
}
|
||||
$top || ($top = $el);
|
||||
return $el;
|
||||
}, $whatsTheRootOf(this));
|
||||
return $top;
|
||||
};
|
||||
noConflict = function() {
|
||||
var currentJasmineFixture, _ref1;
|
||||
currentJasmineFixture = jasmine.fixture;
|
||||
root.jasmineFixture = originalJasmineFixture;
|
||||
if ((_ref1 = root.jasmine) != null) {
|
||||
_ref1.fixture = originalJasmineDotFixture;
|
||||
}
|
||||
root.affix = originalAffix;
|
||||
return currentJasmineFixture;
|
||||
};
|
||||
$whatsTheRootOf = function(that) {
|
||||
if ((that != null ? that.jquery : void 0) != null) {
|
||||
return that;
|
||||
} else if ($('#jasmine_content').length > 0) {
|
||||
return $('#jasmine_content');
|
||||
} else {
|
||||
return $('<div id="jasmine_content"></div>').appendTo('body');
|
||||
}
|
||||
};
|
||||
jasmineFixture = {
|
||||
affix: affix,
|
||||
create: create,
|
||||
noConflict: noConflict
|
||||
};
|
||||
ewwSideEffects(jasmineFixture);
|
||||
return jasmineFixture;
|
||||
};
|
||||
ewwSideEffects = function(jasmineFixture) {
|
||||
var _ref1;
|
||||
if ((_ref1 = root.jasmine) != null) {
|
||||
_ref1.fixture = jasmineFixture;
|
||||
}
|
||||
$.fn.affix = root.affix = jasmineFixture.affix;
|
||||
return afterEach(function() {
|
||||
return $('#jasmine_content').remove();
|
||||
});
|
||||
};
|
||||
if ($) {
|
||||
return jasmineFixture = root.jasmineFixture($);
|
||||
} else {
|
||||
return root.affix = function() {
|
||||
var nowJQueryExists;
|
||||
nowJQueryExists = window.jQuery || window.$;
|
||||
if (nowJQueryExists != null) {
|
||||
jasmineFixture = root.jasmineFixture(nowJQueryExists);
|
||||
return affix.call.apply(affix, [this].concat(__slice.call(arguments)));
|
||||
} else {
|
||||
throw new Error("jasmine-fixture requires jQuery to be defined at window.jQuery or window.$");
|
||||
}
|
||||
};
|
||||
}
|
||||
})(window.jQuery || window.$);
|
||||
|
||||
createHTMLBlock = (function() {
|
||||
var bindData, bindEvents, parseAttributes, parseClasses, parseContents, parseEnclosure, parseReferences, parseVariableScope, regAttr, regAttrDfn, regAttrs, regCBrace, regClass, regClasses, regData, regDatas, regEvent, regEvents, regExclamation, regId, regReference, regTag, regTagNotContent, regZenTagDfn;
|
||||
createHTMLBlock = function($, ZenObject, data, functions, indexes) {
|
||||
var ZenCode, arr, block, blockAttrs, blockClasses, blockHTML, blockId, blockTag, blocks, el, el2, els, forScope, indexName, inner, len, obj, origZenCode, paren, result, ret, zc, zo;
|
||||
if ($.isPlainObject(ZenObject)) {
|
||||
ZenCode = ZenObject.main;
|
||||
} else {
|
||||
ZenCode = ZenObject;
|
||||
ZenObject = {
|
||||
main: ZenCode
|
||||
};
|
||||
}
|
||||
origZenCode = ZenCode;
|
||||
if (indexes === undefined) {
|
||||
indexes = {};
|
||||
}
|
||||
if (ZenCode.charAt(0) === "!" || $.isArray(data)) {
|
||||
if ($.isArray(data)) {
|
||||
forScope = ZenCode;
|
||||
} else {
|
||||
obj = parseEnclosure(ZenCode, "!");
|
||||
obj = obj.substring(obj.indexOf(":") + 1, obj.length - 1);
|
||||
forScope = parseVariableScope(ZenCode);
|
||||
}
|
||||
while (forScope.charAt(0) === "@") {
|
||||
forScope = parseVariableScope("!for:!" + parseReferences(forScope, ZenObject));
|
||||
}
|
||||
zo = ZenObject;
|
||||
zo.main = forScope;
|
||||
el = $();
|
||||
if (ZenCode.substring(0, 5) === "!for:" || $.isArray(data)) {
|
||||
if (!$.isArray(data) && obj.indexOf(":") > 0) {
|
||||
indexName = obj.substring(0, obj.indexOf(":"));
|
||||
obj = obj.substr(obj.indexOf(":") + 1);
|
||||
}
|
||||
arr = ($.isArray(data) ? data : data[obj]);
|
||||
zc = zo.main;
|
||||
if ($.isArray(arr) || $.isPlainObject(arr)) {
|
||||
$.map(arr, function(value, index) {
|
||||
var next;
|
||||
zo.main = zc;
|
||||
if (indexName !== undefined) {
|
||||
indexes[indexName] = index;
|
||||
}
|
||||
if (!$.isPlainObject(value)) {
|
||||
value = {
|
||||
value: value
|
||||
};
|
||||
}
|
||||
next = createHTMLBlock($, zo, value, functions, indexes);
|
||||
if (el.length !== 0) {
|
||||
return $.each(next, function(index, value) {
|
||||
return el.push(value);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!$.isArray(data)) {
|
||||
ZenCode = ZenCode.substr(obj.length + 6 + forScope.length);
|
||||
} else {
|
||||
ZenCode = "";
|
||||
}
|
||||
} else if (ZenCode.substring(0, 4) === "!if:") {
|
||||
result = parseContents("!" + obj + "!", data, indexes);
|
||||
if (result !== "undefined" || result !== "false" || result !== "") {
|
||||
el = createHTMLBlock($, zo, data, functions, indexes);
|
||||
}
|
||||
ZenCode = ZenCode.substr(obj.length + 5 + forScope.length);
|
||||
}
|
||||
ZenObject.main = ZenCode;
|
||||
} else if (ZenCode.charAt(0) === "(") {
|
||||
paren = parseEnclosure(ZenCode, "(", ")");
|
||||
inner = paren.substring(1, paren.length - 1);
|
||||
ZenCode = ZenCode.substr(paren.length);
|
||||
zo = ZenObject;
|
||||
zo.main = inner;
|
||||
el = createHTMLBlock($, zo, data, functions, indexes);
|
||||
} else {
|
||||
blocks = ZenCode.match(regZenTagDfn);
|
||||
block = blocks[0];
|
||||
if (block.length === 0) {
|
||||
return "";
|
||||
}
|
||||
if (block.indexOf("@") >= 0) {
|
||||
ZenCode = parseReferences(ZenCode, ZenObject);
|
||||
zo = ZenObject;
|
||||
zo.main = ZenCode;
|
||||
return createHTMLBlock($, zo, data, functions, indexes);
|
||||
}
|
||||
block = parseContents(block, data, indexes);
|
||||
blockClasses = parseClasses($, block);
|
||||
if (regId.test(block)) {
|
||||
blockId = regId.exec(block)[1];
|
||||
}
|
||||
blockAttrs = parseAttributes(block, data);
|
||||
blockTag = (block.charAt(0) === "{" ? "span" : "div");
|
||||
if (ZenCode.charAt(0) !== "#" && ZenCode.charAt(0) !== "." && ZenCode.charAt(0) !== "{") {
|
||||
blockTag = regTag.exec(block)[1];
|
||||
}
|
||||
if (block.search(regCBrace) !== -1) {
|
||||
blockHTML = block.match(regCBrace)[1];
|
||||
}
|
||||
blockAttrs = $.extend(blockAttrs, {
|
||||
id: blockId,
|
||||
"class": blockClasses,
|
||||
html: blockHTML
|
||||
});
|
||||
el = $("<" + blockTag + ">", blockAttrs);
|
||||
el.attr(blockAttrs);
|
||||
el = bindEvents(block, el, functions);
|
||||
el = bindData(block, el, data);
|
||||
ZenCode = ZenCode.substr(blocks[0].length);
|
||||
ZenObject.main = ZenCode;
|
||||
}
|
||||
if (ZenCode.length > 0) {
|
||||
if (ZenCode.charAt(0) === ">") {
|
||||
if (ZenCode.charAt(1) === "(") {
|
||||
zc = parseEnclosure(ZenCode.substr(1), "(", ")");
|
||||
ZenCode = ZenCode.substr(zc.length + 1);
|
||||
} else if (ZenCode.charAt(1) === "!") {
|
||||
obj = parseEnclosure(ZenCode.substr(1), "!");
|
||||
forScope = parseVariableScope(ZenCode.substr(1));
|
||||
zc = obj + forScope;
|
||||
ZenCode = ZenCode.substr(zc.length + 1);
|
||||
} else {
|
||||
len = Math.max(ZenCode.indexOf("+"), ZenCode.length);
|
||||
zc = ZenCode.substring(1, len);
|
||||
ZenCode = ZenCode.substr(len);
|
||||
}
|
||||
zo = ZenObject;
|
||||
zo.main = zc;
|
||||
els = $(createHTMLBlock($, zo, data, functions, indexes));
|
||||
els.appendTo(el);
|
||||
}
|
||||
if (ZenCode.charAt(0) === "+") {
|
||||
zo = ZenObject;
|
||||
zo.main = ZenCode.substr(1);
|
||||
el2 = createHTMLBlock($, zo, data, functions, indexes);
|
||||
$.each(el2, function(index, value) {
|
||||
return el.push(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
ret = el;
|
||||
return ret;
|
||||
};
|
||||
bindData = function(ZenCode, el, data) {
|
||||
var datas, i, split;
|
||||
if (ZenCode.search(regDatas) === 0) {
|
||||
return el;
|
||||
}
|
||||
datas = ZenCode.match(regDatas);
|
||||
if (datas === null) {
|
||||
return el;
|
||||
}
|
||||
i = 0;
|
||||
while (i < datas.length) {
|
||||
split = regData.exec(datas[i]);
|
||||
if (split[3] === undefined) {
|
||||
$(el).data(split[1], data[split[1]]);
|
||||
} else {
|
||||
$(el).data(split[1], data[split[3]]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return el;
|
||||
};
|
||||
bindEvents = function(ZenCode, el, functions) {
|
||||
var bindings, fn, i, split;
|
||||
if (ZenCode.search(regEvents) === 0) {
|
||||
return el;
|
||||
}
|
||||
bindings = ZenCode.match(regEvents);
|
||||
if (bindings === null) {
|
||||
return el;
|
||||
}
|
||||
i = 0;
|
||||
while (i < bindings.length) {
|
||||
split = regEvent.exec(bindings[i]);
|
||||
if (split[2] === undefined) {
|
||||
fn = functions[split[1]];
|
||||
} else {
|
||||
fn = functions[split[2]];
|
||||
}
|
||||
$(el).bind(split[1], fn);
|
||||
i++;
|
||||
}
|
||||
return el;
|
||||
};
|
||||
parseAttributes = function(ZenBlock, data) {
|
||||
var attrStrs, attrs, i, parts;
|
||||
if (ZenBlock.search(regAttrDfn) === -1) {
|
||||
return undefined;
|
||||
}
|
||||
attrStrs = ZenBlock.match(regAttrDfn);
|
||||
attrs = {};
|
||||
i = 0;
|
||||
while (i < attrStrs.length) {
|
||||
parts = regAttr.exec(attrStrs[i]);
|
||||
attrs[parts[1]] = "";
|
||||
if (parts[3] !== undefined) {
|
||||
attrs[parts[1]] = parseContents(parts[3], data);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return attrs;
|
||||
};
|
||||
parseClasses = function($, ZenBlock) {
|
||||
var classes, clsString, i;
|
||||
ZenBlock = ZenBlock.match(regTagNotContent)[0];
|
||||
if (ZenBlock.search(regClasses) === -1) {
|
||||
return undefined;
|
||||
}
|
||||
classes = ZenBlock.match(regClasses);
|
||||
clsString = "";
|
||||
i = 0;
|
||||
while (i < classes.length) {
|
||||
clsString += " " + regClass.exec(classes[i])[1];
|
||||
i++;
|
||||
}
|
||||
return $.trim(clsString);
|
||||
};
|
||||
parseContents = function(ZenBlock, data, indexes) {
|
||||
var html;
|
||||
if (indexes === undefined) {
|
||||
indexes = {};
|
||||
}
|
||||
html = ZenBlock;
|
||||
if (data === undefined) {
|
||||
return html;
|
||||
}
|
||||
while (regExclamation.test(html)) {
|
||||
html = html.replace(regExclamation, function(str, str2) {
|
||||
var begChar, fn, val;
|
||||
begChar = "";
|
||||
if (str.indexOf("!for:") > 0 || str.indexOf("!if:") > 0) {
|
||||
return str;
|
||||
}
|
||||
if (str.charAt(0) !== "!") {
|
||||
begChar = str.charAt(0);
|
||||
str = str.substring(2, str.length - 1);
|
||||
}
|
||||
fn = new Function("data", "indexes", "var r=undefined;" + "with(data){try{r=" + str + ";}catch(e){}}" + "with(indexes){try{if(r===undefined)r=" + str + ";}catch(e){}}" + "return r;");
|
||||
val = unescape(fn(data, indexes));
|
||||
return begChar + val;
|
||||
});
|
||||
}
|
||||
html = html.replace(/\\./g, function(str) {
|
||||
return str.charAt(1);
|
||||
});
|
||||
return unescape(html);
|
||||
};
|
||||
parseEnclosure = function(ZenCode, open, close, count) {
|
||||
var index, ret;
|
||||
if (close === undefined) {
|
||||
close = open;
|
||||
}
|
||||
index = 1;
|
||||
if (count === undefined) {
|
||||
count = (ZenCode.charAt(0) === open ? 1 : 0);
|
||||
}
|
||||
if (count === 0) {
|
||||
return;
|
||||
}
|
||||
while (count > 0 && index < ZenCode.length) {
|
||||
if (ZenCode.charAt(index) === close && ZenCode.charAt(index - 1) !== "\\") {
|
||||
count--;
|
||||
} else {
|
||||
if (ZenCode.charAt(index) === open && ZenCode.charAt(index - 1) !== "\\") {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
ret = ZenCode.substring(0, index);
|
||||
return ret;
|
||||
};
|
||||
parseReferences = function(ZenCode, ZenObject) {
|
||||
ZenCode = ZenCode.replace(regReference, function(str) {
|
||||
var fn;
|
||||
str = str.substr(1);
|
||||
fn = new Function("objs", "var r=\"\";" + "with(objs){try{" + "r=" + str + ";" + "}catch(e){}}" + "return r;");
|
||||
return fn(ZenObject, parseReferences);
|
||||
});
|
||||
return ZenCode;
|
||||
};
|
||||
parseVariableScope = function(ZenCode) {
|
||||
var forCode, rest, tag;
|
||||
if (ZenCode.substring(0, 5) !== "!for:" && ZenCode.substring(0, 4) !== "!if:") {
|
||||
return undefined;
|
||||
}
|
||||
forCode = parseEnclosure(ZenCode, "!");
|
||||
ZenCode = ZenCode.substr(forCode.length);
|
||||
if (ZenCode.charAt(0) === "(") {
|
||||
return parseEnclosure(ZenCode, "(", ")");
|
||||
}
|
||||
tag = ZenCode.match(regZenTagDfn)[0];
|
||||
ZenCode = ZenCode.substr(tag.length);
|
||||
if (ZenCode.length === 0 || ZenCode.charAt(0) === "+") {
|
||||
return tag;
|
||||
} else if (ZenCode.charAt(0) === ">") {
|
||||
rest = "";
|
||||
rest = parseEnclosure(ZenCode.substr(1), "(", ")", 1);
|
||||
return tag + ">" + rest;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
regZenTagDfn = /([#\.\@]?[\w-]+|\[([\w-!?=:"']+(="([^"]|\\")+")? {0,})+\]|\~[\w$]+=[\w$]+|&[\w$]+(=[\w$]+)?|[#\.\@]?!([^!]|\\!)+!){0,}(\{([^\}]|\\\})+\})?/i;
|
||||
regTag = /(\w+)/i;
|
||||
regId = /(?:^|\b)#([\w-!]+)/i;
|
||||
regTagNotContent = /((([#\.]?[\w-]+)?(\[([\w!]+(="([^"]|\\")+")? {0,})+\])?)+)/i;
|
||||
/*
|
||||
See lookahead syntax (?!) at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
||||
*/
|
||||
|
||||
regClasses = /(\.[\w-]+)(?!["\w])/g;
|
||||
regClass = /\.([\w-]+)/i;
|
||||
regReference = /(@[\w$_][\w$_\d]+)/i;
|
||||
regAttrDfn = /(\[([\w-!]+(="?([^"]|\\")+"?)? {0,})+\])/ig;
|
||||
regAttrs = /([\w-!]+(="([^"]|\\")+")?)/g;
|
||||
regAttr = /([\w-!]+)(="?((([\w]+(\[.*?\])+)|[^"\]]|\\")+)"?)?/i;
|
||||
regCBrace = /\{(([^\}]|\\\})+)\}/i;
|
||||
regExclamation = /(?:([^\\]|^))!([^!]|\\!)+!/g;
|
||||
regEvents = /\~[\w$]+(=[\w$]+)?/g;
|
||||
regEvent = /\~([\w$]+)=([\w$]+)/i;
|
||||
regDatas = /&[\w$]+(=[\w$]+)?/g;
|
||||
regData = /&([\w$]+)(=([\w$]+))?/i;
|
||||
return createHTMLBlock;
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
373
frontend/spec/helpers/jasmine-given.js
Normal file
373
frontend/spec/helpers/jasmine-given.js
Normal file
@@ -0,0 +1,373 @@
|
||||
/* jasmine-given - 2.6.3
|
||||
* Adds a Given-When-Then DSL to jasmine as an alternative style for specs
|
||||
* https://github.com/searls/jasmine-given
|
||||
*/
|
||||
/* jasmine-matcher-wrapper - 0.0.3
|
||||
* Wraps Jasmine 1.x matchers for use with Jasmine 2
|
||||
* https://github.com/testdouble/jasmine-matcher-wrapper
|
||||
*/
|
||||
(function() {
|
||||
var __hasProp = {}.hasOwnProperty,
|
||||
__slice = [].slice;
|
||||
|
||||
(function(jasmine) {
|
||||
var comparatorFor, createMatcher;
|
||||
if (jasmine == null) {
|
||||
return typeof console !== "undefined" && console !== null ? console.warn("jasmine was not found. Skipping jasmine-matcher-wrapper. Verify your script load order.") : void 0;
|
||||
}
|
||||
if (jasmine.matcherWrapper != null) {
|
||||
return;
|
||||
}
|
||||
jasmine.matcherWrapper = {
|
||||
wrap: function(matchers) {
|
||||
var matcher, name, wrappedMatchers;
|
||||
if (jasmine.addMatchers == null) {
|
||||
return matchers;
|
||||
}
|
||||
wrappedMatchers = {};
|
||||
for (name in matchers) {
|
||||
if (!__hasProp.call(matchers, name)) continue;
|
||||
matcher = matchers[name];
|
||||
wrappedMatchers[name] = createMatcher(name, matcher);
|
||||
}
|
||||
return wrappedMatchers;
|
||||
}
|
||||
};
|
||||
createMatcher = function(name, matcher) {
|
||||
return function() {
|
||||
return {
|
||||
compare: comparatorFor(matcher, false),
|
||||
negativeCompare: comparatorFor(matcher, true)
|
||||
};
|
||||
};
|
||||
};
|
||||
return comparatorFor = function(matcher, isNot) {
|
||||
return function() {
|
||||
var actual, context, message, params, pass, _ref;
|
||||
actual = arguments[0], params = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||
context = {
|
||||
actual: actual,
|
||||
isNot: isNot
|
||||
};
|
||||
pass = matcher.apply(context, params);
|
||||
if (isNot) {
|
||||
pass = !pass;
|
||||
}
|
||||
if (!pass) {
|
||||
message = (_ref = context.message) != null ? _ref.apply(context, params) : void 0;
|
||||
}
|
||||
return {
|
||||
pass: pass,
|
||||
message: message
|
||||
};
|
||||
};
|
||||
};
|
||||
})(jasmine || getJasmineRequireObj());
|
||||
|
||||
}).call(this);
|
||||
|
||||
(function() {
|
||||
var __slice = [].slice;
|
||||
|
||||
(function(jasmine) {
|
||||
var Waterfall, additionalInsightsForErrorMessage, apparentReferenceError, attemptedEquality, cloneArray, comparisonInsight, currentSpec, declareJasmineSpec, deepEqualsNotice, doneWrapperFor, errorWithRemovedLines, evalInContextOfSpec, finalStatementFrom, getBlock, invariantList, mostRecentExpectations, mostRecentStacks, mostRecentlyUsed, o, root, stringifyExpectation, wasComparison, whenList, wrapAsExpectations;
|
||||
mostRecentlyUsed = null;
|
||||
root = (1, eval)('this');
|
||||
currentSpec = null;
|
||||
beforeEach(function() {
|
||||
return currentSpec = this;
|
||||
});
|
||||
root.Given = function() {
|
||||
mostRecentlyUsed = root.Given;
|
||||
return beforeEach(getBlock(arguments));
|
||||
};
|
||||
whenList = [];
|
||||
root.When = function() {
|
||||
var b;
|
||||
mostRecentlyUsed = root.When;
|
||||
b = getBlock(arguments);
|
||||
beforeEach(function() {
|
||||
return whenList.push(b);
|
||||
});
|
||||
return afterEach(function() {
|
||||
return whenList.pop();
|
||||
});
|
||||
};
|
||||
invariantList = [];
|
||||
root.Invariant = function() {
|
||||
var invariantBehavior;
|
||||
mostRecentlyUsed = root.Invariant;
|
||||
invariantBehavior = getBlock(arguments);
|
||||
beforeEach(function() {
|
||||
return invariantList.push(invariantBehavior);
|
||||
});
|
||||
return afterEach(function() {
|
||||
return invariantList.pop();
|
||||
});
|
||||
};
|
||||
getBlock = function(thing) {
|
||||
var assignResultTo, setupFunction;
|
||||
setupFunction = o(thing).firstThat(function(arg) {
|
||||
return o(arg).isFunction();
|
||||
});
|
||||
assignResultTo = o(thing).firstThat(function(arg) {
|
||||
return o(arg).isString();
|
||||
});
|
||||
return doneWrapperFor(setupFunction, function(done) {
|
||||
var context, result;
|
||||
context = currentSpec;
|
||||
result = setupFunction.call(context, done);
|
||||
if (assignResultTo) {
|
||||
if (!context[assignResultTo]) {
|
||||
return context[assignResultTo] = result;
|
||||
} else {
|
||||
throw new Error("Unfortunately, the variable '" + assignResultTo + "' is already assigned to: " + context[assignResultTo]);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
mostRecentExpectations = null;
|
||||
mostRecentStacks = null;
|
||||
declareJasmineSpec = function(specArgs, itFunction) {
|
||||
var expectationFunction, expectations, label, stacks;
|
||||
if (itFunction == null) {
|
||||
itFunction = it;
|
||||
}
|
||||
label = o(specArgs).firstThat(function(arg) {
|
||||
return o(arg).isString();
|
||||
});
|
||||
expectationFunction = o(specArgs).firstThat(function(arg) {
|
||||
return o(arg).isFunction();
|
||||
});
|
||||
mostRecentlyUsed = root.subsequentThen;
|
||||
mostRecentExpectations = expectations = [expectationFunction];
|
||||
mostRecentStacks = stacks = [errorWithRemovedLines("failed expectation", 3)];
|
||||
itFunction("then " + (label != null ? label : stringifyExpectation(expectations)), doneWrapperFor(expectationFunction, function(jasmineDone) {
|
||||
var userCommands;
|
||||
userCommands = [].concat(whenList, invariantList, wrapAsExpectations(expectations, stacks));
|
||||
return new Waterfall(userCommands, jasmineDone).flow();
|
||||
}));
|
||||
return {
|
||||
Then: subsequentThen,
|
||||
And: subsequentThen
|
||||
};
|
||||
};
|
||||
wrapAsExpectations = function(expectations, stacks) {
|
||||
var expectation, i, _i, _len, _results;
|
||||
_results = [];
|
||||
for (i = _i = 0, _len = expectations.length; _i < _len; i = ++_i) {
|
||||
expectation = expectations[i];
|
||||
_results.push((function(expectation, i) {
|
||||
return doneWrapperFor(expectation, function(maybeDone) {
|
||||
return expect(expectation).not.toHaveReturnedFalseFromThen(currentSpec, i + 1, stacks[i], maybeDone);
|
||||
});
|
||||
})(expectation, i));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
doneWrapperFor = function(func, toWrap) {
|
||||
if (func.length === 0) {
|
||||
return function() {
|
||||
return toWrap();
|
||||
};
|
||||
} else {
|
||||
return function(done) {
|
||||
return toWrap(done);
|
||||
};
|
||||
}
|
||||
};
|
||||
root.Then = function() {
|
||||
return declareJasmineSpec(arguments);
|
||||
};
|
||||
root.Then.only = function() {
|
||||
return declareJasmineSpec(arguments, it.only);
|
||||
};
|
||||
root.subsequentThen = function(additionalExpectation) {
|
||||
mostRecentExpectations.push(additionalExpectation);
|
||||
mostRecentStacks.push(errorWithRemovedLines("failed expectation", 3));
|
||||
return this;
|
||||
};
|
||||
errorWithRemovedLines = function(msg, n) {
|
||||
var error, lines, stack, _ref;
|
||||
if (stack = new Error(msg).stack) {
|
||||
_ref = stack.split("\n"), error = _ref[0], lines = 2 <= _ref.length ? __slice.call(_ref, 1) : [];
|
||||
return "" + error + "\n" + (lines.slice(n).join("\n"));
|
||||
}
|
||||
};
|
||||
mostRecentlyUsed = root.Given;
|
||||
root.And = function() {
|
||||
return mostRecentlyUsed.apply(this, jasmine.util.argsToArray(arguments));
|
||||
};
|
||||
o = function(thing) {
|
||||
return {
|
||||
isFunction: function() {
|
||||
return Object.prototype.toString.call(thing) === "[object Function]";
|
||||
},
|
||||
isString: function() {
|
||||
return Object.prototype.toString.call(thing) === "[object String]";
|
||||
},
|
||||
firstThat: function(test) {
|
||||
var i;
|
||||
i = 0;
|
||||
while (i < thing.length) {
|
||||
if (test(thing[i]) === true) {
|
||||
return thing[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
Waterfall = (function() {
|
||||
function Waterfall(functions, finalCallback) {
|
||||
if (functions == null) {
|
||||
functions = [];
|
||||
}
|
||||
this.finalCallback = finalCallback != null ? finalCallback : function() {};
|
||||
this.functions = cloneArray(functions);
|
||||
}
|
||||
|
||||
Waterfall.prototype.flow = function() {
|
||||
var func,
|
||||
_this = this;
|
||||
if (this.functions.length === 0) {
|
||||
return this.finalCallback();
|
||||
}
|
||||
func = this.functions.shift();
|
||||
if (func.length > 0) {
|
||||
return func(function() {
|
||||
return _this.flow();
|
||||
});
|
||||
} else {
|
||||
func();
|
||||
return this.flow();
|
||||
}
|
||||
};
|
||||
|
||||
return Waterfall;
|
||||
|
||||
})();
|
||||
cloneArray = function(a) {
|
||||
return a.slice(0);
|
||||
};
|
||||
jasmine._given = {
|
||||
matchers: {
|
||||
toHaveReturnedFalseFromThen: function(context, n, stackTrace, done) {
|
||||
var e, exception, result;
|
||||
result = false;
|
||||
exception = void 0;
|
||||
try {
|
||||
result = this.actual.call(context, done);
|
||||
} catch (_error) {
|
||||
e = _error;
|
||||
exception = e;
|
||||
}
|
||||
this.message = function() {
|
||||
var msg, stringyExpectation;
|
||||
stringyExpectation = stringifyExpectation(this.actual);
|
||||
msg = "Then clause" + (n > 1 ? " #" + n : "") + " `" + stringyExpectation + "` failed by ";
|
||||
if (exception) {
|
||||
msg += "throwing: " + exception.toString();
|
||||
} else {
|
||||
msg += "returning false";
|
||||
}
|
||||
msg += additionalInsightsForErrorMessage(stringyExpectation);
|
||||
if (stackTrace != null) {
|
||||
msg += "\n\n" + stackTrace;
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
return result === false;
|
||||
}
|
||||
},
|
||||
__Waterfall__: Waterfall
|
||||
};
|
||||
stringifyExpectation = function(expectation) {
|
||||
var matches;
|
||||
matches = expectation.toString().replace(/\n/g, '').match(/function\s?\(.*\)\s?{\s*(return\s+)?(.*?)(;)?\s*}/i);
|
||||
if (matches && matches.length >= 3) {
|
||||
return matches[2].replace(/\s+/g, ' ');
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
additionalInsightsForErrorMessage = function(expectationString) {
|
||||
var comparison, expectation;
|
||||
expectation = finalStatementFrom(expectationString);
|
||||
if (comparison = wasComparison(expectation)) {
|
||||
return comparisonInsight(expectation, comparison);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
finalStatementFrom = function(expectationString) {
|
||||
var multiStatement;
|
||||
if (multiStatement = expectationString.match(/.*return (.*)/)) {
|
||||
return multiStatement[multiStatement.length - 1];
|
||||
} else {
|
||||
return expectationString;
|
||||
}
|
||||
};
|
||||
wasComparison = function(expectation) {
|
||||
var comparator, comparison, left, right, s;
|
||||
if (comparison = expectation.match(/(.*) (===|!==|==|!=|>|>=|<|<=) (.*)/)) {
|
||||
s = comparison[0], left = comparison[1], comparator = comparison[2], right = comparison[3];
|
||||
return {
|
||||
left: left,
|
||||
comparator: comparator,
|
||||
right: right
|
||||
};
|
||||
}
|
||||
};
|
||||
comparisonInsight = function(expectation, comparison) {
|
||||
var left, msg, right;
|
||||
left = evalInContextOfSpec(comparison.left);
|
||||
right = evalInContextOfSpec(comparison.right);
|
||||
if (apparentReferenceError(left) && apparentReferenceError(right)) {
|
||||
return "";
|
||||
}
|
||||
msg = "\n\nThis comparison was detected:\n " + expectation + "\n " + left + " " + comparison.comparator + " " + right;
|
||||
if (attemptedEquality(left, right, comparison.comparator)) {
|
||||
msg += "\n\n" + (deepEqualsNotice(comparison.left, comparison.right));
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
apparentReferenceError = function(result) {
|
||||
return /^<Error: "ReferenceError/.test(result);
|
||||
};
|
||||
evalInContextOfSpec = function(operand) {
|
||||
var e;
|
||||
try {
|
||||
return (function() {
|
||||
return eval(operand);
|
||||
}).call(currentSpec);
|
||||
} catch (_error) {
|
||||
e = _error;
|
||||
return "<Error: \"" + ((e != null ? typeof e.message === "function" ? e.message() : void 0 : void 0) || e) + "\">";
|
||||
}
|
||||
};
|
||||
attemptedEquality = function(left, right, comparator) {
|
||||
var _ref;
|
||||
if (!(comparator === "==" || comparator === "===")) {
|
||||
return false;
|
||||
}
|
||||
if (((_ref = jasmine.matchersUtil) != null ? _ref.equals : void 0) != null) {
|
||||
return jasmine.matchersUtil.equals(left, right);
|
||||
} else {
|
||||
return jasmine.getEnv().equals_(left, right);
|
||||
}
|
||||
};
|
||||
deepEqualsNotice = function(left, right) {
|
||||
return "However, these items are deeply equal! Try an expectation like this instead:\n expect(" + left + ").toEqual(" + right + ")";
|
||||
};
|
||||
return beforeEach(function() {
|
||||
if (jasmine.addMatchers != null) {
|
||||
return jasmine.addMatchers(jasmine.matcherWrapper.wrap(jasmine._given.matchers));
|
||||
} else {
|
||||
return this.addMatchers(jasmine._given.matchers);
|
||||
}
|
||||
});
|
||||
})(jasmine);
|
||||
|
||||
}).call(this);
|
||||
98
frontend/spec/helpers/jasmine-only.js
Normal file
98
frontend/spec/helpers/jasmine-only.js
Normal file
@@ -0,0 +1,98 @@
|
||||
/* jasmine-only - 0.1.1
|
||||
* Exclusivity spec helpers for jasmine: `describe.only` and `it.only`
|
||||
* https://github.com/davemo/jasmine-only
|
||||
*/
|
||||
(function() {
|
||||
var __hasProp = {}.hasOwnProperty,
|
||||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||||
|
||||
(function(jasmine) {
|
||||
var describeOnly, env, itOnly, root;
|
||||
root = (1, eval)('this');
|
||||
env = jasmine.getEnv();
|
||||
describeOnly = function(description, specDefinitions) {
|
||||
var suite;
|
||||
suite = new jasmine.Suite(this, description, null, this.currentSuite);
|
||||
suite.exclusive_ = 1;
|
||||
this.exclusive_ = Math.max(this.exclusive_, 1);
|
||||
return this.describe_(suite, specDefinitions);
|
||||
};
|
||||
itOnly = function(description, func) {
|
||||
var spec;
|
||||
spec = this.it(description, func);
|
||||
spec.exclusive_ = 2;
|
||||
this.exclusive_ = 2;
|
||||
return spec;
|
||||
};
|
||||
env.exclusive_ = 0;
|
||||
env.describe = function(description, specDefinitions) {
|
||||
var suite;
|
||||
suite = new jasmine.Suite(this, description, null, this.currentSuite);
|
||||
return this.describe_(suite, specDefinitions);
|
||||
};
|
||||
env.describe_ = function(suite, specDefinitions) {
|
||||
var declarationError, e, parentSuite;
|
||||
parentSuite = this.currentSuite;
|
||||
if (parentSuite) {
|
||||
parentSuite.add(suite);
|
||||
} else {
|
||||
this.currentRunner_.add(suite);
|
||||
}
|
||||
this.currentSuite = suite;
|
||||
declarationError = null;
|
||||
try {
|
||||
specDefinitions.call(suite);
|
||||
} catch (_error) {
|
||||
e = _error;
|
||||
declarationError = e;
|
||||
}
|
||||
if (declarationError) {
|
||||
this.it("encountered a declaration exception", function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
this.currentSuite = parentSuite;
|
||||
return suite;
|
||||
};
|
||||
env.specFilter = function(spec) {
|
||||
return this.exclusive_ <= spec.exclusive_;
|
||||
};
|
||||
env.describe.only = function() {
|
||||
return describeOnly.apply(env, arguments);
|
||||
};
|
||||
env.it.only = function() {
|
||||
return itOnly.apply(env, arguments);
|
||||
};
|
||||
root.describe.only = function(description, specDefinitions) {
|
||||
return env.describe.only(description, specDefinitions);
|
||||
};
|
||||
root.it.only = function(description, func) {
|
||||
return env.it.only(description, func);
|
||||
};
|
||||
root.iit = root.it.only;
|
||||
root.ddescribe = root.describe.only;
|
||||
jasmine.Spec = (function(_super) {
|
||||
__extends(Spec, _super);
|
||||
|
||||
function Spec(env, suite, description) {
|
||||
this.exclusive_ = suite.exclusive_;
|
||||
Spec.__super__.constructor.call(this, env, suite, description);
|
||||
}
|
||||
|
||||
return Spec;
|
||||
|
||||
})(jasmine.Spec);
|
||||
return jasmine.Suite = (function(_super) {
|
||||
__extends(Suite, _super);
|
||||
|
||||
function Suite(env, suite, specDefinitions, parentSuite) {
|
||||
this.exclusive_ = parentSuite && parentSuite.exclusive_ || 0;
|
||||
Suite.__super__.constructor.call(this, env, suite, specDefinitions, parentSuite);
|
||||
}
|
||||
|
||||
return Suite;
|
||||
|
||||
})(jasmine.Suite);
|
||||
})(jasmine);
|
||||
|
||||
}).call(this);
|
||||
214
frontend/spec/helpers/jasmine-stealth.js
Normal file
214
frontend/spec/helpers/jasmine-stealth.js
Normal file
@@ -0,0 +1,214 @@
|
||||
/* jasmine-stealth - 0.0.17
|
||||
* Makes Jasmine spies a bit more robust
|
||||
* https://github.com/searls/jasmine-stealth
|
||||
*/
|
||||
(function() {
|
||||
var __hasProp = {}.hasOwnProperty,
|
||||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
||||
|
||||
(function() {
|
||||
var Captor, fake, root, stubChainer, unfakes, whatToDoWhenTheSpyGetsCalled, _;
|
||||
root = (1, eval)('this');
|
||||
_ = function(obj) {
|
||||
return {
|
||||
each: function(iterator) {
|
||||
var item, _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = obj.length; _i < _len; _i++) {
|
||||
item = obj[_i];
|
||||
_results.push(iterator(item));
|
||||
}
|
||||
return _results;
|
||||
},
|
||||
isFunction: function() {
|
||||
return Object.prototype.toString.call(obj) === "[object Function]";
|
||||
},
|
||||
isString: function() {
|
||||
return Object.prototype.toString.call(obj) === "[object String]";
|
||||
}
|
||||
};
|
||||
};
|
||||
root.spyOnConstructor = function(owner, classToFake, methodsToSpy) {
|
||||
var fakeClass, spies;
|
||||
if (methodsToSpy == null) {
|
||||
methodsToSpy = [];
|
||||
}
|
||||
if (_(methodsToSpy).isString()) {
|
||||
methodsToSpy = [methodsToSpy];
|
||||
}
|
||||
spies = {
|
||||
constructor: jasmine.createSpy("" + classToFake + "'s constructor")
|
||||
};
|
||||
fakeClass = (function() {
|
||||
function _Class() {
|
||||
spies.constructor.apply(this, arguments);
|
||||
}
|
||||
|
||||
return _Class;
|
||||
|
||||
})();
|
||||
_(methodsToSpy).each(function(methodName) {
|
||||
spies[methodName] = jasmine.createSpy("" + classToFake + "#" + methodName);
|
||||
return fakeClass.prototype[methodName] = function() {
|
||||
return spies[methodName].apply(this, arguments);
|
||||
};
|
||||
});
|
||||
fake(owner, classToFake, fakeClass);
|
||||
return spies;
|
||||
};
|
||||
unfakes = [];
|
||||
afterEach(function() {
|
||||
_(unfakes).each(function(u) {
|
||||
return u();
|
||||
});
|
||||
return unfakes = [];
|
||||
});
|
||||
fake = function(owner, thingToFake, newThing) {
|
||||
var originalThing;
|
||||
originalThing = owner[thingToFake];
|
||||
owner[thingToFake] = newThing;
|
||||
return unfakes.push(function() {
|
||||
return owner[thingToFake] = originalThing;
|
||||
});
|
||||
};
|
||||
root.stubFor = root.spyOn;
|
||||
jasmine.createStub = jasmine.createSpy;
|
||||
jasmine.createStubObj = function(baseName, stubbings) {
|
||||
var name, obj, stubbing;
|
||||
if (stubbings.constructor === Array) {
|
||||
return jasmine.createSpyObj(baseName, stubbings);
|
||||
} else {
|
||||
obj = {};
|
||||
for (name in stubbings) {
|
||||
stubbing = stubbings[name];
|
||||
obj[name] = jasmine.createSpy(baseName + "." + name);
|
||||
if (_(stubbing).isFunction()) {
|
||||
obj[name].andCallFake(stubbing);
|
||||
} else {
|
||||
obj[name].andReturn(stubbing);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
whatToDoWhenTheSpyGetsCalled = function(spy) {
|
||||
var matchesStub, priorPlan;
|
||||
matchesStub = function(stubbing, args, context) {
|
||||
switch (stubbing.type) {
|
||||
case "args":
|
||||
return jasmine.getEnv().equals_(stubbing.ifThis, jasmine.util.argsToArray(args));
|
||||
case "context":
|
||||
return jasmine.getEnv().equals_(stubbing.ifThis, context);
|
||||
}
|
||||
};
|
||||
priorPlan = spy.plan;
|
||||
return spy.andCallFake(function() {
|
||||
var i, stubbing;
|
||||
i = 0;
|
||||
while (i < spy._stealth_stubbings.length) {
|
||||
stubbing = spy._stealth_stubbings[i];
|
||||
if (matchesStub(stubbing, arguments, this)) {
|
||||
if (stubbing.satisfaction === "callFake") {
|
||||
return stubbing.thenThat.apply(stubbing, arguments);
|
||||
} else {
|
||||
return stubbing.thenThat;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return priorPlan.apply(spy, arguments);
|
||||
});
|
||||
};
|
||||
jasmine.Spy.prototype.whenContext = function(context) {
|
||||
var spy;
|
||||
spy = this;
|
||||
spy._stealth_stubbings || (spy._stealth_stubbings = []);
|
||||
whatToDoWhenTheSpyGetsCalled(spy);
|
||||
return stubChainer(spy, "context", context);
|
||||
};
|
||||
jasmine.Spy.prototype.when = function() {
|
||||
var ifThis, spy;
|
||||
spy = this;
|
||||
ifThis = jasmine.util.argsToArray(arguments);
|
||||
spy._stealth_stubbings || (spy._stealth_stubbings = []);
|
||||
whatToDoWhenTheSpyGetsCalled(spy);
|
||||
return stubChainer(spy, "args", ifThis);
|
||||
};
|
||||
stubChainer = function(spy, type, ifThis) {
|
||||
var addStubbing;
|
||||
addStubbing = function(satisfaction) {
|
||||
return function(thenThat) {
|
||||
spy._stealth_stubbings.unshift({
|
||||
type: type,
|
||||
ifThis: ifThis,
|
||||
satisfaction: satisfaction,
|
||||
thenThat: thenThat
|
||||
});
|
||||
return spy;
|
||||
};
|
||||
};
|
||||
return {
|
||||
thenReturn: addStubbing("return"),
|
||||
thenCallFake: addStubbing("callFake")
|
||||
};
|
||||
};
|
||||
jasmine.Spy.prototype.mostRecentCallThat = function(callThat, context) {
|
||||
var i;
|
||||
i = this.calls.length - 1;
|
||||
while (i >= 0) {
|
||||
if (callThat.call(context || this, this.calls[i]) === true) {
|
||||
return this.calls[i];
|
||||
}
|
||||
i--;
|
||||
}
|
||||
};
|
||||
jasmine.Matchers.ArgThat = (function(_super) {
|
||||
__extends(ArgThat, _super);
|
||||
|
||||
function ArgThat(matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
ArgThat.prototype.jasmineMatches = function(actual) {
|
||||
return this.matcher(actual);
|
||||
};
|
||||
|
||||
return ArgThat;
|
||||
|
||||
})(jasmine.Matchers.Any);
|
||||
jasmine.Matchers.ArgThat.prototype.matches = jasmine.Matchers.ArgThat.prototype.jasmineMatches;
|
||||
jasmine.argThat = function(expected) {
|
||||
return new jasmine.Matchers.ArgThat(expected);
|
||||
};
|
||||
jasmine.Matchers.Capture = (function(_super) {
|
||||
__extends(Capture, _super);
|
||||
|
||||
function Capture(captor) {
|
||||
this.captor = captor;
|
||||
}
|
||||
|
||||
Capture.prototype.jasmineMatches = function(actual) {
|
||||
this.captor.value = actual;
|
||||
return true;
|
||||
};
|
||||
|
||||
return Capture;
|
||||
|
||||
})(jasmine.Matchers.Any);
|
||||
jasmine.Matchers.Capture.prototype.matches = jasmine.Matchers.Capture.prototype.jasmineMatches;
|
||||
Captor = (function() {
|
||||
function Captor() {}
|
||||
|
||||
Captor.prototype.capture = function() {
|
||||
return new jasmine.Matchers.Capture(this);
|
||||
};
|
||||
|
||||
return Captor;
|
||||
|
||||
})();
|
||||
return jasmine.captor = function() {
|
||||
return new Captor();
|
||||
};
|
||||
})();
|
||||
|
||||
}).call(this);
|
||||
0
frontend/tasks/.keep
Normal file
0
frontend/tasks/.keep
Normal file
0
frontend/vendor/css/.keep
vendored
Normal file
0
frontend/vendor/css/.keep
vendored
Normal file
0
frontend/vendor/img/.keep
vendored
Normal file
0
frontend/vendor/img/.keep
vendored
Normal file
10
frontend/vendor/js/devise-min.js
vendored
Normal file
10
frontend/vendor/js/devise-min.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// AngularDevise
|
||||
// -------------------
|
||||
// v1.2.1
|
||||
//
|
||||
// Copyright (c)2016 Justin Ridgewell
|
||||
// Distributed under MIT license
|
||||
//
|
||||
// https://github.com/cloudspace/angular_devise
|
||||
|
||||
!function(a){"use strict";var b=a.module("Devise",[]);b.provider("AuthIntercept",function(){var a=!1;this.interceptAuth=function(b){return a=!!b||void 0===b,this},this.$get=["$rootScope","$q",function(b,c){return{responseError:function(d){var e=d.config.interceptAuth;if(e=!!e||a&&void 0===e,e&&401===d.status){var f=c.defer();return b.$broadcast("devise:unauthorized",d,f),f.reject(d),f.promise}return c.reject(d)}}}]}).config(["$httpProvider",function(a){a.interceptors.push("AuthIntercept")}]),b.provider("Auth",function(){function b(b,c,d){var h={method:f[b].toLowerCase(),url:e[b]};return c&&(g?(h.data={},h.data[g]=c):h.data=c),a.extend(h,d),h}function c(b,c){a.forEach(b,function(a,d){this[d+c]=function(a){return void 0===a?b[d]:(b[d]=a,this)}},this)}function d(a){return function(){return a}}var e={login:"/users/sign_in.json",logout:"/users/sign_out.json",register:"/users.json",sendResetPasswordInstructions:"/users/password.json",resetPassword:"/users/password.json"},f={login:"POST",logout:"DELETE",register:"POST",sendResetPasswordInstructions:"POST",resetPassword:"PUT"},g="user",h=function(a){return a.data};c.call(this,f,"Method"),c.call(this,e,"Path"),this.resourceName=function(a){return void 0===a?g:(g=a,this)},this.parse=function(a){return"function"!=typeof a?h:(h=a,this)},this.$get=["$q","$http","$rootScope",function(a,c,e){function f(a){return j._currentUser=a,a}function g(){f(null),j._promise=null}function i(a){return function(b){return e.$broadcast("devise:"+a,b),b}}var j={_currentUser:null,parse:h,_promise:null,reset:function(){g(),j.currentUser()},login:function(a,d){var e=arguments.length>0,g=j.isAuthenticated();return a=a||{},c(b("login",a,d)).then(j.parse).then(f).then(function(a){return e&&!g?i("new-session")(a):a}).then(i("login"))},logout:function(a){var e=d(j._currentUser);return c(b("logout",void 0,a)).then(g).then(e).then(i("logout"))},register:function(a,d){return a=a||{},c(b("register",a,d)).then(j.parse).then(f).then(i("new-registration"))},sendResetPasswordInstructions:function(a){return a=a||{},c(b("sendResetPasswordInstructions",a)).then(j.parse).then(i("send-reset-password-instructions-successfully"))},resetPassword:function(a){return a=a||{},c(b("resetPassword",a)).then(j.parse).then(f).then(i("reset-password-successfully"))},currentUser:function(){return j.isAuthenticated()?a.when(j._currentUser):(null===j._promise&&(j._promise=j.login()),j._promise)},isAuthenticated:function(){return!!j._currentUser}};return j}]})}(angular);
|
||||
1343
frontend/vendor/js/underscore.js
vendored
Normal file
1343
frontend/vendor/js/underscore.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
0
frontend/vendor/static/.keep
vendored
Normal file
0
frontend/vendor/static/.keep
vendored
Normal file
@@ -3,7 +3,7 @@ FROM ruby:2.3.0
|
||||
RUN apt-get update
|
||||
|
||||
RUN apt-get install -y build-essential
|
||||
RUN apt-get install -y nodejs sqlite3
|
||||
RUN apt-get install -y nodejs-legacy nodejs sqlite3 npm
|
||||
|
||||
ENV WRESTLINGDEV_SECRET_KEY_BASE 077cdbef5c2ccf22543fb17a67339f234306b7fa2e1e4463d851c444c10a5611829a2290b253da78339427f131571fac9a42c83d960b2d25ecc10a4a0a7ce1a2
|
||||
ENV WRESTLINGDEV_DEVISE_SECRET_KEY 2f29d49db6704377ba263f7cb9db085b386bcb301c0cd501126a674686ab1a109754071165b08cd72af03cec4642a4dd04361c994462254dd5d85e9594e8b9aa
|
||||
@@ -13,8 +13,13 @@ ADD Gemfile* /tmp/
|
||||
WORKDIR /tmp
|
||||
RUN bundle install --without production
|
||||
|
||||
RUN npm install -g lineman
|
||||
|
||||
RUN mkdir /rails
|
||||
WORKDIR /rails
|
||||
|
||||
ADD . /rails
|
||||
|
||||
VOLUME ["/rails"]
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
@@ -4,7 +4,7 @@ FROM ruby:2.3.0
|
||||
RUN apt-get update
|
||||
RUN apt-get -y upgrade
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential libssl-dev libyaml-dev libreadline-dev openssl curl git-core zlib1g-dev bison libxml2-dev libxslt1-dev libcurl4-openssl-dev libsqlite3-dev sqlite3 wget apache2 apt-transport-https nodejs mysql-client postfix
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential libssl-dev libyaml-dev libreadline-dev openssl curl git-core zlib1g-dev bison libxml2-dev libxslt1-dev libcurl4-openssl-dev libsqlite3-dev sqlite3 wget apache2 apt-transport-https nodejs nodejs-legacy npm mysql-client postfix
|
||||
|
||||
#New Relic
|
||||
#RUN echo deb http://apt.newrelic.com/debian/ newrelic non-free >> /etc/apt/sources.list.d/newrelic.list
|
||||
@@ -50,6 +50,12 @@ COPY Gemfile Gemfile
|
||||
COPY Gemfile.lock Gemfile.lock
|
||||
RUN bundle install --without test
|
||||
|
||||
#Cache node_modules
|
||||
WORKDIR /tmp
|
||||
COPY frontend/package.json package.json
|
||||
RUN npm install
|
||||
RUN npm install lineman
|
||||
RUN npm install -g lineman
|
||||
|
||||
# Copy site into place.
|
||||
RUN rm -rf /var/www
|
||||
@@ -59,9 +65,13 @@ ENV WRESTLINGDEV_SECRET_KEY_BASE 077cdbef5c2ccf22543fb17a67339f234306b7fa2e1e446
|
||||
ENV WRESTLINGDEV_DEVISE_SECRET_KEY 2f29d49db6704377ba263f7cb9db085b386bcb301c0cd501126a674686ab1a109754071165b08cd72af03cec4642a4dd04361c994462254dd5d85e9594e8b9aa
|
||||
WORKDIR /var/www/
|
||||
ADD . /var/www/
|
||||
|
||||
#Copy node_modules to /var/www
|
||||
RUN mv /tmp/node_modules /var/www/frontend/node_modules
|
||||
|
||||
#RUN RAILS_ENV=production bundle exec rake db:migrate
|
||||
RUN RAILS_ENV=production bundle exec rake assets:precompile
|
||||
|
||||
#RUN cp /var/www/frontend/dist/*.html /var/www/public/
|
||||
|
||||
# Update the default apache site with the config we created.
|
||||
RUN rm /etc/apache2/sites-enabled/000-default.conf
|
||||
@@ -73,8 +83,7 @@ RUN a2ensite default-ssl.conf
|
||||
RUN echo PassengerMaxPoolSize 3 >> /etc/apache2/apache2.conf
|
||||
RUN echo PassengerMinInstances 3 >> /etc/apache2/apache2.conf
|
||||
RUN echo PassengerPreStart *:443 >> /etc/apache2/apache2.conf
|
||||
|
||||
|
||||
|
||||
|
||||
# By default, simply start apache.
|
||||
CMD /usr/sbin/apache2ctl -D FOREGROUND
|
||||
|
||||
2
run-all-tests.sh
Executable file
2
run-all-tests.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
rake db:migrate RAILS_ENV=test
|
||||
rake test
|
||||
7
test/controllers/api_controller_test.rb
Normal file
7
test/controllers/api_controller_test.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class ApiControllerTest < ActionController::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
@@ -5,12 +5,12 @@ class MatchesControllerTest < ActionController::TestCase
|
||||
|
||||
setup do
|
||||
@tournament = Tournament.find(1)
|
||||
@tournament.generateMatchups
|
||||
@match = @tournament.matches.first
|
||||
# @tournament.generateMatchups
|
||||
@match = Match.where("tournament_id = ? and mat_id = ?",1,1).first
|
||||
end
|
||||
|
||||
def post_update
|
||||
patch :update, id: @match.id, match: {w1: @match.w1, w2: @match.w2}
|
||||
patch :update, id: @match.id, match: {tournament_id: 1, mat_id: 1}
|
||||
end
|
||||
|
||||
def get_edit
|
||||
|
||||
@@ -5,7 +5,7 @@ class MatsControllerTest < ActionController::TestCase
|
||||
|
||||
setup do
|
||||
@tournament = Tournament.find(1)
|
||||
@tournament.generateMatchups
|
||||
# @tournament.generateMatchups
|
||||
@mat = mats(:one)
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ class SchoolsControllerTest < ActionController::TestCase
|
||||
|
||||
setup do
|
||||
@tournament = Tournament.find(1)
|
||||
@tournament.generateMatchups
|
||||
# @tournament.generateMatchups
|
||||
@school = @tournament.schools.first
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ class StaticPagesControllerTest < ActionController::TestCase
|
||||
|
||||
setup do
|
||||
@tournament = Tournament.find(1)
|
||||
@tournament.generateMatchups
|
||||
# @tournament.generateMatchups
|
||||
@school = @tournament.schools.first
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ include Devise::TestHelpers
|
||||
|
||||
setup do
|
||||
@tournament = Tournament.find(1)
|
||||
@tournament.generateMatchups
|
||||
# @tournament.generateMatchups
|
||||
@school = @tournament.schools.first
|
||||
@wrestlers = @tournament.weights.first.wrestlers
|
||||
@adjust = Teampointadjust.find(1)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user