This commit is contained in:
Scott Erickson 2014-01-12 11:58:24 -08:00
commit 6d60221668
16 changed files with 446 additions and 284 deletions

4
.gitignore vendored
View file

@ -71,5 +71,7 @@ FLOOBITS_README.md
# mongodb # mongodb
db/ db/
bin/node/
bin/mongo/
### If you add something here, copy it to the end of .npmignore, too. ### ### If you add something here, copy it to the end of .npmignore, too. ###

View file

@ -86,6 +86,9 @@ dump.rdb
# Mongo # Mongo
mongo/ mongo/
bin/node/
bin/mongo/
# Karma coverage # Karma coverage
coverage/ coverage/

13
.travis.yml Normal file
View file

@ -0,0 +1,13 @@
nguage: node_js
node_js:
- 0.10
before_script:
- "npm install"
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- "./node_modules/.bin/bower install"
- "gem install sass"
- "./node_modules/.bin/brunch b"
script:
- "./node_modules/.bin/karma start --browsers Firefox --single-run"

View file

@ -2,6 +2,7 @@ CodeCombat
========== ==========
![](https://dl.dropboxusercontent.com/u/138899/GitHub%20Wikis/readme_00.png) ![](https://dl.dropboxusercontent.com/u/138899/GitHub%20Wikis/readme_00.png)
[![Build Status](https://travis-ci.org/codecombat/codecombat.png?branch=master)](https://travis-ci.org/codecombat/codecombat)
CodeCombat is a multiplayer programming game for learning how to code. **See the [Archmage developer wiki](https://github.com/codecombat/codecombat/wiki) for a dev setup guide, extensive documentation, and much more.** CodeCombat is a multiplayer programming game for learning how to code. **See the [Archmage developer wiki](https://github.com/codecombat/codecombat/wiki) for a dev setup guide, extensive documentation, and much more.**

View file

@ -49,3 +49,4 @@ module.exports =
uk: require './uk' # українська мова, Ukranian uk: require './uk' # українська мова, Ukranian
hi: require './hi' # ि, Hindi hi: require './hi' # ि, Hindi
ur: require './ur' # اُردُو, Urdu ur: require './ur' # اُردُو, Urdu
'ms-BA': require './ms-BA' # Bahasa Melayu, Bahasa Malaysia

43
app/locale/ms-BA.coffee Normal file
View file

@ -0,0 +1,43 @@
module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa Malaysia", translation:
modal:
close: "Tutup"
okay: "Ok"
not_found:
page_not_found: "Halaman tidak ditemui"
nav:
# Header
sign_up: "Buat Akaun"
log_in: "Log Masuk"
log_out: "Log Keluar"
play: "bermain"
# Footer
home: "Halaman"
contribute: "Sumbangan"
legal: "Undang- undang"
about: "Tentang"
contact: "Hubungi"
forms:
name: "Nama"
email: "Emel"
message: "Mesej"
cancel: "Batal"
login:
log_in: "Log Masuk"
sign_up: "buat akaun baru"
or: ", atau "
recover: "perbaharui akaun"
signup:
description: "Ianya percuma. Hanya berberapa langkah sahaja:"
email_announcements: "Terima pengesahan melalui Emel"
coppa: "13+ atau bukan- USA"
coppa_why: "(Kenapa?)"
creating: "Membuat Akaun..."
sign_up: "Daftar"
or: "atau "
log_in: "log masuk"

View file

@ -21,7 +21,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
admin: "超级管理员" admin: "超级管理员"
# Footer # Footer
home: "首页" home: "首页"
contribute: "" contribute: "贡献"
legal: "法律" legal: "法律"
about: "关于" about: "关于"
contact: "联系我们" contact: "联系我们"
@ -162,15 +162,15 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
multiplayer_title: "多人游戏设置" multiplayer_title: "多人游戏设置"
multiplayer_link_description: "把这个链接告诉小伙伴们,一起玩吧。" multiplayer_link_description: "把这个链接告诉小伙伴们,一起玩吧。"
multiplayer_hint_label: "提示:" multiplayer_hint_label: "提示:"
multiplayer_hint: " 点击全选,然后按 ⌘-C 或 Ctrl-C 复制链接。" multiplayer_hint: " 点击全选,然后按 Apple-C苹果电脑或 Ctrl-C 复制链接。"
multiplayer_coming_soon: "多人游戏的更多特性!" multiplayer_coming_soon: "多人游戏的更多特性!"
guide_title: "指南" guide_title: "指南"
tome_minion_spells: "小助手的法术" tome_minion_spells: "助手的咒语"
tome_read_only_spells: "只读的法术" tome_read_only_spells: "只读的咒语"
tome_other_units: "其他单元" tome_other_units: "其他单元"
tome_cast_button_castable: "投掷" tome_cast_button_castable: "发动"
tome_cast_button_casting: "投掷" tome_cast_button_casting: "发动"
tome_cast_button_cast: "施法" tome_cast_button_cast: "发动咒语"
tome_autocast_delay: "自动施法延迟" tome_autocast_delay: "自动施法延迟"
tome_autocast_1: "1 秒" tome_autocast_1: "1 秒"
tome_autocast_3: "3 秒" tome_autocast_3: "3 秒"

View file

@ -2,182 +2,181 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese
common: common:
loading: "Loading..." loading: "Loading..."
# modal: modal:
# close: "Close" close: "關閉"
# okay: "Okay" okay: ""
#
# not_found: not_found:
# page_not_found: "Page not found" page_not_found: "找不到網頁"
#
# nav: nav:
# # Header # Header
# sign_up: "Create Account" sign_up: "註冊"
# log_in: "Log In" log_in: "登錄"
# log_out: "Log Out" log_out: "退出"
# play: "Play" play: ""
# editor: "Editor" editor: "編輯"
# blog: "Blog" blog: "博客"
# forum: "Forum" forum: "論壇"
# admin: "Admin" admin: "超級管理員"
# # Footer # Footer
# home: "Home" home: "首頁"
# contribute: "Contribute" contribute: "貢獻"
# legal: "Legal" legal: "法律"
# about: "About" about: "關於"
# contact: "Contact" contact: "聯繫我們"
# twitter_follow: "Follow" twitter_follow: "關注"
#
# forms: forms:
# name: "Name" name: "名字"
# email: "Email" email: "郵箱"
# message: "Message" message: "留言"
# cancel: "Cancel" cancel: "退出"
#
# login: login:
# log_in: "Log In" log_in: "登錄"
# sign_up: "create new account" sign_up: "註冊"
# or: ", or " or: ",或"
# recover: "recover account" recover: "找回帳戶"
#
# signup: signup:
# description: "It's free. Just need a couple things and you'll be good to go:" description: "這是免費的。超簡單的喲:"
# email_announcements: "Receive announcements by email" email_announcements: "通過郵件接收通知"
# coppa: "13+ or non-USA" # coppa: ""
# coppa_why: "(Why?)" coppa_why: "爲什麽?"
# creating: "Creating Account..." creating: "帳戶創建中..."
# sign_up: "Sign Up" sign_up: "註冊"
# or: "or " or: ""
# log_in: "log in with password" log_in: "登錄"
#
# home: home:
# slogan: "Learn to Code JavaScript by Playing a Game" slogan: "通過玩遊戲學習Javascript 腳本語言"
# no_ie: "CodeCombat does not run in IE8 or older. Sorry!" no_ie: "抱歉Internet Explorer 9 等舊的瀏覽器打不開此網站"
# no_mobile: "CodeCombat wasn't designed for mobile devices and may not work!" no_mobile: "CodeCombat 不是針對手機設備設計的,所以可能會出問題!"
# play: "Play" play: ""
#
play: play:
choose_your_level: "擇你的水平" choose_your_level: "取難度"
# adventurer_prefix: "You can jump to any level below, or discuss the levels on " adventurer_prefix: "你可以選擇以下任意關卡,或者討論以上的關卡 "
# adventurer_forum: "the Adventurer forum" adventurer_forum: "冒險家論壇"
# adventurer_suffix: "." adventurer_suffix: "."
# campaign_beginner: "Beginner Campaign" campaign_beginner: "新手作戰"
# campaign_beginner_description: "... in which you learn the wizardry of programming." campaign_beginner_description: "...在這裡可以學到編程技巧。"
# campaign_dev: "Random Harder Levels" campaign_dev: "隨機關卡"
# campaign_dev_description: "... in which you learn the interface while doing something a little harder." campaign_dev_description: "...在這裡你可以學到做一些複雜功能的接口。"
# campaign_multiplayer: "Multiplayer Arenas" campaign_multiplayer: "多人競技場"
# campaign_multiplayer_description: "... in which you code head-to-head against other players." campaign_multiplayer_description: "...在這裡你可以和其他玩家們進行代碼近戰。"
# campaign_player_created: "Player-Created" campaign_player_created: "已創建的玩家"
# campaign_player_created_description: "... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>." campaign_player_created_description: "...在這裡你可以與你的小夥伴的創造力戰鬥 <a href=\"/contribute#artisan\">技術指導</a>."
# level_difficulty: "Difficulty: " level_difficulty: "難度"
#
# contact: contact:
# contact_us: "Contact CodeCombat" contact_us: "聯繫我們"
# welcome: "Good to hear from you! Use this form to send us email." welcome: "很高興收到你的信!用這個表格給我們發電郵。 "
# contribute_prefix: "If you're interested in contributing, check out our " contribute_prefix: "如果你想貢獻代碼,請看 "
# contribute_page: "contribute page" contribute_page: "貢獻代碼頁面"
# contribute_suffix: "!" contribute_suffix: ""
# forum_prefix: "For anything public, please try " forum_prefix: "對於任何公共部份,放手去做吧 "
# forum_page: "our forum" forum_page: "我們的論壇"
# forum_suffix: " instead." forum_suffix: "代替。"
# sending: "Sending..." sending: "發送中。。。"
# send: "Send Feedback" send: "意見反饋"
#
diplomat_suggestion: diplomat_suggestion:
# title: "Help translate CodeCombat!" title: "幫我們翻譯CodeCombat"
# sub_heading: "We need your language skills." sub_heading: "我們需要您的語言技能"
pitch_body: "We develop CodeCombat in English, but we already have players all over the world. Many of them want to play in Chinese (Traditional) but don't speak English, so if you can speak both, please consider signing up to be a Diplomat and help translate both the CodeCombat website and all the levels into Chinese (Traditional)." pitch_body: "我們開發了CodeCombat的英文版但是現在我們的玩家遍佈全球。很多人想玩中文繁体版的卻不會說英文所以如果你中英文都會請考慮一下參加我們的翻譯工作幫忙把 CodeCombat 網站還有所有的關卡翻譯成中文(繁体)。"
missing_translations: "Until we can translate everything into Chinese (Traditional), you'll see English when Chinese (Traditional) isn't available." # missing_translations: ""
# learn_more: "Learn more about being a Diplomat" # learn_more: ""
# subscribe_as_diplomat: "Subscribe as a Diplomat" # subscribe_as_diplomat: ""
#
# account_settings: account_settings:
# title: "Account Settings" title: "帳戶設置"
# not_logged_in: "Log in or create an account to change your settings." not_logged_in: "登錄或創建一個帳戶來修改設置。"
# autosave: "Changes Save Automatically" autosave: "自動保存修改"
# me_tab: "Me" me_tab: ""
# picture_tab: "Picture" picture_tab: "圖片"
# wizard_tab: "Wizard" wizard_tab: "巫師"
# password_tab: "Password" password_tab: "密碼"
# emails_tab: "Emails" emails_tab: "郵件"
# language_tab: "Language" gravatar_select: "選擇使用 Gravatar 照片"
# gravatar_select: "Select which Gravatar photo to use" gravatar_add_photos: "添加小圖和照片到一个 Gravatar 帳戶供你選擇。"
# gravatar_add_photos: "Add thumbnails and photos to a Gravatar account for your email to choose an image." gravatar_add_more_photos: "添加更多照片到你的 Gravatar 帳戶并查看。"
# gravatar_add_more_photos: "Add more photos to your Gravatar account to access them here." wizard_color: "巫師 衣服 顏色"
# wizard_color: "Wizard Clothes Color" new_password: "新密碼"
# new_password: "New Password" new_password_verify: "核實"
# new_password_verify: "Verify" email_subscriptions: "郵箱驗證"
# email_subscriptions: "Email Subscriptions" email_announcements: "通知"
# email_announcements: "Announcements" email_announcements_description: "接收關於 CodeCombat 最近的新聞和發展的郵件。"
# email_announcements_description: "Get emails on the latest news and developments at CodeCombat." # contributor_emails: ""
# contributor_emails: "Contributor Class Emails" contribute_prefix: "我們在尋找志同道合的人!請到 "
# contribute_prefix: "We're looking for people to join our party! Check out the " contribute_page: "貢獻頁面"
# contribute_page: "contribute page" contribute_suffix: " 查看更多信息。"
# contribute_suffix: " to find out more." email_toggle: "切換所有"
# email_toggle: "Toggle All" saving: "保存中..."
# language: "Language" error_saving: "保存時出錯"
# saving: "Saving..." saved: "保存修改"
# error_saving: "Error Saving" password_mismatch: "密碼不匹配。"
# saved: "Changes Saved"
# password_mismatch: "Password does not match." account_profile:
# edit_settings: "編輯設置"
# account_profile: profile_for_prefix: "關於TA的基本資料"
# edit_settings: "Edit Settings" profile_for_suffix: ""
# profile_for_prefix: "Profile for " profile: "基本資料"
# profile_for_suffix: "" user_not_found: "沒有找到用戶。檢查URL"
# profile: "Profile" gravatar_not_found_mine: "我們找不到TA的基本資料"
# user_not_found: "No user found. Check the URL?" gravatar_not_found_email_suffix: "."
# gravatar_not_found_mine: "We couldn't find your profile associated with:" gravatar_signup_prefix: "去註冊 "
# gravatar_signup_prefix: "Sign up at " gravatar_signup_suffix: " 去設置!"
# gravatar_signup_suffix: " to get set up!" gravatar_not_found_other: "哎呦,沒有與這個人的郵箱相關的資料。"
# gravatar_not_found_other: "Alas, there's no profile associated with this person's email address." gravatar_contact: "聯繫"
# gravatar_contact: "Contact" gravatar_websites: "網站"
# gravatar_websites: "Websites" # gravatar_accounts: ""
# gravatar_accounts: "As Seen On" gravatar_profile_link: "完善 Gravatar 資料"
# gravatar_profile_link: "Full Gravatar Profile"
# play_level:
# play_level: level_load_error: "關卡不能載入。"
# level_load_error: "Level could not be loaded." done: "完成"
# done: "Done" grid: "格子"
# grid: "Grid" customize_wizard: "自定義巫師"
# customize_wizard: "Customize Wizard" home: "主頁"
# home: "Home" guide: "指南"
# guide: "Guide" multiplayer: "多人遊戲"
# multiplayer: "Multiplayer" restart: "重新開始"
# restart: "Restart" goals: "目標"
# goals: "Goals" action_timeline: "行動時間軸"
# action_timeline: "Action Timeline" click_to_select: "點擊選擇一個單元。"
# click_to_select: "Click on a unit to select it." reload_title: "重載所有代碼?"
# reload_title: "Reload All Code?" reload_really: "確定重載這一關,返回開始處?"
# reload_really: "Are you sure you want to reload this level back to the beginning?" reload_confirm: "重載所有"
# reload_confirm: "Reload All" victory_title_prefix: ""
# victory_title_prefix: "" victory_title_suffix: " 完成"
# victory_title_suffix: " Complete" victory_sign_up: "保存進度"
# victory_sign_up: "Sign Up for Updates" victory_sign_up_poke: "想保存你的代碼?創建一個免費帳戶吧!"
# victory_sign_up_poke: "Want to get the latest news by email? Create a free account and we'll keep you posted!" victory_rate_the_level: "評估關卡: "
# victory_rate_the_level: "Rate the level: " victory_play_next_level: "下一關"
# victory_play_next_level: "Play Next Level" victory_go_home: "返回主頁"
# victory_go_home: "Go Home" victory_review: "給我們反饋!"
# victory_review: "Tell us more!" victory_hour_of_code_done: "你完成了嗎?"
# victory_hour_of_code_done: "Are You Done?" victory_hour_of_code_done_yes: "是的,我完成了我的代碼!"
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code!" multiplayer_title: "多人遊戲設置"
# multiplayer_title: "Multiplayer Settings" multiplayer_link_description: "把這個鏈接告訴小夥伴們,一起玩吧。"
# multiplayer_link_description: "Give this link to anyone to have them join you." multiplayer_hint_label: "提示:"
# multiplayer_hint_label: "Hint:" multiplayer_hint: " 點擊全選,然後按 Apple-C苹果電腦或 Ctrl-C 複製鏈接。"
# multiplayer_hint: " Click the link to select all, then press Apple-C or Ctrl-C to copy the link." multiplayer_coming_soon: "多人遊戲的更多特性!"
# multiplayer_coming_soon: "More multiplayer features to come!" guide_title: "指南"
# guide_title: "Guide" tome_minion_spells: "助手的咒語"
# tome_minion_spells: "Your Minions' Spells" tome_read_only_spells: "只讀的咒語"
# tome_read_only_spells: "Read-Only Spells" tome_other_units: "其他單元"
# tome_other_units: "Other Units" tome_cast_button_castable: "發動"
# tome_cast_button_castable: "Cast" tome_cast_button_casting: "發動中"
# tome_cast_button_casting: "Casting" tome_cast_button_cast: "咒語"
# tome_cast_button_cast: "Spell Cast" tome_autocast_delay: "自動施法延遲"
# tome_autocast_delay: "Autocast Delay" tome_autocast_1: "1 秒"
# tome_autocast_1: "1 second" tome_autocast_3: "3 秒"
# tome_autocast_3: "3 seconds" tome_autocast_5: "5 秒"
# tome_autocast_5: "5 seconds" tome_autocast_manual: "手動手动"
# tome_autocast_manual: "Manual" tome_select_spell: "選擇一個法術"
# tome_select_spell: "Select a Spell" tome_select_a_thang: "選擇人物來 "
# tome_select_a_thang: "Select Someone for " tome_available_spells: "可用的法術"
# tome_available_spells: "Available Spells" hud_continue: "繼續 (按 shift-空格)"
# hud_continue: "Continue (press shift-space)"

View file

@ -1,9 +1,6 @@
extends /templates/modal/save_version extends /templates/modal/save_version
block modal-header-content block modal-body-content
h3(data-i18n="editor.save_view_title") Save New Version
block content
h3= "Level: " + level.get('name') + " - " + (levelNeedsSave ? "Modified" : "Not Modified") h3= "Level: " + level.get('name') + " - " + (levelNeedsSave ? "Modified" : "Not Modified")
if levelNeedsSave if levelNeedsSave
form#save-level-form.form-horizontal form#save-level-form.form-horizontal

View file

@ -1,11 +1,9 @@
block modal-header-content extends /templates/modal/modal_base
h3(data-i18n="contact.contact_modal_title") Contact
.modal-header block modal-header-content
.button.close(type="button", data-dismiss="modal", aria-hidden="true") &times;
h3(data-i18n="contact.contact_us") Contact CodeCombat... h3(data-i18n="contact.contact_us") Contact CodeCombat...
.modal-body block modal-body-content
p p
span(data-i18n="contact.welcome") Good to hear from you! Use this form to send us email. span(data-i18n="contact.welcome") Good to hear from you! Use this form to send us email.
span(data-i18n="contact.contribute_prefix") If you're interested in contributing, check out our span(data-i18n="contact.contribute_prefix") If you're interested in contributing, check out our
@ -25,7 +23,7 @@ block modal-header-content
.controls .controls
textarea#contact-message.input-block-level(name="message", rows=8) textarea#contact-message.input-block-level(name="message", rows=8)
.modal-footer block modal-footer-content
span.sending-indicator.pull-left.hide(data-i18n="contact.sending") Sending... span.sending-indicator.pull-left.hide(data-i18n="contact.sending") Sending...
a(href='#', data-dismiss="modal", aria-hidden="true", data-i18n="forms.cancel").btn Cancel a(href='#', data-dismiss="modal", aria-hidden="true", data-i18n="forms.cancel").btn Cancel
button.btn.btn-primary#contact-submit-button(data-i18n="contact.send") Send Feedback button.btn.btn-primary#contact-submit-button(data-i18n="contact.send") Send Feedback

View file

@ -1,6 +1,9 @@
.modal-header extends /templates/modal/modal_base
block modal-header-content
h3(data-i18n="save.save_version_title") Save New Version h3(data-i18n="save.save_version_title") Save New Version
.modal-body
block modal-body-content
form.form-horizontal form.form-horizontal
.control-group .control-group
label.control-label(for="commitMessage") Commit Message label.control-label(for="commitMessage") Commit Message
@ -11,7 +14,11 @@
.controls .controls
input#major-version.input-large(name="version-is-major", type="checkbox") input#major-version.input-large(name="version-is-major", type="checkbox")
span.help-block span.help-block
.modal-footer
block modal-body-wait-content
h3 Saving...
block modal-footer-content
#accept-cla-wrapper.alert.alert-info #accept-cla-wrapper.alert.alert-info
| To save changes, first you must agree to | To save changes, first you must agree to
strong#cla-link our CLA strong#cla-link our CLA
@ -20,7 +27,3 @@
button.btn(data-dismiss="modal") Cancel button.btn(data-dismiss="modal") Cancel
button.btn.btn-primary#save-version-button Save button.btn.btn-primary#save-version-button Save
.modal-body.wait.hide
h3 Saving...
.progress.progress-striped.active
.bar

View file

@ -22,6 +22,7 @@ contactSchema =
module.exports = class ContactView extends View module.exports = class ContactView extends View
id: "contact-modal" id: "contact-modal"
template: template template: template
closeButton: true
events: events:
"click #contact-submit-button": "contact" "click #contact-submit-button": "contact"

View file

@ -1,83 +1,83 @@
// Testacular configuration // Testacular configuration
// Generated on Fri Feb 15 2013 18:38:33 GMT-0500 (EST) // Generated on Fri Feb 15 2013 18:38:33 GMT-0500 (EST)
module.exports = function(config) {
// base path, that will be used to resolve files and exclude config.set({
basePath = '.'; // base path, that will be used to resolve files and exclude
basePath : '',
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files : [
'public/javascripts/vendor.js',
'public/lib/ace/ace.js',
'public/javascripts/app.js',
'test/app/**/*.coffee'
],
preprocessors : {
'**/*.coffee': 'coffee',
'**/javascripts/app.js': 'coverage'
},
// list of files to exclude
exclude : [],
// test results reporter to use
// possible values: 'dots', 'progress', 'junit'
reporters : ['progress', 'coverage'],
// web server port
port : 9050,
// cli runner port
runnerPort : 9051,
// enable / disable colors in the output (reporters and logs)
colors : true,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel : config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch : true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers : ['Chrome'],
// list of files / patterns to load in the browser // If browser does not capture in given timeout [ms], kill it
files = [ captureTimeout : 5000,
JASMINE,
JASMINE_ADAPTER,
'public/javascripts/vendor.js',
'public/lib/ace/ace.js',
'public/javascripts/app.js',
'test/app/**/*.coffee'
];
// list of files to exclude // Continuous Integration mode
exclude = [ // if true, it capture browsers, run tests and executing
singleRun : false,
];
coverageReporter : {
type : 'html',
dir : 'coverage/'
},
// test results reporter to use plugins : [
// possible values: 'dots', 'progress', 'junit' 'karma-jasmine',
reporters = ['progress', 'coverage']; 'karma-chrome-launcher',
//reporters = ['progress']; 'karma-phantomjs-launcher',
'karma-coffee-preprocessor',
'karma-coverage',
'karma-firefox-launcher'
]
});
// web server port
port = 9050;
// cli runner port
runnerPort = 9051;
// enable / disable colors in the output (reporters and logs)
colors = true;
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel = LOG_INFO;
// enable / disable watching file and executing tests whenever any file changes
autoWatch = true;
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers = ['Chrome'];
// If browser does not capture in given timeout [ms], kill it
captureTimeout = 5000;
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun = false;
preprocessors = {
'**/*.coffee': 'coffee',
'**/javascripts/app.js': 'coverage'
};
coverageReporter = {
type : 'html',
dir : 'coverage/'
}; };

View file

@ -26,7 +26,7 @@
], ],
"scripts": { "scripts": {
"start": "node ./index.js", "start": "node ./index.js",
"test": "brunch test", "test": "./node_modules/.bin/karma start",
"predeploy": "echo Starting deployment--hold onto your butts.; echo Skipping brunch build --production", "predeploy": "echo Starting deployment--hold onto your butts.; echo Skipping brunch build --production",
"postdeploy": "echo Deployed. Unclench." "postdeploy": "echo Deployed. Unclench."
}, },
@ -72,13 +72,23 @@
"clean-css-brunch": "> 1.0 < 1.8", "clean-css-brunch": "> 1.0 < 1.8",
"auto-reload-brunch": "> 1.0 < 1.8", "auto-reload-brunch": "> 1.0 < 1.8",
"brunch": "~1.7.4", "brunch": "~1.7.4",
"karma": "~0.8.0",
"jasmine-node": "", "jasmine-node": "",
"nodemon": "0.7.5", "nodemon": "0.7.5",
"marked": "0.2.x", "marked": "0.2.x",
"telepath-brunch": "https://github.com/nwinter/telepath-brunch/tarball/master", "telepath-brunch": "https://github.com/nwinter/telepath-brunch/tarball/master",
"bower": "~1.2.8", "bower": "~1.2.8",
"bless-brunch": "~1.6.1" "bless-brunch": "~1.6.1",
"karma-script-launcher": "~0.1.0",
"karma-chrome-launcher": "~0.1.2",
"karma-firefox-launcher": "~0.1.3",
"karma-html2js-preprocessor": "~0.1.0",
"karma-coffee-preprocessor": "~0.1.2",
"karma-jasmine": "~0.1.5",
"requirejs": "~2.1.10",
"karma-requirejs": "~0.2.1",
"karma-phantomjs-launcher": "~0.1.1",
"karma": "~0.10.9",
"karma-coverage": "~0.1.4"
}, },
"license": "Copyright © 2014 CodeCombat", "license": "Copyright © 2014 CodeCombat",
"private": true, "private": true,

View file

@ -55,6 +55,7 @@ class Node(Dependency):
wants_to_upgrade = strtobool(user_input) wants_to_upgrade = strtobool(user_input)
except: except:
print u"Please enter y or n. " print u"Please enter y or n. "
user_input = raw_input()
continue continue
break break
if wants_to_upgrade: if wants_to_upgrade:

View file

@ -7,30 +7,120 @@ describe 'LevelComponent', ->
description:'Makes the unit uncontrollably bash anything bashable, using the bash system.' description:'Makes the unit uncontrollably bash anything bashable, using the bash system.'
code: 'bash();' code: 'bash();'
language: 'javascript' language: 'javascript'
official: true
permissions:simplePermissions permissions:simplePermissions
components = {} components = {}
url = getURL('/db/level.component') url = getURL('/db/level.component')
it 'clears things first', (done) -> it 'preparing test : clears things first.', (done) ->
clearModels [Level, LevelComponent], (err) -> clearModels [Level, LevelComponent], (err) ->
expect(err).toBeNull() expect(err).toBeNull()
done() done()
it 'can make a LevelComponent, without setting official.', (done) -> it 'can\'t be created by ordinary users.', (done) ->
loginJoe (joe) -> loginJoe (joe) ->
request.post {uri:url, json:component}, (err, res, body) ->
expect(res.statusCode).toBe(403)
done()
it 'can be created by an admin.', (done) ->
loginAdmin (joe) ->
request.post {uri:url, json:component}, (err, res, body) -> request.post {uri:url, json:component}, (err, res, body) ->
expect(res.statusCode).toBe(200) expect(res.statusCode).toBe(200)
expect(body.official).toBeUndefined() expect(body._id).toBeDefined()
expect(body.name).toBe(component.name)
expect(body.description).toBe(component.description)
expect(body.code).toBe(component.code)
expect(body.language).toBe(component.language)
expect(body.__v).toBe(0)
expect(body.creator).toBeDefined()
expect(body.original).toBeDefined()
expect(body.created).toBeDefined()
expect(body.version).toBeDefined()
expect(body.permissions).toBeDefined()
components[0] = body components[0] = body
done() done()
it 'can allows admins to edit the official property.', (done) -> it 'have a unique name.', (done) ->
loginAdmin (joe) ->
request.post {uri:url, json:component}, (err, res, body) ->
expect(res.statusCode).toBe(422)
done()
it 'can read by an admin.', (done) ->
loginAdmin (joe) ->
request.get {uri:url+'/'+components[0]._id}, (err, res, body) ->
expect(res.statusCode).toBe(200)
body = JSON.parse(body)
expect(body._id).toBe(components[0]._id)
done()
it 'can be read by ordinary users.', (done) ->
loginJoe (joe) ->
request.get {uri:url+'/'+components[0]._id}, (err, res, body) ->
expect(res.statusCode).toBe(200)
body = JSON.parse(body)
expect(body._id).toBe(components[0]._id)
expect(body.name).toBe(components[0].name)
expect(body.slug).toBeDefined()
expect(body.description).toBe(components[0].description)
expect(body.code).toBe(components[0].code)
expect(body.language).toBe(components[0].language)
expect(body.__v).toBe(0)
expect(body.official).toBeDefined()
expect(body.creator).toBeDefined()
expect(body.original).toBeDefined()
expect(body.created).toBeDefined()
expect(body.configSchema).toBeDefined()
expect(body.dependencies).toBeDefined()
expect(body.propertyDocumentation).toBeDefined()
expect(body.version.isLatestMajor).toBe(true)
expect(body.version.isLatestMinor).toBe(true)
expect(body.permissions).toBeDefined()
done()
it 'is unofficial by default', (done) ->
loginJoe (joe) ->
request.get {uri:url+'/'+components[0]._id}, (err, res, body) ->
expect(res.statusCode).toBe(200)
body = JSON.parse(body)
expect(body._id).toBe(components[0]._id)
expect(body.official).toBe(false)
done()
it 'has system ai by default', (done) ->
loginJoe (joe) ->
request.get {uri:url+'/'+components[0]._id}, (err, res, body) ->
expect(res.statusCode).toBe(200)
body = JSON.parse(body)
expect(body._id).toBe(components[0]._id)
expect(body.system).toBe("ai")
done()
it 'official property isn\'t editable by an ordinary user.', (done) ->
components[0].official = true
loginJoe (joe) ->
request.post {uri:url, json:components[0]}, (err, res, body) ->
expect(res.statusCode).toBe(403)
done()
it 'official property is editable by an admin.', (done) ->
components[0].official = true components[0].official = true
loginAdmin (joe) -> loginAdmin (joe) ->
request.post {uri:url, json:components[0]}, (err, res, body) -> request.post {uri:url, json:components[0]}, (err, res, body) ->
expect(body.official).toBe(true)
expect(res.statusCode).toBe(200) expect(res.statusCode).toBe(200)
done() expect(body.official).toBe(true)
expect(body.original).toBe(components[0].original)
expect(body.version.isLatestMinor).toBe(true)
expect(body.version.isLatestMajor).toBe(true)
components[1] = body
request.get {uri:url+'/'+components[0]._id}, (err, res, body) ->
expect(res.statusCode).toBe(200)
body = JSON.parse(body)
expect(body._id).toBe(components[0]._id)
expect(body.official).toBe(false)
expect(body.version.isLatestMinor).toBe(false)
expect(body.version.isLatestMajor).toBe(false)
done()