<commit_before>package mesos_test

import (
	"testing"

	"github.com/mesos/mesos-go"
)

func TestResource_IsEmpty(t *testing.T) {
	for i, tc := range []struct {
		r     *mesos.Resource
		wants bool
	}{
		{nil, true},
		{new(mesos.Resource), true},
		{resource(valueScalar(0)), true},
		{resource(valueSet()), true},
		{resource(valueSet([]string{}...)), true},
		{resource(valueSet()), true},
		{resource(valueSet("")), false},
		{resource(valueRange()), true},
		{resource(valueRange(span(0, 0))), false},
	} {
		actual := tc.r.IsEmpty()
		if tc.wants != actual {
			t.Errorf("test case %d failed: wants (%t) != actual (%t)", i, tc.wants, actual)
		}
	}
}

func TestResources_MinusAll(t *testing.T) {
	for i, tc := range []struct {
		r1, r2      mesos.Resources
		wants       mesos.Resources
		wantsCPU    float64
		wantsMemory uint64
	}{
		{r1: nil, r2: nil, wants: nil},
		{r1: resources(), r2: resources(), wants: resources()},
		// simple scalars, same roles for everything
		{
			r1: resources(
				resource(name("cpus"), valueScalar(50), role("*")),
				resource(name("mem"), valueScalar(4096), role("*")),
			),
			r2: resources(
				resource(name("cpus"), valueScalar(0.5), role("*")),
				resource(name("mem"), valueScalar(1024), role("*")),
			),
			wants: resources(
				resource(name("cpus"), valueScalar(49.5), role("*")),
				resource(name("mem"), valueScalar(3072), role("*")),
			),
			wantsCPU:    49.5,
			wantsMemory: 3072,
		},
		// multi-role subtraction
		{
			r1: resources(
				resource(name("cpus"), valueScalar(5), role("role1")),
				resource(name("cpus"), valueScalar(3), role("role2")),
			),
			r2: resources(
				resource(name("cpus"), valueScalar(1), role("role1")),
			),
			wants: resources(
				resource(name("cpus"), valueScalar(4), role("role1")),
				resource(name("cpus"), valueScalar(3), role("role2")),
			),
			wantsCPU: 7,
		},
	} {
		backup := tc.r1.Clone()

		// MinusAll preserves the left operand
		actual := tc.r1.MinusAll(tc.r2)
		if !tc.wants.Equivalent(actual) {
			t.Errorf("test case %d failed: wants (%v) != actual (%v)", i, tc.wants, actual)
		}
		if !backup.Equivalent(tc.r1) {
			t.Errorf("test case %d failed: backup (%v) != r1 (%v)", i, backup, tc.r1)
		}

		// SubtractAll mutates the left operand
		tc.r1.SubtractAll(tc.r2)
		if !tc.wants.Equivalent(tc.r1) {
			t.Errorf("test case %d failed: wants (%v) != r1 (%v)", i, tc.wants, tc.r1)
		}

		cpus, ok := tc.r1.CPUs()<commit_msg>added resources range subtraction tests<commit_after>package mesos_test

import (
	"testing"

	"github.com/mesos/mesos-go"
)

func TestResource_IsEmpty(t *testing.T) {
	for i, tc := range []struct {
		r     *mesos.Resource
		wants bool
	}{
		{nil, true},
		{new(mesos.Resource), true},
		{resource(valueScalar(0)), true},
		{resource(valueSet()), true},
		{resource(valueSet([]string{}...)), true},
		{resource(valueSet()), true},
		{resource(valueSet("")), false},
		{resource(valueRange()), true},
		{resource(valueRange(span(0, 0))), false},
	} {
		actual := tc.r.IsEmpty()
		if tc.wants != actual {
			t.Errorf("test case %d failed: wants (%t) != actual (%t)", i, tc.wants, actual)
		}
	}
}

func TestResources_MinusAll(t *testing.T) {
	for i, tc := range []struct {
		r1, r2      mesos.Resources
		wants       mesos.Resources
		wantsCPU    float64
		wantsMemory uint64
	}{
		{r1: nil, r2: nil, wants: nil},
		{r1: resources(), r2: resources(), wants: resources()},
		// simple scalars, same roles for everything
		{
			r1: resources(
				resource(name("cpus"), valueScalar(50), role("*")),
				resource(name("mem"), valueScalar(4096), role("*")),
			),
			r2: resources(
				resource(name("cpus"), valueScalar(0.5), role("*")),
				resource(name("mem"), valueScalar(1024), role("*")),
			),
			wants: resources(
				resource(name("cpus"), valueScalar(49.5), role("*")),
				resource(name("mem"), valueScalar(3072), role("*")),
			),
			wantsCPU:    49.5,
			wantsMemory: 3072,
		},
		// multi-role, scalar subtraction
		{
			r1: resources(
				resource(name("cpus"), valueScalar(5), role("role1")),
				resource(name("cpus"), valueScalar(3), role("role2")),
			),
			r2: resources(
				resource(name("cpus"), valueScalar(1), role("role1")),
			),
			wants: resources(
				resource(name("cpus"), valueScalar(4), role("role1")),
				resource(name("cpus"), valueScalar(3), role("role2")),
			),
			wantsCPU: 7,
		},
		// simple ranges, same roles, lower-edge overlap
		{
			r1: resources(
				resource(name("ports"), valueRange(span(20000, 40000)), role("*")),
			),
			r2: resources(
				resource(name("ports"), valueRange(span(10000, 20000), span(30000, 50000)), role("*")),
			),
			wants: resources(
				resource(name("ports"), valueRange(span(20001, 29999)), role("*")),
			),
		},
		// simple ranges, same roles, single port/lower-edge
		{
			r1: resources(
				resource(name("ports"), valueRange(span(50000, 60000)), role("*")),
			),
			r2: resources(
				resource(name("ports"), valueRange(span(50000, 50000)), role("*")),
			),
			wants: resources(
				resource(name("ports"), valueRange(span(50001, 60000)), role("*")),
			),
		},
		// simple ranges, same roles, multi port/lower-edge
		{
			r1: resources(
				resource(name("ports"), valueRange(span(50000, 60000)), role("*")),
			),
			r2: resources(
				resource(name("ports"), valueRange(span(50000, 50001)), role("*")),
			),
			wants: resources(
				resource(name("ports"), valueRange(span(50002, 60000)), role("*")),
			),
		},
		// simple ranges, same roles, identical overlap
		{
			r1: resources(
				resource(name("ports"), valueRange(span(50000, 60000)), role("*")),
			),
			r2: resources(
				resource(name("ports"), valueRange(span(50000, 60000)), role("*")),
			),
			wants: resources(),
		},
		// multiple ranges, same roles, swiss cheese
		{
			r1: resources(
				resource(name("ports"), valueRange(span(1, 10), span(20, 30), span(40, 50)), role("*")),
			),
			r2: resources(
				resource(name("ports"), valueRange(span(2, 9), span(15, 45), span(48, 50)), role("*")),
			),
			wants: resources(
				resource(name("ports"), valueRange(span(1, 1), span(10, 10), span(46, 47)), role("*")),
			),
		},
		// multiple ranges, same roles, no overlap
		{
			r1: resources(
				resource(name("ports"), valueRange(span(1, 10)), role("*")),
			),
			r2: resources(
				resource(name("ports"), valueRange(span(11, 20)), role("*")),
			),
			wants: resources(
				resource(name("ports"), valueRange(span(1, 10)), role("*")),
			),
		},
	} {
		backup := tc.r1.Clone()

		// MinusAll preserves the left operand
		actual := tc.r1.MinusAll(tc.r2)
		if !tc.wants.Equivalent(actual) {
			t.Errorf("test case %d failed: wants (%v) != actual (%v)", i, tc.wants, actual)
		}
		if !backup.Equivalent(tc.r1) {
			t.Errorf("test case %d failed: backup (%v) != r1 (%v)", i, backup, tc.r1)
		}

		// SubtractAll mutates the left operand
		tc.r1.SubtractAll(tc.r2)
		if !tc.wants.Equivalent(tc.r1) {
			t.Errorf("test case %d failed: wants (%v) != r1 (%v)", i, tc.wants, tc.r1)
		}

		cpus, ok := tc.r1.CPUs()
{'fraction_non_alphanumeric': 0.21170592433975732, 'fraction_numerical': 0.04354032833690221, 'mean_word_length': 3.855162855162855, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5659640', 'n_tokens_mistral': 3105, 'n_tokens_neox': 2613, 'n_words': 552}