ããã«ã¡ã¯ãæè¡é¨ éçºåºç¤ã°ã«ã¼ãã®è«¸æ©ã§ãã
ã¯ãã¯ãããã§ã¯æ¨ä»ã®å¤ãã®Webä¼æ¥ã¨åãããã«ãGitHub Enterpriseã®Pull Requestã使ã£ãã³ã¼ãã¬ãã¥ã¼ãåºç¯ã«å®æ½ãã¦ãã¾ããããããã¡ã®ã³ã¼ãã¬ãã¥ã¼ã§ã¯ãã½ã¼ã¹ã³ã¼ãã®åé¢ã«ã¨ã©ã¾ããããµã¼ãã¹ã®æ©è½ã¨ãã¦é åçãã©ããããä¿å®æ§ãå«ããè¨è¨ãé©åãã¨ãã£ãè°è«ã«çºå±ãããã¨ãè¯ãããã¾ãã
ãããã¯ãããªãªãã§è©±é¡ã«ä¸ãã£ããç¾å¨æå»ãã®æ±ãããã«é¢ããè¨è¨ã®è©±ãæ¸ãã¾ãã
èæ¯
ãµã¼ãã¹ãéçºã»éå¶ãã¦ããæã ã«ã¯ãæé帯ã«ãã£ã¦åºãåããããç¹å®ã®æéã®ã¿ã«è¡¨ç¤ºãããã³ã³ãã³ããããããããã¾ãã ãã®ãã³ã«ãããã¤ãç´ãã¨ããã®ã¯ã¤ããã®ã§(ç¹ã«24:00ã«åºãªããªãã³ã³ãã³ããªã©)ãªãã¨ãããããªãã¾ãããä¸æ¹ã§æéå¼ã®ã³ã³ãã³ãã¯ãã®æã«ãªãã¾ã§ã¡ããã¨åãã¦ããã確証ãåããªãã®ã§æãã§ãã
ãã®ã¤ããããªãã¨ã軽æ¸ã§ããªããã®ãã¨èãã¾ããã
ã¤ããã®æ´ç
ããã¸ã身è¿ãªæ¦å¿µãªã®ã§ç§ãã¡ã¯å¿ããã¡ã§ããã ç¾å¨æå»ã¨ããã®ã¯ããã°ã©ããå¶å¾¡åºæ¥ãªãå¤é¨ããã®å ¥åã§ãããã®ãããããã°ã©ã ã®ãããããªã¨ããã§èªç±ã«å ¥åãåãå ¥ããã¨å¤é¨ç°å¢ã¸ã®ä¾å度ãä¸ãã£ã¦ãã¾ããèªç±ã«åãããããã¹ããããããã®ãé£ãããªãã¾ãã
ããã«ãåè¿°ã®ãããªæéå¼ã³ã³ãã³ãã®å¤å®ãããå ´åããã®åå¾ããæ¥æãããåºæºæå»ã®ä»¥å/以éã§ãããããããã¯æé帯ã«ãã¶ã£ã¦ããããªã©ã®å¤å®ããããã¨ãå¤ãã¯ãã§ãããããã£ãå¤å®ã¯ãããèªä½ã¯ããã¦é£ãããã®ã§ã¯ããã¾ããããä»ã®ãã¸ãã¯ã¨æ··å¨ããã¨ç ©éã«ãªããã¡ã§ãã
è¨ãæããã¨ãæéæ©è½ã®ä½ãã¥ããã¯ããã®ãããªåé¡ãã²ã¨ã¾ã¨ãã«è§£ããã¨ãã¦ãã¾ããã¨ã«ç±æ¥ãã¾ãã
ã¾ããããã£ãæéæ©è½ã¯ãèªåãã¹ããæ¸ãå ´åã«ãèããã¹ããã¨ãå¢ãã¦ãã¾ãã¾ãããã¨ãã°ãèªåãã¹ãæã«æ¥æãã¹ã¿ãããããå®çªã©ã¤ãã©ãªã¨ãã¦Timecopã¨ããgemãããã¾ãããã®gemã¯ãTime.now
ã®æ¯ãèããæ¸ãæãããã¨ã§æ¥æãã¹ã¿ããã¾ãããcapybara-webkitã使ã£ãEnd-to-Endãã¹ãã§ã¯ãã¾ãåãã¾ãããããã¯ããã¹ã対象ã®Rubyã³ã¼ãã®æ¥æã¯ã¹ã¿ãã§ãã¦ããcapybara-webkitãèµ·åãããã©ã¦ã¶ããã»ã¹ã®æ¥æã¯ã¹ã¿ãåºæ¥ããé½é½¬ãçã¾ããããã§ãããã®ããã«ãå¤é¨ããã»ã¹ã¨ã®ããåããçºçãããã¨ã«ãªãã¨ãåç´ã«ãè¨èªã¬ãã«ã§ç¾å¨æ¥æãã¹ã¿ããã¨ããæ¹æ³ã§ã¯è¡ãè©°ã¾ã£ã¦ãã¾ãã¾ãã
解æ³
ãã®åé¡ã¨ã®åãåãããã«ã¯ç¹å¥ãªãã¨ã¯ããã¾ãããå¤é¨ããã®å ¥åã«å¯¾ãã¦ã¯ãèªã¿è¾¼ãç®æãå±æåãããã£ããèªã¿è¾¼ãã å¤ãåæã§ä½¿ã£ã¦ããã¾ããã¾ãæé帯ã«ãã¶ããã©ããã¨ãã£ãå¤å®ãæ½åºãã¦ããã¾ãã
æ¥æã®å¤å®å¦çãæ½åºãã
ä¾ãã°ãã¥ã¼ã«ãããã£ãå¦çããã£ãã¨ãã¾ãã
- if @start_at <= Time.now && Time.now < @end_at && current_user.target? && some_condition?(current_user) = render(:special_event) # æéã«ãªãã¨ç¾ããã³ã³ãã³ã
ã¾ãã¯æå»ããã¶ã£ã¦ãããã©ããã®å¤å®ããã¯ã©ã¹ãã¡ã½ããã«æ½åºãã¾ãã
def enabled_now? @start_at <= Time.now && Time.now < @end_at end
- if enabled_now? && current_user.target? && some_condition?(current_user) = render(:special_event) # æéã«ãªãã¨ç¾ããã³ã³ãã³ã
ããã«ãæ½åºããenabled_now?
ã®ä¸ãããã£ã¨æ´çã§ãããã§ãã
2å.new
ããã¦ããTime
ã¯åä¸ãªãã¸ã§ã¯ãã§ããã¹ãã§ããã¾ããåè¿°ã®ããã«æ¥æã®ã«ãã¼ã®å¤å®ããã¦ããå¦çã¨å¤é¨å
¥åã®èªã¿è¾¼ã¿ã§ããTime.now
ã¯ãããã»ããã¡ã½ããã®è²¬åã¯å°ãªããªãã¾ãã
ä¿®æ£ç¯å²ãæå°ã«ãããå ´åãRubyã§ããã°ããã©ã«ãå¼æ°ãªã©ã«ããã®ããã£ã¨ãç°¡åã§ãããã
def enabled?(at: Time.now) @start_at <= at && at < @end_at # ããã㯠(@start_at ... @end_at).cover?(at) ãªã© end
ãããã¦ããã¨ããã¥ã¼å ¨ä½ã®ãã¹ãã§ã¯ãªãããã®å¤å®ã«é¢å¿äºãçµã£ã¦ãã¹ããã§ããããã«ãªãã¾ããä¾ãã°èªåãã¹ãã«ã¦æ¤è¨¼ãããå ´åã§ããTimecopã使ãå¿ è¦ããªããªãã¾ãã
ä¸è¨ã§ã¯ãã«ãã¼ã¡ã½ããããããã«ãå¤å®ãè¡ãå°ããªã¯ã©ã¹ã«æ½åºãã¦ãã¾ãã
context 'while being enabled' do let(:policy) { TimePeriodPolicy.new(start_at: 1.second.ago(at), end_at: 1.second.since(at)) } let(:at) { Time.now } it { expect(policy).to be_enabled(at) } end describe 'Xmas period' do let(:xmas_policy) do TimePeriodPolicy.new( start_at: Time.zone.parse('2015/12/20'), end_at: Time.zone.parse('2015/12/25').end_of_day ) end context 'in 12/19' do it { expect(xmas_policy).not_to be_enabled(Time.zone.parse('2015/12/19 00:00:00')) } end context 'in 12/20' do it { expect(xmas_policy).to be_enabled(Time.zone.parse('2015/12/20 00:00:00')) } end context 'in 12/26' do it { expect(xmas_policy).not_to be_enabled(Time.zone.parse('2015/12/26 00:00:00')) } end end
å®éã®ãµã¼ãã¹ã§ã®ã³ã³ãã³ãåºãåãã¯ãæé帯ã ãã§ãªãã¦ã¼ã¶ã®ç¶æ ããã®ä»ãã¼ã¿ãåæ¡ããå¿ è¦ãããã±ã¼ã¹ãå¤ãã§ããããããã§ããæ¥æãå¤é¨åãã¦ãããã¨ã§ãã¹ããå®å ¨ã«ã³ã³ããã¼ã«ã§ããã¡ãªããã¯å¤§ããã¯ãã§ãã
æ¥æãåå¾ããå¦çãå±æåãã
ãã¦ãæ¥æãå ã«æ¡ä»¶ãå¤å®ããç®æã¯æ½åºã§ãã¾ãããã§ã¯å¤é¨å ¥åã®å±æåãã¤ã¾ãç¾å¨æ¥æãåå¾ããç®æã¯ã©ã®ããã«ããã°ããã§ããããããã¡ããå®ç³éãé²ãã¦ããã¾ããããããªãã¡
- å¤é¨ç°å¢ãèªã¿è¾¼ãç®æãä¸ç®æã«ãã
- ãã¸ãã¯å ããã¯ãããã§èªã¿è¾¼ãã å±æåããã¤ã³ã¿ã¼ãã§ã¼ã¹ããä¸èº«ãåç §ãã
ã¨ããã¢ããã¼ãã§ãã
ä»åã®ä¾ã§è¨ãã°ãç¾å¨æå»ãã¨ãã¦æ¬²ããã£ããã®ã¯ãå®ã¯å³å¯ãªæå³ã§ã®ã³ã¼ãå®è¡æç¹ã®ç¾å¨ãã§ã¯ãªãããªã¯ã¨ã¹ããããæéãã§ååã§ãããã®ããããããåå¾ããã¤ã³ã¿ã¼ãã§ã¼ã¹ãä¸ç®æã«éå®ãã¾ãã
ç¾å¨ã¯ãã¯ãããã§ã¯ããã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãçµ±ä¸ããããã«Triceã¨ããgemãä½ãã使ã£ã¦ãã¾ãã
ãã®gemã¯ãRailsã®ã³ã³ããã¼ã©ã«ãªã¯ã¨ã¹ããå°éããæéã表ãrequested_at
ã¡ã½ãããæä¾ãã¾ãã
class ApplicationController < ActionController::Base include Trice::ControllerMethods end
class SpecialEventsController < Applicationcontroller def show ... if @event.policy.enabled?(requested_at) do_something else head :not_found end end end
ã¢ãã«ã®å¦çã§ãã®æå»ã使ãã«ã¯ãã³ã³ããã¼ã©ãããã®æå»ã渡ãã¦ããã¾ãã ãªããªããç¾å¨ãç¥ãã®ã¯ãå¤é¨ããã®å ¥åãé©åã«ã¢ãã«ã«æ¸¡ããã¨ããã³ã³ããã¼ã©ã®è²¬åã®ç¯å²ã§ãããã¢ãã«å´ã¯ãã®Timeãªãã¸ã§ã¯ãã®ç±æ¥ãé¢ç¥ãã¹ãã§ãªãããã§ãã
ãã¥ã¼ã§ãåæ§ã«ãTime.now
ãç´æ¥å¼ã¶ã®ã§ã¯ãªããrequested_at
ããåå¾ã§ããå¤ãåºæºã¨ãã¦æéæ©è½ãå¤å®ãã¾ãã
- @event.policy.enabled?(requested_at) = render(:special_event) # æéã«ãªãã¨ç¾ããã³ã³ãã³ã
ãã¦ããã®ããã«ç¾å¨æå»ãåå¾ããã¤ã³ã¿ã¼ãã§ã¼ã¹ãæ½åºããã¨ãèªåãã¹ãã®ä¸ããåç §ããç¾å¨æå»ãå¤æ´ããã®ãç°¡åã«ãªãã¾ãã
Timecopãªã©ã®ããã«ããã»ã¹å
¨ä½ã§å
±æãããTime.now
ãã¹ã¿ãããã®ã§ã¯ãªããcontroller#requested_at
ã®ã¿ãã¹ã¿ãããã°ãããªããããã¹ã¿ããå½±é¿ããç¯å²ãã³ã³ããã¼ã«ãããããªãã¾ãã
before do controller.stub(:requested_at) { Time.zone.parse('2015/12/20 00:00:00') } get :show, id: xmas_event.id end
ã·ã¹ãã æå»ä»¥å¤ã®å ¥åãåãä»ããããããã«ãã
ããã«ãããã¾ã§ãªãã¡ã¯ã¿ãªã³ã°ãé²ããçµæãå½åã¯ãç¾å¨æå»ã«ãã£ã¦æåãå¤ãããæ©è½ã§ãã£ããã®ããå®ã¯ããªã¯ã¨ã¹ãæå»ã¨ã¿ãªããTimeãªãã¸ã§ã¯ãã«åºã¥ãã¦æåãå¤ãããã¨ããæ©è½ã ã£ããã¨ã«æ°ä»ãã¾ãã
ã¨ãããã¨ã¯ãTime.now
ãå¼ãã§ã·ã¹ãã æå»ãåå¾ãã以å¤ã®æ¹æ³ã§ãªã¯ã¨ã¹ãæå»ãè¨å®ã§ããã°ãèªåãã¹ããåä½ç¢ºèªãã¨ã¦ãããããããªãã¾ãã
Triceã§ã¯å®éã«ããªã¯ã¨ã¹ãã®HTTPãããã使ã£ã¦å¤é¨ãããåºæºæ¥æãè¨å®ã§ããããã«ãªã£ã¦ãã¾ãã èªåãã¹ãå ãããã®ãªã¯ã¨ã¹ãããããå©ç¨ãã¦åºæºæ¥æãèªç±ã«è¨å®ããããã®ãã¹ããã«ãã¼ãããã¾ãã
ãã®ãããªå®è£
ãããã°ãæ¬çªã«è¿ãæ§æã®æåãã¹ãç°å¢ã§ãæéæ©è½ã®åä½ãç¡çãªã確èªã§ãã¾ããã¾ããCapybaraã§ã®End-to-Endãã¹ãã®ãããªé«ã¬ãã«ãªèªåãã¹ããããåãããã«åºæºæ¥æãè¨å®ãã¦ãã¹ãã§ããããã«ãªãã¾ããåè¿°ã®ããã«ãTimecopãªã©å¦çç³»ã®Time.now
ãã¾ããã¨ã¹ã¿ãããã©ã¤ãã©ãªã¯åããªããã¨ãããã¾ãããTriceã®æ¹å¼ã§ããã°åé¡ãªãåä½ãã¾ãã
ã¾ã¨ã
ç¾å¨æå»ã®åå¾(Time.now)ã¯å¤é¨å ¥åã®èªã¿åãã«ã»ããªãã¾ãããç¾å¨æå»ã«åºã¥ãã¦åå²ãããããªå¦çã¯ãä¸è¦ç°¡åã«è¦ãã¾ãããå°ããã¤ã¢ããªã±ã¼ã·ã§ã³ãè¤éã«ãã¦ããã¾ãã
ãããã
- å ¥ååå¾ã¨å¤å®é¨åãåé¢ãã
- å ¥ååå¾ããç®æãçµ±ä¸ã»å±æåãã
- å¿ è¦ã«å¿ãã¦ãå¤é¨ã®å¤ã§ä¸æ¸ãã§ããããã«ãã
ã¨ãªãã¡ã¯ã¿ãªã³ã°ãã¦ãããã¨ã§ãåä½ç¢ºèªãèªåãã¹ãã§ã®æ±ãããããåãæ»ãã¾ããã
ãããã£ãæ¹æ³ã¯ã決ãã¦ç¹å¥ã§é£ãããã¨ããã¦ããããã§ã¯ããã¾ãããã©ã¡ããã¨ããã°ãªãã¸ã§ã¯ãæåã ã£ããããã°ã©ãã³ã°ä¸è¬ã ã£ããã®åºæ¬çãªèãæ¹ãå®éã®ã¢ããªã±ã¼ã·ã§ã³ã«é©ç¨ãããã®ããã«å¿ è¦ãªå°ããªã©ã¤ãã©ãªãã¤ãã£ãã ãã§ããããã§ããå®éã®ãµã¼ãã¹ã§ããè¦ãã¤ããã軽æ¸ã§ãã¦ããã®ã§ã¯ãªãã§ããããã
ãããã¦èªã¿ãã
åè¿°ã®ããã«ããã®ç¾å¨æ¥æãé©åã«æ½åºãã¦ã³ã¼ããæ´çããæ¹æ³ã¯ã決ãã¦ç®æ°ãããã®ã§ã¯ãªããå¤ãã®æ¸ç±ããµã¤ãã§èªããã¦ããèãæ¹ã§ããå éã®å¤ãã®æ å ±ã®ãã¡ãç¹ã«ããã¾ã¨ã¾ã£ã¦ããã¨æããURLã示ãã¾ãã®ã§ãããã£ãããã¡ããåããã¦ã©ããã
- ããã§ããªãããã¹ãé§åéçºãã¹ã¿ã¼ï¼ï¼åç°å人ããããã¹ãé§åéçºåé¡ã解çã³ã¼ã使ããªãã解説ãã¾ãï½ç¾å¨æå»ãé¢ãããã¹ãããããã¹ã容ææ§è¨è¨ãå¦ã¶ #tdd
- ã³ã¼ãå ã§ãç¾æå»ããæ°è»½ã«åå¾ãã¦ã¯ãããªã