extreme coding : take control of your code
DESCRIPTION
Extreme Coding : Take control of your code. Exilesoft Johannes Brodwall Exilesoft Chief scientist @ jhannes. TODO: Preparator refactoring of MyTime. Are you in control of the code ?. Or is the code in control of you ?. Kata New code Old code. Part I. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/1.jpg)
Extreme Coding:Take control of your code
ExilesoftJohannes Brodwall
Exilesoft Chief scientist
@jhannes
TODO:
Preparator refactoring of MyTime
![Page 2: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/2.jpg)
Are you in control of the code?
![Page 3: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/3.jpg)
Or is the code in control of you?
![Page 4: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/4.jpg)
KataNew codeOld code
![Page 5: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/5.jpg)
Part I
![Page 6: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/6.jpg)
Practicing Test-Driven
Development
![Page 7: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/7.jpg)
public class PrimeFactorsTest { @Test public void oneHasNoFactors() { assertTrue(getPrimeFactors(1).isEmpty()); }
} Think of the simplest test case
![Page 8: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/8.jpg)
public class PrimeFactorsTest {
@Test public void oneHasNoFactors() { assertTrue(getPrimeFactors(1).isEmpty()); }
private List<Integer> getPrimeFactors(int i) { // TODO Auto-generated method stub return null; }
}
Make the code compile=> Test runs red
![Page 9: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/9.jpg)
public class PrimeFactorsTest {
@Test public void oneHasNoFactors() { assertTrue(getPrimeFactors(1).isEmpty()); }
private List<Integer> getPrimeFactors(int i) { return new ArrayList<>(); }
}
The simplest thing to green
![Page 10: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/10.jpg)
public class PrimeFactorsTest {
@Test public void oneHasNoFactors() { assertTrue(getPrimeFactors(1).isEmpty()); }
private List<Integer> getPrimeFactors(int i) { List<Integer> factors = new ArrayList<>(); return factors; }
}
Refactor
![Page 11: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/11.jpg)
public class PrimeFactorsTest {
@Test public void oneHasNoFactors() { assertTrue(getPrimeFactors(1).isEmpty()); }
@Test public void factorsOfTwo() { assertEquals(Arrays.asList(2), getPrimeFactors(2)); }
private List<Integer> getPrimeFactors(int i) { List<Integer> factors = new ArrayList<>(); return factors; }
} The next simplest test=> Tests fail
![Page 12: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/12.jpg)
public class PrimeFactorsTest {
@Test public void oneHasNoFactors() { assertTrue(getPrimeFactors(1).isEmpty()); }
@Test public void factorsOfTwo() { assertEquals(Arrays.asList(2), getPrimeFactors(2)); }
private List<Integer> getPrimeFactors(int i) { List<Integer> factors = new ArrayList<>(); if (i == 2) factors.add(2); return factors; }
} Simplest possible thing: Special case it
![Page 13: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/13.jpg)
public class PrimeFactorsTest {
@Test public void oneHasNoFactors() { assertTrue(getPrimeFactors(1).isEmpty()); }
@Test public void factorsOfTwo() { assertEquals(Arrays.asList(2), getPrimeFactors(2)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); if (number == 2) factors.add(2); return factors; }
} Refactor – improve naming
![Page 14: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/14.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfTwo() { assertEquals(Arrays.asList(2), getPrimeFactors(2)); }
@Test public void factorsOfThree() { assertEquals(Arrays.asList(3), getPrimeFactors(3)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); if (number == 2) factors.add(2); if (number == 3) factors.add(3); return factors; }} Simplest next case +
code
![Page 15: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/15.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfTwo() { assertEquals(Arrays.asList(2), getPrimeFactors(2)); }
@Test public void factorsOfThree() { assertEquals(Arrays.asList(3), getPrimeFactors(3)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); if (number > 1) factors.add(number); return factors; }}
Refactor away duplication
![Page 16: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/16.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfFour() { assertEquals(Arrays.asList(2,2), getPrimeFactors(4)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); if (number == 4) { factors.add(2); number /= 2; } if (number > 1) factors.add(number); return factors; }}
Next caseSpecial case result
![Page 17: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/17.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfSix() { assertEquals(Arrays.asList(2,3), getPrimeFactors(6)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); if (number == 6) { factors.add(2); number /= 2; } if (number == 4) { factors.add(2); number /= 2; } if (number > 1) factors.add(number); return factors; }} Next case – duplicate
special case
![Page 18: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/18.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfSix() { assertEquals(Arrays.asList(2,3), getPrimeFactors(6)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); int factor = 2; if (number % factor == 0) { factors.add(factor); number /= factor; } if (number > 1) factors.add(number); return factors; }} Refactor away
duplicationImportant design step!
![Page 19: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/19.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfEight() { assertEquals(Arrays.asList(2,2,2), getPrimeFactors(8)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); int factor = 2; if (number % factor == 0) { factors.add(factor); number /= factor; } if (number > 1) factors.add(number); return factors; }} Next test – fails
![Page 20: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/20.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfEight() { assertEquals(Arrays.asList(2,2,2), getPrimeFactors(8)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); int factor = 2; while (number % factor == 0) { factors.add(factor); number /= factor; } if (number > 1) factors.add(number); return factors; }} Simplest thing to make
it work!
![Page 21: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/21.jpg)
public class PrimeFactorsTest {
// ... @Test public void factorsOfNine() { assertEquals(Arrays.asList(3,3), getPrimeFactors(9)); }
private List<Integer> getPrimeFactors(int number) { List<Integer> factors = new ArrayList<>(); for (int factor = 2; factor<number; factor++) { while (number % factor == 0) { factors.add(factor); number /= factor; } } if (number > 1) factors.add(number); return factors; }}
Next test and code
![Page 22: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/22.jpg)
TDD – the steps
![Page 23: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/23.jpg)
Think of next testsWrite a testMake it pass as simply as possibleRefactor: Add names, remove duplication
![Page 24: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/24.jpg)
Think of next testsWrite a testMake it pass as simply as possibleRefactor: Add names, remove duplication
![Page 25: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/25.jpg)
Think of next testsWrite a testMake it pass as simply as possibleRefactor: Add names, remove duplication
![Page 26: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/26.jpg)
Think of next testsWrite a testMake it pass as simply as possibleRefactor: Add names, remove duplication
![Page 27: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/27.jpg)
This is where the design comes:Refactor: Add names, remove duplication
![Page 28: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/28.jpg)
You think too much!
![Page 29: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/29.jpg)
You think too much!(about the wrong things)
![Page 30: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/30.jpg)
Part II
![Page 31: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/31.jpg)
Starting out with TDD
![Page 32: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/32.jpg)
Problem domain:
![Page 33: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/33.jpg)
Read measurement data
![Page 34: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/34.jpg)
Given “some data” in the database
![Page 35: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/35.jpg)
When a client sends a “Read register
Modbus message”
![Page 36: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/36.jpg)
Then we respond with the correct
data
![Page 37: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/37.jpg)
Shallow acceptance test
![Page 38: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/38.jpg)
describe("Modbus data server", function() { it("should read saved data from correct register", function(done) { var measurements = [ sampleMeasurement({ cassette: 1, transponder: 1, thickness: 50.1 }), sampleMeasurement({ cassette: 1, transponder: 2, thickness: 50.2 }), ];
updateData(measurements, function() { readRegisters(cassette_start_pos(1), 4, function(err, data) { data.readFloatLE(0).should.be.approximately(50.1, 0.0001); data.readFloatLE(4).should.be.approximately(50.2, 0.0001); done(); }); }); });});
![Page 39: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/39.jpg)
describe("Modbus data server", function() { it("should read saved data from correct register", function(done) { var measurements = [ sampleMeasurement({ cassette: 1, transponder: 1, thickness: 50.1 }), sampleMeasurement({ cassette: 1, transponder: 2, thickness: 50.2 }), ];
updateData(measurements, function() { readRegisters(cassette_start_pos(1), 4, function(err, data) { data.readFloatLE(0).should.be.approximately(50.1, 0.0001); data.readFloatLE(4).should.be.approximately(50.2, 0.0001); done(); }); }); });});
Given
![Page 40: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/40.jpg)
describe("Modbus data server", function() { it("should read saved data from correct register", function(done) { var measurements = [ sampleMeasurement({ cassette: 1, transponder: 1, thickness: 50.1 }), sampleMeasurement({ cassette: 1, transponder: 2, thickness: 50.2 }), ];
updateData(measurements, function() { readRegisters(cassette_start_pos(1), 4, function(err, data) { data.readFloatLE(0).should.be.approximately(50.1, 0.0001); data.readFloatLE(4).should.be.approximately(50.2, 0.0001); done(); }); }); });});
When
![Page 41: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/41.jpg)
describe("Modbus data server", function() { it("should read saved data from correct register", function(done) { var measurements = [ sampleMeasurement({ cassette: 1, transponder: 1, thickness: 50.1 }), sampleMeasurement({ cassette: 1, transponder: 2, thickness: 50.2 }), ];
updateData(measurements, function() { readRegisters(cassette_start_pos(1), 4, function(err, data) { data.readFloatLE(0).should.be.approximately(50.1, 0.0001); data.readFloatLE(4).should.be.approximately(50.2, 0.0001); done(); }); }); });});
Then
![Page 42: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/42.jpg)
Shallow implementation
![Page 43: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/43.jpg)
var registers = new buffer.Buffer(10000);var cassette_start_register = function(cassette_id) { return 0;};var readRegisters = function(start_register, register_count, callback) { var message = registers.slice(start_register*2, start_register*2 + register_count*2); callback(null, message);};var updateData = function(objects, callback) { for (var i=0; i<objects.length; i++) { var measurement = objects[i]; var transducer_pos = 2*cassette_start_register(measurement.cassette_id) + 4*(measurement.transponder_id - 1); registers.writeFloatLE(measurement.thickness, transducer_pos); } callback();};
![Page 44: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/44.jpg)
Extending it to the database
![Page 45: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/45.jpg)
var Sequelize = require("sequelize");var sequelize = new Sequelize('modbusfun', 'modbus', 'secret', { dialect: 'mysql', port: 3306, logging: false });
var Measurement = require('../lib/modbus-fun/measurement') .init(sequelize);var updateRegisters = function(callback) { Measurement.findMeasurements(function(err, objects) { for (var i=0; i<objects.length; i++) { var measurement = objects[i]; var transducer_pos = 2*cassette_start_register(measurement.cassette_id) + 4*(measurement.transponder_id - 1); registers.writeFloatLE(measurement.thickness, transducer_pos); } callback(); });};
![Page 46: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/46.jpg)
Extending it to TCP
![Page 47: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/47.jpg)
var myRegisters = Registers.createRegisters(Measurement);var server = myRegisters.createSocket();var modbusClient;
var readRegisters = function(start, count, callback) { modbusClient.readRegisters(start, count, function(err, data) { callback(err, data); });};
![Page 48: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/48.jpg)
var readRegisters = function(offset, register_count, callback) { callbacks[++transactionId] = function(response_message) { callback(0, response_message.slice(10, 10 + register_count*2)); };
var fc = 0x04; var message = new buffer.Buffer(12); message.writeUInt16LE(transactionId, 0); message.writeUInt16LE(protocolId, 2); message.writeUInt16LE(6, 4); message.writeUInt8(unitId, 6); message.writeUInt8(fc, 7); message.writeUInt16LE(offset, 8); message.writeUInt16LE(register_count, 10);
client.write(message);};
![Page 49: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/49.jpg)
Shallow – then deep
![Page 50: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/50.jpg)
Part III
![Page 51: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/51.jpg)
Getting in control of legacy code
![Page 52: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/52.jpg)
![Page 53: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/53.jpg)
![Page 54: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/54.jpg)
![Page 55: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/55.jpg)
public class HomeControllerTest{ [Test] public void GetEmployeeAvailabilityShouldXXX() { var homeController = new HomeController(); var result = homeController.GetEmployeeAvailability(); result.Should().BeNull(); }}
System.NullReferenceException : Object reference not set to an instance of an object. at Exilesoft.MyTime.Controllers.HomeController.GetEmployeeAvailability() in HomeController.cs: line 190 at HomeControllerTest.GetEmployeeAvailabilityShouldXXX() in HomeControllerTest.cs: line 11
![Page 56: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/56.jpg)
public JsonResult GetEmployeeAvailability(){ string specialEventFullText = string.Empty; DateTime? selectedDate = (DateTime)Session[selectedDateKey]; if (selectedDate == null) selectedDate = DateTime.Now;
private DateTime SelectedDate{ get { if (Session == null) return DateTime.Now; return ((DateTime?) Session[selectedDateKey]) ?? DateTime.Now; }}
Ctrl-r, ctrl-m
![Page 57: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/57.jpg)
Test goes reeeely slow and bombs:System.Data.SqlClient.SqlException : A network-related or instance-specific
error occurred while establishing a connection to SQL Server.
![Page 58: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/58.jpg)
private string DisplaySpecialEvent(string specialEventFullText){ List<SpecialEvent> specilEventList = dbContext.SpecialEvents.Where(c => c.EventFromDate <= DateTime.Today && DateTime.Today <= c.EventToDate).ToList();
Ctrl-r, ctrl-m
private IEnumerable<SpecialEvent> SpecialEvents{ get { return dbContext.SpecialEvents; }}
![Page 59: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/59.jpg)
public HomeController(){ dbContext = new Context(); SpecialEvents = dbContext.SpecialEvents;}
public HomeController(IEnumerable<SpecialEvent> specialEvents){ SpecialEvents = specialEvents;}
![Page 60: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/60.jpg)
[Test]public void GetEmployeeAvailabilityShouldXXX(){ var homeController = new HomeController(new List<SpecialEvent>()); var result = homeController.GetEmployeeAvailability(); result.Should().BeNull();}
![Page 61: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/61.jpg)
Test now runs fast, but encounters
EntityFramework issues
![Page 62: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/62.jpg)
public JsonResult GetEmployeeAvailability(){ string specialEventFullText = string.Empty; var selectedDate = SelectedDate;
//SpecialEvent specilEvent = dbContext.SpecialEvents.Where(c => c.EventFromDate.Value.Year == selectedDate.Value.Year && // c.EventFromDate.Value.Month == selectedDate.Value.Month && c.EventFromDate.Value.Day == selectedDate.Value.Day).SingleOrDefault();
specialEventFullText = this.DisplaySpecialEvent(specialEventFullText);
var allAttendanceForDay = dbContext.Attendances.Where(a => a.Employee.IsEnable == true && a.Year == selectedDate.Year && a.Month == selectedDate.Month && a.Day == selectedDate.Day);
![Page 63: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/63.jpg)
public JsonResult GetEmployeeAvailability(){ string specialEventFullText = string.Empty; var selectedDate = SelectedDate;
specialEventFullText = this.DisplaySpecialEvent(specialEventFullText);
var allAttendanceForDay = dbContext.Attendances.Where(a => a.Employee.IsEnable == true && a.Year == selectedDate.Year && a.Month == selectedDate.Month && a.Day == selectedDate.Day);
![Page 64: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/64.jpg)
public JsonResult GetEmployeeAvailability(){ var selectedDate = SelectedDate; string specialEventFullText = DisplaySpecialEvent(string.Empty);
var allAttendanceForDay = dbContext.Attendances.Where(a => a.Employee.IsEnable == true && a.Year == selectedDate.Year && a.Month == selectedDate.Month && a.Day == selectedDate.Day);
![Page 65: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/65.jpg)
Session[attendanceListKey] = result.ToList();
if (Session != null) Session[attendanceListKey] = result.ToList();
![Page 66: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/66.jpg)
public List<int> GetExitLocationMachins(){ string _exitLocationMachines = ConfigurationManager.AppSettings["ExitLocationMachines"].ToString(); List<int> _locationIDList = new List<int>(); foreach (string locationID in _exitLocationMachines.Split(',')) _locationIDList.Add(int.Parse(locationID));
return _locationIDList;}
Really!?“Machins”?!
![Page 67: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/67.jpg)
public List<int> GetExitLocationMachins(){ string _exitLocationMachines = ConfigurationManager.AppSettings["ExitLocationMachines"].ToString(); List<int> _locationIDList = new List<int>(); foreach (string locationID in _exitLocationMachines.Split(',')) _locationIDList.Add(int.Parse(locationID));
return _locationIDList;}
Ctrl-r, ctrl-r
public List<int> GetExitLocationMachines(){ string _exitLocationMachines = ConfigurationManager.AppSettings["ExitLocationMachines"].ToString(); List<int> _locationIDList = new List<int>(); foreach (string locationID in _exitLocationMachines.Split(',')) _locationIDList.Add(int.Parse(locationID));
return _locationIDList;}
![Page 68: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/68.jpg)
[Test]public void GetEmployeeAvailabilityShouldXXX(){ ConfigurationManager.AppSettings["ExitLocationMachines"] = "200,300"; var homeController = new HomeController(new List<SpecialEvent>(), new List<Attendance>()); var result = homeController.GetEmployeeAvailability(); result.Should().BeNull();}
![Page 69: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/69.jpg)
internal static List<EmployeeData> GetAllEmployees(){ //var tempValue = CasheEmployeeData(); string data = new WebClient().DownloadString(string.Format(ConfigurationManager.AppSettings["EmployeeWebApi"], "GetMyTimeEmployees")); JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
cacheEmployeeDataList = (List<EmployeeData>)jsonSerializer.Deserialize(data, typeof(List<EmployeeData>));
List<int> employeeEnrollmentsIds = EmployeeEnrollmentRepository.GetEmployeeEnrollments().Select(s=>s.EmployeeId).ToList();
return cacheEmployeeDataList.Where(s => employeeEnrollmentsIds.Contains(s.Id)).ToList();}
![Page 70: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/70.jpg)
public IEnumerable<EmployeeData> EmployeeWebList { get; set; }
public HomeController(){ dbContext = new Context(); SpecialEvents = dbContext.SpecialEvents; Attendances = dbContext.Attendances; EmployeeWebList = new EmployeeWebGateway();}
public HomeController(IEnumerable<SpecialEvent> specialEvents, IEnumerable<Attendance> attendances, IEnumerable<EmployeeData> employeeWebList){ Attendances = attendances; SpecialEvents = specialEvents; EmployeeWebList = employeeWebList;}
![Page 71: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/71.jpg)
public JsonResult GetEmployeeAvailability(){ ... int onsiteEmployeeCount = EmployeeRepository.EmployeesOnSite(selectedDate);
Ctrl-r, ctrl-i
int onsiteEmployeeCount = dbContext.EmployeesOnSite.Count(a => a.FromDate <= (DateTime?) selectedDate && a.ToDate >= (DateTime?) selectedDate);
![Page 72: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/72.jpg)
Expected object to be <null>, but found System.Web.Mvc.JsonResult{ ContentEncoding = <null> ContentType = <null> Data = { GraphData = Time,Count, PeopleIn = 0, PeopleOut = 0, absentEmployeeCount = 0, totalEmployeeCount = 0, onSiteCount = 0, specilEvent = } JsonRequestBehavior = DenyGet MaxJsonLength = <null> RecursionLimit = <null>}.
Hurrah!
![Page 73: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/73.jpg)
[Test]public void GetEmployeeAvailabilityShouldXXX(){ ConfigurationManager.AppSettings["ExitLocationMachines"] = "200,300"; var homeController = new HomeController( new List<SpecialEvent>(), new List<Attendance>(), new List<EmployeeData>(), new List<EmployeeOnSite>()); var result = homeController.GetEmployeeAvailability(); result.Should().BeNull();}
![Page 74: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/74.jpg)
public HomeController(){ dbContext = new Context(); SpecialEvents = dbContext.SpecialEvents; EmployeesOnSite = dbContext.EmployeesOnSite; Attendances = dbContext.Attendances; EmployeeWebList = new EmployeeWebGateway();}
public HomeController(IEnumerable<SpecialEvent> specialEvents, IEnumerable<Attendance> attendances, IEnumerable<EmployeeData> employeeWebList, IEnumerable<EmployeeOnSite> employeesOnSite){ EmployeesOnSite = employeesOnSite; Attendances = attendances; SpecialEvents = specialEvents; EmployeeWebList = employeeWebList;}
![Page 75: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/75.jpg)
[Test]public void GetEmployeeAvailabilityShouldTrackArrivedEmployees(){ ConfigurationManager.AppSettings["ExitLocationMachines"] = "200,300";
var today = DateTime.Today.AddDays(-1); var employee1 = new EmployeeEnrollment { IsEnable = true, EnrollNo = 1 }; var employee2 = new EmployeeEnrollment { IsEnable = true, EnrollNo = 2 }; _attendances.Add(SampleAttendance(today.AddHours(12), employee1)); _attendances.Add(SampleAttendance(today.AddHours(13).AddMinutes(30), employee2));
var homeController = new HomeController( new List<SpecialEvent>(), _attendances, new List<EmployeeData>(), new List<EmployeeOnSite>()); homeController.SelectedDate = today.AddHours(19).AddMinutes(23);
var result = homeController.GetEmployeeAvailability(); string graphData = GetProperty(result.Data, "GraphData").ToString(); graphData.Should().Contain("Time,Count\n"); graphData.Should().Contain("11:00:00,0"); graphData.Should().Contain("13:00:00,1"); graphData.Should().Contain("14:00:00,2"); graphData.Should().Contain("19:23:00,2"); graphData.Should().NotContain("20:20:00,");}
![Page 76: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/76.jpg)
Testing legacy code
![Page 77: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/77.jpg)
New up a class and call a method
![Page 78: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/78.jpg)
Replace dependencies with
Lists (!)
![Page 79: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/79.jpg)
Get the test to run
![Page 80: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/80.jpg)
Add logic to the test
![Page 81: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/81.jpg)
[Test]public void GetEmployeeAvailabilityShouldReduceEmployeesWhenExit(){ _attendances.Add(SampleAttendance(_today.AddHours(12).AddMinutes(30), _employee1)); _attendances.Add(SampleAttendance(_today.AddHours(13).AddMinutes(20), _employee1, "out", 200)); _homeController.SelectedDate = _today.AddHours(19).AddMinutes(23);
var result = _homeController.GetEmployeeAvailability(); string graphData = GetProperty(result.Data, "GraphData").ToString(); graphData.Should().Contain("12:00:00,0"); graphData.Should().Contain("13:00:00,1"); graphData.Should().Contain("14:00:00,0");}
![Page 82: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/82.jpg)
[Test]public void GetEmployeeAvailabilityShouldCountEmployeesInside(){ _attendances.Add(SampleAttendance(_today.AddHours(12).AddMinutes(30), _employee1)); _attendances.Add(SampleAttendance(_today.AddHours(13).AddMinutes(20), _employee1, "out", 200));
_homeController.SelectedDate = _today.AddHours(8).AddMinutes(31); GetProperty(_homeController.GetEmployeeAvailability().Data, "PeopleOut").Should().Be(0);
_homeController.SelectedDate = _today.AddHours(12).AddMinutes(31); GetProperty(_homeController.GetEmployeeAvailability().Data, "PeopleIn").Should().Be(1); GetProperty(_homeController.GetEmployeeAvailability().Data, "PeopleOut").Should().Be(0);
_homeController.SelectedDate = _today.AddHours(13).AddMinutes(21); GetProperty(_homeController.GetEmployeeAvailability().Data, "PeopleIn").Should().Be(0); GetProperty(_homeController.GetEmployeeAvailability().Data, "PeopleOut").Should().Be(1);}
![Page 83: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/83.jpg)
But: It’s not about the tests
![Page 84: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/84.jpg)
It’s about the refactorings
![Page 85: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/85.jpg)
• Rename• Extract method• Introduce variable• Introduce parameters• Inline method
![Page 86: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/86.jpg)
The Challenge
![Page 87: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/87.jpg)
Do 100 refactorings per day
![Page 88: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/88.jpg)
Do 100 refactorings per day
Print out a cheat sheet with resharper refactorings
![Page 89: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/89.jpg)
Practice a coding kata
![Page 90: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/90.jpg)
Create a test for a legacy class
![Page 91: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/91.jpg)
Give me feedback:
How likely are you to recommend this session to a co-worker on a scale from 1 (lowest) to 10 (highest)?
Optional: What's the reason for your number?
![Page 92: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/92.jpg)
http://JohannesBrodwall.comhttp://exilesoft.com
http://twitter.com/jhannes
Thank you
![Page 93: Extreme Coding : Take control of your code](https://reader036.vdocument.in/reader036/viewer/2022081604/56815e99550346895dcd2a7c/html5/thumbnails/93.jpg)
Give me feedback:
How likely are you to recommend this session to a co-worker on a scale from 1 (lowest) to 10 (highest)?
Optional: What's the reason for your number?