# Global Metrics

path: .metrics.loc.sloc
old: 192.0
new: 604.0
path: .metrics.loc.blank
old: 32.0
new: 113.0
path: .metrics.loc.ploc
old: 123.0
new: 393.0
path: .metrics.loc.lloc
old: 49.0
new: 217.0
path: .metrics.loc.cloc
old: 37.0
new: 98.0
path: .metrics.halstead.effort
old: 147077.57874720666
new: 1265026.4939736363
path: .metrics.halstead.purity_ratio
old: 1.1621272408910566
new: 0.5380008574737342
path: .metrics.halstead.estimated_program_length
old: 789.0843965650274
new: 1194.3619035916895
path: .metrics.halstead.N2
old: 308.0
new: 957.0
path: .metrics.halstead.vocabulary
old: 125.0
new: 174.0
path: .metrics.halstead.length
old: 679.0
new: 2220.0
path: .metrics.halstead.level
old: 0.032158317872603585
new: 0.013061650992685477
path: .metrics.halstead.bugs
old: 0.928773309491076
new: 3.898927498251965
path: .metrics.halstead.time
old: 8170.976597067037
new: 70279.24966520203
path: .metrics.halstead.n2
old: 104.0
new: 150.0
path: .metrics.halstead.N1
old: 371.0
new: 1263.0
path: .metrics.halstead.n1
old: 21.0
new: 24.0
path: .metrics.halstead.volume
old: 4729.767529285557
new: 16523.334560784177
path: .metrics.halstead.difficulty
old: 31.096153846153847
new: 76.56
path: .metrics.nexits.average
old: 1.5
new: 0.17647058823529413
path: .metrics.nexits.sum
old: 6.0
new: 9.0
path: .metrics.nargs.sum
old: 8.0
new: 34.0
path: .metrics.nargs.average
old: 2.0
new: 0.6666666666666666
path: .metrics.cognitive.sum
old: 6.0
new: 10.0
path: .metrics.cognitive.average
old: 1.5
new: 0.19607843137254904
path: .metrics.cyclomatic.average
old: 1.8571428571428572
new: 1.4166666666666667
path: .metrics.cyclomatic.sum
old: 13.0
new: 34.0
path: .metrics.nom.functions
old: 4.0
new: 21.0
path: .metrics.nom.total
old: 4.0
new: 51.0
path: .metrics.nom.closures
old: 0.0
new: 30.0
path: .metrics.mi.mi_visual_studio
old: 22.712334529850832
new: 5.226285283606691
path: .metrics.mi.mi_original
old: 38.83809204604492
new: 8.936947834967441
path: .metrics.mi.mi_sei
old: 13.09683865729141
new: -30.13047607449204

# Spaces Data

## Minimal test - lines (35, 104)

path: .spaces[0].metrics.nargs.average
old: 2.0
new: 1.1111111111111112
path: .spaces[0].metrics.nargs.sum
old: 2.0
new: 10.0
path: .spaces[0].metrics.nexits.average
old: 0.0
new: 1.0
path: .spaces[0].metrics.nexits.sum
old: 0.0
new: 9.0
path: .spaces[0].metrics.loc.sloc
old: 9.0
new: 70.0
path: .spaces[0].metrics.loc.ploc
old: 7.0
new: 46.0
path: .spaces[0].metrics.loc.lloc
old: 2.0
new: 17.0
path: .spaces[0].metrics.loc.blank
old: 2.0
new: 16.0
path: .spaces[0].metrics.loc.cloc
old: 0.0
new: 8.0
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 14.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.2727272727272727
path: .spaces[0].metrics.halstead.volume
old: 263.22462421590114
new: 1497.7619832260814
path: .spaces[0].metrics.halstead.N2
old: 27.0
new: 104.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 99.0586500259616
new: 418.9132927051375
path: .spaces[0].metrics.halstead.length
old: 56.0
new: 239.0
path: .spaces[0].metrics.halstead.time
old: 87.74154140530038
new: 1518.1992812428116
path: .spaces[0].metrics.halstead.effort
old: 1579.3477452954069
new: 27327.587062370607
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.7689044647493144
new: 1.7527752832850942
path: .spaces[0].metrics.halstead.n2
old: 18.0
new: 57.0
path: .spaces[0].metrics.halstead.difficulty
old: 6.0
new: 18.24561403508772
path: .spaces[0].metrics.halstead.N1
old: 29.0
new: 135.0
path: .spaces[0].metrics.halstead.bugs
old: 0.04520612224517764
new: 0.30242169023465215
path: .spaces[0].metrics.halstead.vocabulary
old: 26.0
new: 77.0
path: .spaces[0].metrics.halstead.level
old: 0.16666666666666666
new: 0.05480769230769231
path: .spaces[0].metrics.halstead.n1
old: 8.0
new: 20.0
path: .spaces[0].metrics.mi.mi_visual_studio
old: 62.1025272140916
new: 35.633564513273114
path: .spaces[0].metrics.mi.mi_sei
old: 77.60843161312731
new: 38.6383094239308
path: .spaces[0].metrics.mi.mi_original
old: 106.19532153609664
new: 60.933395317697034
path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 0.3333333333333333
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 3.0
path: .spaces[0].metrics.nom.functions
old: 1.0
new: 9.0
path: .spaces[0].metrics.nom.total
old: 1.0
new: 9.0

### Code

    namespace TestThrottledEventQueue {

    // A simple queue of runnables, to serve as the base target of
    // ThrottledEventQueues in tests.
    //
    // This is much simpler than mozilla::TaskQueue, and so better for unit tests.
    // It's about the same as mozilla::EventQueue, but that doesn't implement
    // nsIEventTarget, so it can't be the base target of a ThrottledEventQueue.
    struct RunnableQueue : nsISerialEventTarget {
      std::queue> runnables;

      bool IsEmpty() { return runnables.empty(); }
      size_t Length() { return runnables.size(); }

      [[nodiscard]] nsresult Run() {
        while (!runnables.empty()) {
          auto runnable = move(runnables.front());
          runnables.pop();
          nsresult rv = runnable->Run();
          if (NS_FAILED(rv)) return rv;
        }

        return NS_OK;
      }

      // nsIEventTarget methods

      [[nodiscard]] NS_IMETHODIMP Dispatch(already_AddRefed aRunnable,
                                           uint32_t aFlags) override {
        MOZ_ALWAYS_TRUE(aFlags == nsIEventTarget::DISPATCH_NORMAL);
        runnables.push(aRunnable);
        return NS_OK;
      }

      [[nodiscard]] NS_IMETHODIMP DispatchFromScript(nsIRunnable* aRunnable,
                                                     uint32_t aFlags) override {
        RefPtr r = aRunnable;
        return Dispatch(r.forget(), aFlags);
      }

      NS_IMETHOD_(bool)
      IsOnCurrentThreadInfallible(void) override { return NS_IsMainThread(); }

      [[nodiscard]] NS_IMETHOD IsOnCurrentThread(bool* retval) override {
        *retval = IsOnCurrentThreadInfallible();
        return NS_OK;
      }

      [[nodiscard]] NS_IMETHODIMP DelayedDispatch(
          already_AddRefed aEvent, uint32_t aDelay) override {
        return NS_ERROR_NOT_IMPLEMENTED;
      }

      // nsISupports methods

      NS_DECL_THREADSAFE_ISUPPORTS

     private:
      virtual ~RunnableQueue() = default;
    };

    NS_IMPL_ISUPPORTS(RunnableQueue, nsIEventTarget, nsISerialEventTarget)

    static void Enqueue(nsIEventTarget* target, function&& aCallable) {
      nsresult rv =
          target->Dispatch(NS_NewRunnableFunction("TEQ GTest", move(aCallable)));
      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
    }

    }  // namespace TestThrottledEventQueue

## Minimal test - lines (138, 182)

path: .spaces[3].metrics.nexits.sum
old: 4.0
new: 0.0
path: .spaces[3].metrics.nexits.average
old: 4.0
new: 0.0
path: .spaces[3].metrics.halstead.effort
old: 16903.908018941802
new: 13066.29095490459
path: .spaces[3].metrics.halstead.n2
old: 53.0
new: 23.0
path: .spaces[3].metrics.halstead.N1
old: 118.0
new: 92.0
path: .spaces[3].metrics.halstead.level
old: 0.07598566308243727
new: 0.06084656084656084
path: .spaces[3].metrics.halstead.n1
old: 15.0
new: 12.0
path: .spaces[3].metrics.halstead.estimated_program_length
old: 362.1831430259773
new: 147.06147499796518
path: .spaces[3].metrics.halstead.purity_ratio
old: 1.716507786852973
new: 0.9487837096642916
path: .spaces[3].metrics.halstead.volume
old: 1284.4546595038216
new: 795.0388676264698
path: .spaces[3].metrics.halstead.difficulty
old: 13.160377358490566
new: 16.434782608695652
path: .spaces[3].metrics.halstead.vocabulary
old: 68.0
new: 35.0
path: .spaces[3].metrics.halstead.N2
old: 93.0
new: 63.0
path: .spaces[3].metrics.halstead.bugs
old: 0.2195517109435799
new: 0.18491847152708668
path: .spaces[3].metrics.halstead.length
old: 211.0
new: 155.0
path: .spaces[3].metrics.halstead.time
old: 939.1060010523224
new: 725.905053050255
path: .spaces[3].metrics.cyclomatic.average
old: 2.5
new: 1.0
path: .spaces[3].metrics.cyclomatic.sum
old: 5.0
new: 1.0
path: .spaces[3].metrics.nargs.average
old: 2.0
new: 0.5
path: .spaces[3].metrics.loc.sloc
old: 59.0
new: 45.0
path: .spaces[3].metrics.loc.cloc
old: 4.0
new: 17.0
path: .spaces[3].metrics.loc.ploc
old: 45.0
new: 21.0
path: .spaces[3].metrics.loc.blank
old: 10.0
new: 7.0
path: .spaces[3].metrics.loc.lloc
old: 18.0
new: 17.0
path: .spaces[3].metrics.nom.total
old: 1.0
new: 4.0
path: .spaces[3].metrics.nom.closures
old: 0.0
new: 3.0
path: .spaces[3].metrics.mi.mi_original
old: 66.57182791637834
new: 74.37443444723256
path: .spaces[3].metrics.mi.mi_sei
old: 40.47735528003078
new: 72.43498082442238
path: .spaces[3].metrics.mi.mi_visual_studio
old: 38.930893518349905
new: 43.493821314171086
path: .spaces[3].metrics.cognitive.average
old: 3.0
new: 0.0
path: .spaces[3].metrics.cognitive.sum
old: 3.0
new: 0.0

### Code

    TEST(ThrottledEventQueue, MixedDispatch)
    {
      string log;

      auto base = MakeRefPtr();
      RefPtr throttled =
          ThrottledEventQueue::Create(base, "test queue 2");

      // A ThrottledEventQueue limits its impact on the base target by only queuing
      // its next event on the base once the prior event has been run. What it
      // actually queues on the base is a sort of proxy event called an
      // "executor": the base running the executor draws an event from the
      // ThrottledEventQueue and runs that. If the ThrottledEventQueue has further
      // events, it re-queues the executor on the base, effectively "going to the
      // back of the line".

      // Queue an event on the ThrottledEventQueue. This also queues the "executor"
      // event on the base.
      Enqueue(throttled, [&]() { log += 'a'; });
      ASSERT_EQ(throttled->Length(), 1U);
      ASSERT_EQ(base->Length(), 1U);

      // Add a second event to the throttled queue. The executor is already queued.
      Enqueue(throttled, [&]() { log += 'b'; });
      ASSERT_EQ(throttled->Length(), 2U);
      ASSERT_EQ(base->Length(), 1U);

      // Add an event directly to the base, after the executor.
      Enqueue(base, [&]() { log += 'c'; });
      ASSERT_EQ(throttled->Length(), 2U);
      ASSERT_EQ(base->Length(), 2U);

      // Run the base target. This runs:
      // - the executor, which runs the first event from the ThrottledEventQueue,
      //   and re-enqueues itself
      // - the event queued directly on the base
      // - the executor again, which runs the second event from the
      // ThrottledEventQueue.
      ASSERT_EQ(log, "");
      ASSERT_TRUE(NS_SUCCEEDED(base->Run()));
      ASSERT_EQ(log, "acb");

      ASSERT_TRUE(base->IsEmpty());
      ASSERT_TRUE(throttled->IsEmpty());
    }

## Minimal test - lines (108, 120)

path: .spaces[1].metrics.halstead.volume
old: 760.5801913818267
new: 366.63429801500513
path: .spaces[1].metrics.halstead.length
old: 146.0
new: 78.0
path: .spaces[1].metrics.halstead.purity_ratio
old: 1.1068578322416938
new: 1.2391936761427955
path: .spaces[1].metrics.halstead.vocabulary
old: 37.0
new: 26.0
path: .spaces[1].metrics.halstead.N2
old: 68.0
new: 29.0
path: .spaces[1].metrics.halstead.difficulty
old: 12.592592592592592
new: 10.633333333333333
path: .spaces[1].metrics.halstead.level
old: 0.07941176470588235
new: 0.09404388714733544
path: .spaces[1].metrics.halstead.effort
old: 9577.676484067448
new: 3898.544702226221
path: .spaces[1].metrics.halstead.N1
old: 78.0
new: 49.0
path: .spaces[1].metrics.halstead.n2
old: 27.0
new: 15.0
path: .spaces[1].metrics.halstead.estimated_program_length
old: 161.60124350728728
new: 96.65710673913804
path: .spaces[1].metrics.halstead.time
old: 532.0931380037471
new: 216.5858167903456
path: .spaces[1].metrics.halstead.bugs
old: 0.15033226036769168
new: 0.08256837881216253
path: .spaces[1].metrics.halstead.n1
old: 10.0
new: 11.0
path: .spaces[1].metrics.nom.total
old: 1.0
new: 4.0
path: .spaces[1].metrics.nom.closures
old: 0.0
new: 3.0
path: .spaces[1].metrics.loc.ploc
old: 19.0
new: 11.0
path: .spaces[1].metrics.loc.blank
old: 3.0
new: 2.0
path: .spaces[1].metrics.loc.sloc
old: 22.0
new: 13.0
path: .spaces[1].metrics.nargs.average
old: 2.0
new: 0.5
path: .spaces[1].metrics.mi.mi_original
old: 86.19788818652478
new: 98.5151229911034
path: .spaces[1].metrics.mi.mi_sei
old: 48.75823368919235
new: 66.5282472592229
path: .spaces[1].metrics.mi.mi_visual_studio
old: 50.40812174650572
new: 57.611183035732985

### Code

    TEST(ThrottledEventQueue, RunnableQueue)
    {
      string log;

      RefPtr queue = MakeRefPtr();
      Enqueue(queue, [&]() { log += 'a'; });
      Enqueue(queue, [&]() { log += 'b'; });
      Enqueue(queue, [&]() { log += 'c'; });

      ASSERT_EQ(log, "");
      ASSERT_TRUE(NS_SUCCEEDED(queue->Run()));
      ASSERT_EQ(log, "abc");
    }

## Minimal test - lines (122, 136)

path: .spaces[2].metrics.nexits.average
old: 2.0
new: 0.0
path: .spaces[2].metrics.nexits.sum
old: 2.0
new: 0.0
path: .spaces[2].metrics.nargs.average
old: 2.0
new: 1.0
path: .spaces[2].metrics.cognitive.average
old: 3.0
new: 0.0
path: .spaces[2].metrics.cognitive.sum
old: 3.0
new: 0.0
path: .spaces[2].metrics.nom.total
old: 1.0
new: 2.0
path: .spaces[2].metrics.nom.closures
old: 0.0
new: 1.0
path: .spaces[2].metrics.cyclomatic.average
old: 2.5
new: 1.0
path: .spaces[2].metrics.cyclomatic.sum
old: 5.0
new: 1.0
path: .spaces[2].metrics.halstead.N2
old: 115.0
new: 30.0
path: .spaces[2].metrics.halstead.level
old: 0.0641304347826087
new: 0.10555555555555556
path: .spaces[2].metrics.halstead.n1
old: 16.0
new: 12.0
path: .spaces[2].metrics.halstead.estimated_program_length
old: 411.07593991234864
new: 123.730172764082
path: .spaces[2].metrics.halstead.n2
old: 59.0
new: 19.0
path: .spaces[2].metrics.halstead.time
old: 1402.9504997802396
new: 185.1304937039306
path: .spaces[2].metrics.halstead.difficulty
old: 15.59322033898305
new: 9.473684210526317
path: .spaces[2].metrics.halstead.bugs
old: 0.2869163610722832
new: 0.0743667932652112
path: .spaces[2].metrics.halstead.effort
old: 25253.108996044313
new: 3332.3488866707507
path: .spaces[2].metrics.halstead.length
old: 260.0
new: 71.0
path: .spaces[2].metrics.halstead.vocabulary
old: 75.0
new: 31.0
path: .spaces[2].metrics.halstead.volume
old: 1619.4928595289289
new: 351.74793803746815
path: .spaces[2].metrics.halstead.N1
old: 145.0
new: 41.0
path: .spaces[2].metrics.halstead.purity_ratio
old: 1.5810613073551871
new: 1.7426784896349576
path: .spaces[2].metrics.loc.cloc
old: 3.0
new: 0.0
path: .spaces[2].metrics.loc.lloc
old: 20.0
new: 6.0
path: .spaces[2].metrics.loc.ploc
old: 46.0
new: 12.0
path: .spaces[2].metrics.loc.blank
old: 9.0
new: 3.0
path: .spaces[2].metrics.loc.sloc
old: 58.0
new: 15.0
path: .spaces[2].metrics.mi.mi_original
old: 65.64350791552621
new: 96.41242960552177
path: .spaces[2].metrics.mi.mi_visual_studio
old: 38.388016324869135
new: 56.38153778100688
path: .spaces[2].metrics.mi.mi_sei
old: 36.76619133515442
new: 63.494701939334234

### Code

    TEST(ThrottledEventQueue, SimpleDispatch)
    {
      string log;

      auto base = MakeRefPtr();
      RefPtr throttled =
          ThrottledEventQueue::Create(base, "test queue 1");

      Enqueue(throttled, [&]() { log += 'a'; });
      ASSERT_TRUE(NS_SUCCEEDED(base->Run()));
      ASSERT_EQ(log, "a");

      ASSERT_TRUE(base->IsEmpty());
      ASSERT_TRUE(throttled->IsEmpty());
    }