<commit_before>require 'modesty'

describe Modesty, "Working with identities" do
  before :each do
    @id = rand 10**10
  end

  it "can make an identity" do
    Modesty.identify! @id
    Modesty.identity.should == @id
  end

  it "can identify as nil" do
    Modesty.identify! nil
    Modesty.identity.should be_nil
  end

  after :all do
    Modesty.instance_variable_set("@identity", nil)
  end
end

describe Modesty, "contextual identity" do
  before :all do
    Modesty.experiments.clear
    Modesty.metrics.clear
    Modesty.data.flushdb
  end

  it "can make an experiment with contextual identities for its metrics" do
    Modesty.new_metric :donation_amount
    Modesty.new_metric :donation
    Modesty.new_metric :creation

    Modesty.new_experiment :creation_page do |e|
      e.metric :creation
      e.metric :donation, :by => :creator
      e.metric :donation_amount, :by => :creator
    end
  end

  it "leaves the other metrics alone" do
    e = Modesty.experiments[:creation_page]
    e.chooses :experiment, :for => 700
    Modesty.identify! 700
    e.group.should == :experiment

    Modesty.track! :creation
    m = Modesty.metrics[:creation/:creation_page/:experiment]
    m.distribution.should == {1 => 1}
  end

  it "expects a passed-in identity for the specified metrics" do
    lambda do
      Modesty.track! :donation
    end.should raise_error(Modesty::IdentityError)
  end

  it "aggregates counts by the contextual identity's experiment group" do
    e = Modesty.experiments[:creation_page]
    e.chooses :control, :for => 600
    Modesty.identify! 600
    lambda do
      #user 600 donated 10 bucks to user 700's birthday wish!
      Modesty.track! :donation_amount, 10, :creator => 700
    end.should_not raise_error
    group_exp = Modesty.metrics[:donation_amount/:creation_page/:experiment]
    group_exp.distribution.should == {10 => 1}
    group_ctrl = Modesty.metrics[:donation_amount/:creation_page/:control]
    group_ctrl.distribution.should == {}

    e.chooses :experiment, :for => 500
    #user 500 donated 2000 to 600's wish
    Modesty.identify! 500
    Modesty.track! :donation_amount, 2000, :creator => 600

    group_exp.distribution.should == {10 => 1}
    group_ctrl.distribution.should == {2000 => 1}
  end
end<commit_msg>Add specs for contextual identity in experiments<commit_after>require 'modesty'

describe Modesty, "Working with identities" do
  before :each do
    @id = rand 10**10
  end

  it "can make an identity" do
    Modesty.identify! @id
    Modesty.identity.should == @id
  end

  it "can identify as nil" do
    Modesty.identify! nil
    Modesty.identity.should be_nil
  end

  after :all do
    Modesty.instance_variable_set("@identity", nil)
  end
end

describe Modesty, "contextual identity" do
  before :each do
    Modesty.experiments.clear
    Modesty.metrics.clear
    Modesty.data.flushdb

    Modesty.new_metric :donation_amount
    Modesty.new_metric :donation
    Modesty.new_metric :creation

    Modesty.new_experiment :creation_page do |e|
      e.metric :creation
      e.metric :donation, :by => :creator
      e.metric :donation_amount, :by => :creator
    end
    @e = Modesty.experiments[:creation_page]
    Modesty.identify! nil

    @e.chooses :experiment, :for => 500
    @e.chooses :control, :for => 600
    @e.chooses :experiment, :for => 700
    @group_exp = Modesty.metrics[:donation_amount/:creation_page/:experiment]
    @group_ctrl = Modesty.metrics[:donation_amount/:creation_page/:control]
  end

  it "leaves the other metrics alone" do
    Modesty.with_identity 700 do
      @e.group.should == :experiment
      Modesty.track! :creation
    end

    m = Modesty.metrics[:creation/:creation_page/:experiment]
    m.distribution.should == {1 => 1}
  end

  it "expects a passed-in identity for the specified metrics" do
    Modesty.identify! 700
    lambda do
      Modesty.track! :donation
    end.should raise_error(Modesty::IdentityError)
  end

  it "aggregates counts by the contextual identity's experiment group" do
    Modesty.with_identity 600 do
      lambda do
        #user 600 donated 10 bucks to user 700's birthday wish!
        Modesty.track! :donation_amount, 10, :with => {:creator => 700}
      end.should_not raise_error
    end
    @group_exp.distribution.should == {10 => 1}
    @group_ctrl.distribution.should == {}

    @e.chooses :experiment, :for => 500
    #user 500 donated 2000 to 600's wish
    Modesty.with_identity 500 do
      Modesty.track! :donation_amount, 2000, :with => {:creator => 600}
    end

    @group_exp.distribution.should == {10 => 1}
    @group_ctrl.distribution.should == {2000 => 1}
  end

  it "verify that all(:users) still remembers the real users" do
    # user 600, who is in the control group, donates $45 to user 700's wish
    Modesty.with_identity 600 do
      Modesty.track! :donation_amount, 45, :with => {:creator => 700}
    end

    # user 500, who is in the experiment group, donates $30 to user 700's wish
    Modesty.with_identity 500 do
      Modesty.track! :donation_amount, 30, :with => {:creator => 700}
    end

    # a guest donates $15 to user 700's wish
    Modesty.with_identity nil do
      Modesty.track! :donation_amount, 15, :with => {:creator => 700}
    end

    @group_exp.distribution.should == {45 => 1, 30 => 1, 15 => 1}
    @group_ctrl.distribution.should == {}
    @group_exp.distribution_by(:creator).should == {700 => {45 => 1, 30 => 1, 15 => 1}}
    @group_ctrl.distribution_by(:creator).should == {}

    @group_exp.all(:creators).should == [700]
    @group_exp.all(:users).should == [500, 600]
    @group_exp.unidentified_users.should == 1
  end
end
{'fraction_non_alphanumeric': 0.1066430469441984, 'fraction_numerical': 0.037023914968999115, 'mean_word_length': 3.2772727272727273, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6921153', 'n_tokens_mistral': 2070, 'n_tokens_neox': 1791, 'n_words': 513}